Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
plugins {
`maven-publish`
`java-test-fixtures`
id("java")
id("idea")
}
Expand All @@ -32,6 +33,8 @@ dependencies {
testImplementation(libs.junit.jupiter.api)
testImplementation(libs.junit.jupiter.params)
testRuntimeOnly(libs.junit.jupiter.engine)

testFixturesApi(libs.junit.jupiter.api)
}

tasks.build {
Expand Down
85 changes: 85 additions & 0 deletions api/src/main/java/org/apache/gravitino/encryption/kms/KmsApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.gravitino.encryption.kms;

import java.util.Arrays;
import java.util.Locale;
import java.util.stream.Collectors;
import org.apache.gravitino.annotation.DeveloperApi;

/** The KMS product API that defines key identifier and operation semantics. */
@DeveloperApi
public enum KmsApi {
/** Amazon Web Services Key Management Service. */
AWS_KMS("aws-kms"),

/** Google Cloud Key Management Service. */
GOOGLE_CLOUD_KMS("google-cloud-kms"),

/** Microsoft Azure Key Vault. */
AZURE_KEY_VAULT("azure-key-vault"),

/** The OpenBao Transit secrets engine API. */
OPENBAO_TRANSIT("openbao-transit"),

/** The HashiCorp Vault Transit secrets engine API. */
VAULT_TRANSIT("vault-transit");

private final String wireValue;

KmsApi(String wireValue) {
this.wireValue = wireValue;
}

/**
* Returns the stable configuration value for this API.
*
* @return the configuration value
*/
public String wireValue() {
return wireValue;
}

/**
* Parses a configured API value.
*
* @param value configured API value
* @return the matching API
* @throws IllegalArgumentException if the value is null, blank, or unsupported
*/
public static KmsApi fromWireValue(String value) {
if (value == null || value.trim().isEmpty()) {
throw new IllegalArgumentException("KMS API cannot be blank");
}

String normalized = value.trim().toLowerCase(Locale.ROOT);
return Arrays.stream(values())
.filter(api -> api.wireValue.equals(normalized))
.findFirst()
.orElseThrow(
() ->
new IllegalArgumentException(
String.format(
"Unsupported KMS API '%s'; supported values are %s",
value,
Arrays.stream(values())
.map(KmsApi::wireValue)
.collect(Collectors.joining(", ")))));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.gravitino.encryption.kms;

import com.google.errorprone.annotations.FormatMethod;
import com.google.errorprone.annotations.FormatString;
import org.apache.gravitino.exceptions.ConnectionFailedException;

/** Indicates that a KMS backend rejected or could not resolve configured credentials. */
public class KmsAuthenticationException extends ConnectionFailedException {

/**
* Creates an authentication exception with the specified cause and detail message.
*
* @param cause the cause
* @param message the detail message
* @param args the arguments to the message
*/
@FormatMethod
public KmsAuthenticationException(Throwable cause, @FormatString String message, Object... args) {
super(cause, message, args);
}

/**
* Creates an authentication exception with the specified detail message.
*
* @param message the detail message
* @param args the arguments to the message
*/
@FormatMethod
public KmsAuthenticationException(@FormatString String message, Object... args) {
super(message, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.gravitino.encryption.kms;

import org.apache.gravitino.annotation.DeveloperApi;
import org.apache.gravitino.exceptions.ConnectionFailedException;

/**
* Inspects keys managed by a configured KMS.
*
* <p>This is a server-side operation client, not a credential-vending API. Provider credentials
* authenticate calls made by the client and must never be returned to callers. This client does not
* perform cryptographic operations.
*/
@DeveloperApi
public interface KmsClient extends AutoCloseable {

/**
* Reads the provider-reported properties of a key.
*
* @param reference key to inspect
* @return normalized key properties
* @throws IllegalArgumentException if the reference does not belong to this client
* @throws ConnectionFailedException if the provider cannot be queried
*/
KmsKeyProperties getKeyProperties(KmsReference reference);

/** Releases resources owned by this client. */
@Override
default void close() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.gravitino.encryption.kms;

import java.util.Map;
import org.apache.gravitino.annotation.DeveloperApi;
import org.apache.gravitino.exceptions.ConnectionFailedException;

/** Creates server-side KMS clients for one supported KMS API. */
@DeveloperApi
public interface KmsClientFactory {

/**
* Returns the KMS API implemented by this factory.
*
* @return the supported KMS API
*/
KmsApi api();

/**
* Creates a client bound to a configured KMS source.
*
* <p>Provider credentials are private implementation details of the returned client. They must
* not be exposed as Gravitino credentials or key properties.
*
* @param source logical name of the configured KMS instance
* @param properties provider-specific configuration
* @return the configured client
* @throws IllegalArgumentException if the source or configuration is invalid
* @throws ConnectionFailedException if required external initialization fails
*/
KmsClient create(String source, Map<String, String> properties);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.gravitino.encryption.kms;

import com.google.errorprone.annotations.FormatMethod;
import com.google.errorprone.annotations.FormatString;

/** Indicates invalid KMS configuration detected during initialization. */
public class KmsConfigurationException extends IllegalArgumentException {

/**
* Creates a configuration exception with the specified detail message.
*
* @param message the detail message
* @param args the arguments to the message
*/
@FormatMethod
public KmsConfigurationException(@FormatString String message, Object... args) {
super(args.length == 0 ? message : String.format(message, args));
}

/**
* Creates a configuration exception with the specified cause and detail message.
*
* @param cause the cause
* @param message the detail message
* @param args the arguments to the message
*/
@FormatMethod
public KmsConfigurationException(Throwable cause, @FormatString String message, Object... args) {
super(args.length == 0 ? message : String.format(message, args), cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.gravitino.encryption.kms;

import org.apache.gravitino.annotation.DeveloperApi;

/**
* Common properties reported for a KMS key.
*
* <p>Capabilities describe downstream use; this API does not perform cryptographic operations.
*/
@DeveloperApi
public interface KmsKeyProperties {

/**
* Returns the requested key reference.
*
* @return the key reference
*/
KmsReference reference();

/**
* Returns whether the provider reports that the key exists.
*
* @return whether the key exists
*/
boolean present();

/**
* Returns whether the provider reports that the key is enabled.
*
* @return whether the key is enabled
*/
boolean enabled();

/**
* Returns whether the key supports wrapping data-encryption keys.
*
* @return whether wrapping is supported
*/
boolean supportsWrapping();

/**
* Returns whether the key supports unwrapping data-encryption keys.
*
* @return whether unwrapping is supported
*/
boolean supportsUnwrapping();
}
Loading
Loading