Skip to content

feat(security): Add design documents for sensitive data management#10732

Open
babumahesh wants to merge 1 commit intoapache:mainfrom
babumahesh:feat/credential_management
Open

feat(security): Add design documents for sensitive data management#10732
babumahesh wants to merge 1 commit intoapache:mainfrom
babumahesh:feat/credential_management

Conversation

@babumahesh
Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Raise a document about external secrets and encryption at rest for catalog properties .

  1. External Secret Management (SecretProvider) - Integration with
    AWS Secrets Manager, Vault, and other external secret stores to
    avoid storing secrets in Gravitino's backend database
    (babumahesh@e9a4b4a#diff-5eecc2a25fa5b2a764f787ac1dc8b9f3b117790320d634d6f6f3cf6960814996)

  2. Catalog properties Encryption at Rest (EncryptionProvider) - AES-GCM
    encryption for sensitive catalog properties stored in Gravitino's
    backend database
    (babumahesh@e9a4b4a#diff-be1104f868165d9d33be232eb484de1b821778c07f1d5c775919dc3122433a44)

Why are the changes needed?
It's a feature.

Fix:
#10415
#4681

Does this PR introduce any user-facing change?
N/A

How was this patch tested?

1. External Secret Management (SecretProvider) - Integration with
     AWS Secrets Manager, Vault, and other external secret stores to
     avoid storing secrets in Gravitino's backend database

  2. Database Encryption at Rest (EncryptionProvider) - AES-GCM
     encryption for sensitive catalog properties stored in Gravitino's
     backend database
@babumahesh babumahesh marked this pull request as ready for review April 9, 2026 17:59
@babumahesh
Copy link
Copy Markdown
Contributor Author

@roryqi

I have design proposals for

  1. Encrypt sensitive data in catalog properties
  2. Support integration with external secret managers (e.g., HashiCorp Vault, AWS Secrets Manager, KMS) as backends

Can you please review further or if possible we can connect over call aslo that would be better to discuss in detail.

@roryqi
Copy link
Copy Markdown
Contributor

roryqi commented Apr 10, 2026

Thanks for your design document. I am pleased to communicate about this topic. I took a short look.
There are a few questions!

  1. How did the existed catalog migrate the sensitive properties?
  2. Should we configure a KMS for a Gravitino server or serveral KMS for a Gravitino server?

@babumahesh
Copy link
Copy Markdown
Contributor Author

Thanks for your design document. I am pleased to communicate about this topic. I took a short look. There are a few questions!

  1. How did the existed catalog migrate the sensitive properties?
  2. Should we configure a KMS for a Gravitino server or serveral KMS for a Gravitino server?

For Existing catalog migrate the sensitive properties

  • In-House Encryption: Migration script makes sense

    • Script transforms plain-text → enc:AES-GCM:v1:... in the Gravitino DB
    • Safe to automate because it's a deterministic transformation
    • Its also upto users whether they wanted to migrate or not
  • External Secret Management

    • Manual migration preference is reasonable
      • Store secrets in their secret manager (AWS Secrets Manager/Vault)
      • Update catalog properties manually : plain-text → ${secret:path/to/secret}
    • Hard to automate because secret paths/organization vary by company

Should we configure a KMS for a Gravitino server or serveral KMS for a Gravitino server:

  • Both patterns supported via hybrid syntax:
    • Global default: One secret provider configured in gravitino.conf, catalogs use simple syntax ${secret:mysql/password}
    • Multi-tenant: Multiple secret providers enabled, catalogs explicitly specify provider
      • ${secret:vault:team-a/mysql/password} → uses HashiCorp Vault
      • ${secret:aws-sm:team-b/postgres#password} → uses AWS Secrets Manager

Key principle: Either with in-house encryption or with KMS; Both Plain-text and secured catalogs can coexist

@roryqi
Copy link
Copy Markdown
Contributor

roryqi commented Apr 10, 2026

Thanks for your design document. I am pleased to communicate about this topic. I took a short look. There are a few questions!

  1. How did the existed catalog migrate the sensitive properties?
  2. Should we configure a KMS for a Gravitino server or serveral KMS for a Gravitino server?

For Existing catalog migrate the sensitive properties

  • In-House Encryption: Migration script makes sense

    • Script transforms plain-text → enc:AES-GCM:v1:... in the Gravitino DB
    • Safe to automate because it's a deterministic transformation
    • Its also upto users whether they wanted to migrate or not
  • External Secret Management

    • Manual migration preference is reasonable

      • Store secrets in their secret manager (AWS Secrets Manager/Vault)
      • Update catalog properties manually : plain-text → ${secret:path/to/secret}
    • Hard to automate because secret paths/organization vary by company

We need a migration document to help users to migrate the sensitive properties when required.

Should we configure a KMS for a Gravitino server or serveral KMS for a Gravitino server:

  • Both patterns supported via hybrid syntax:

    • Global default: One secret provider configured in gravitino.conf, catalogs use simple syntax ${secret:mysql/password}

    • Multi-tenant: Multiple secret providers enabled, catalogs explicitly specify provider

      • ${secret:vault:team-a/mysql/password} → uses HashiCorp Vault
      • ${secret:aws-sm:team-b/postgres#password} → uses AWS Secrets Manager

Key principle: Either with in-house encryption or with KMS; Both Plain-text and secured catalogs can coexist

Is it necessary to have multiple KMS for one server? Which situations require this feature?

@babumahesh
Copy link
Copy Markdown
Contributor Author

babumahesh commented Apr 10, 2026

Thanks for your design document. I am pleased to communicate about this topic. I took a short look. There are a few questions!

  1. How did the existed catalog migrate the sensitive properties?
  2. Should we configure a KMS for a Gravitino server or serveral KMS for a Gravitino server?

For Existing catalog migrate the sensitive properties

  • In-House Encryption: Migration script makes sense

    • Script transforms plain-text → enc:AES-GCM:v1:... in the Gravitino DB
    • Safe to automate because it's a deterministic transformation
    • Its also upto users whether they wanted to migrate or not
  • External Secret Management

    • Manual migration preference is reasonable

      • Store secrets in their secret manager (AWS Secrets Manager/Vault)
      • Update catalog properties manually : plain-text → ${secret:path/to/secret}
    • Hard to automate because secret paths/organization vary by company

We need a migration document to help users to migrate the sensitive properties when required.

Should we configure a KMS for a Gravitino server or serveral KMS for a Gravitino server:

  • Both patterns supported via hybrid syntax:

    • Global default: One secret provider configured in gravitino.conf, catalogs use simple syntax ${secret:mysql/password}

    • Multi-tenant: Multiple secret providers enabled, catalogs explicitly specify provider

      • ${secret:vault:team-a/mysql/password} → uses HashiCorp Vault
      • ${secret:aws-sm:team-b/postgres#password} → uses AWS Secrets Manager

Key principle: Either with in-house encryption or with KMS; Both Plain-text and secured catalogs can coexist

Is it necessary to have multiple KMS for one server? Which situations require this feature?

Multiple KMS support is not strictly necessary, but provides flexibility for specific enterprise scenarios:

  • Multi-cloud/Hybrid deployments

    • AWS catalogs → AWS Secrets Manager
    • On-premise catalogs → HashiCorp Vault
    • Example: ${secret:aws-sm:rds/password} vs ${secret:vault:mysql/password}
  • Multi-tenant environments

    • Team A uses their corporate Vault instance
    • Team B uses a different Vault/secret manager

Though we could always start with one KMS for simplicity.

@roryqi
Copy link
Copy Markdown
Contributor

roryqi commented Apr 13, 2026

Yes, we could always start with one KMS for simplicity.
KMS may be like MySQL, we only need a kind of storage, although we can deploy in multiple clouds.
Gravitino server in AWS may use AWS Secrets Manager, Gravitino on-premise may use HashiCorp Vault.
Do we need users to know which kms they are using?

@babumahesh
Copy link
Copy Markdown
Contributor Author

Yes, we could always start with one KMS for simplicity. KMS may be like MySQL, we only need a kind of storage, although we can deploy in multiple clouds. Gravitino server in AWS may use AWS Secrets Manager, Gravitino on-premise may use HashiCorp Vault. Do we need users to know which kms they are using?

Agreed.

And for "Do we need users to know which KMS they are using?"

Yes, it's better if users know which KMS is configured. This makes it easier for them to onboard keys or obtain necessary access. We might need to add an admin/settings section in the Gravitino UI to display the KMS configuration (at least the service details), though this admin/settings kind of section doesn't currently exist in the UI.

@babumahesh
Copy link
Copy Markdown
Contributor Author

@roryqi

Is there anything else from the approach perspective? If this looks good , then we can start with implementation further.

@roryqi
Copy link
Copy Markdown
Contributor

roryqi commented Apr 14, 2026

@roryqi

Is there anything else from the approach perspective? If this looks good , then we can start with implementation further.

Yes, I need a deeper review. Thanks for your understanding.

@roryqi
Copy link
Copy Markdown
Contributor

roryqi commented Apr 14, 2026

Yes, we could always start with one KMS for simplicity. KMS may be like MySQL, we only need a kind of storage, although we can deploy in multiple clouds. Gravitino server in AWS may use AWS Secrets Manager, Gravitino on-premise may use HashiCorp Vault. Do we need users to know which kms they are using?

Agreed.

And for "Do we need users to know which KMS they are using?"

Yes, it's better if users know which KMS is configured. This makes it easier for them to onboard keys or obtain necessary access. We might need to add an admin/settings section in the Gravitino UI to display the KMS configuration (at least the service details), though this admin/settings kind of section doesn't currently exist in the UI.

Admin should know that but we shouldn't expose it to normal users. Normal users won't care about which database we used.
Normal users won't care about which KMS we used. Admin can know the KMS kind by reading the configurations.

Comment thread design-docs/external_secret_management_design.md
* @throws SecretResolutionException if secret resolution fails
*/
@Nullable
String resolveSecret(String secretReference);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we define a class secretReference? String is flexible but it lacks constraint.

* @throws SecretResolutionException if secret resolution fails
*/
@Nullable
String resolveSecret(String secretReference);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could u give me other systems' secret reference like Databricks and Snowflake?


### Core Components

#### 1. SecretProvider Interface
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can refer to the Iceberg similar design, you can see

/** A minimum client interface to connect to a key management service (KMS). */
public interface KeyManagementClient extends Serializable, Closeable {

  /**
   * Wrap a secret key, using a wrapping/master key which is stored in KMS and referenced by an ID.
   * Wrapping means encryption of the secret key with the master key, and adding optional
   * KMS-specific metadata that allows the KMS to decrypt the secret key in an unwrapping call.
   *
   * @param key a secret key being wrapped
   * @param wrappingKeyId a key ID that represents a wrapping key stored in KMS
   * @return wrapped key material
   */
  ByteBuffer wrapKey(ByteBuffer key, String wrappingKeyId);

  /**
   * Some KMS systems support generation of secret keys inside the KMS server.
   *
   * @return true if KMS server supports key generation and KeyManagementClient implementation is
   *     interested to leverage this capability. Otherwise, return false - Iceberg will then
   *     generate secret keys locally (using the SecureRandom mechanism) and call {@link
   *     #wrapKey(ByteBuffer, String)} to wrap them in KMS.
   */
  default boolean supportsKeyGeneration() {
    return false;
  }

  /**
   * Generate a new secret key in the KMS server, and wrap it using a wrapping/master key which is
   * stored in KMS and referenced by an ID. This method will be called only if supportsKeyGeneration
   * returns true.
   *
   * @param wrappingKeyId a key ID that represents a wrapping key stored in KMS
   * @return key in two forms: raw, and wrapped with the given wrappingKeyId
   */
  default KeyGenerationResult generateKey(String wrappingKeyId) {
    throw new UnsupportedOperationException("Key generation is not supported in this KmsClient");
  }

  /**
   * Unwrap a secret key, using a wrapping/master key which is stored in KMS and referenced by an
   * ID.
   *
   * @param wrappedKey wrapped key material (encrypted key and optional KMS metadata, returned by
   *     the wrapKey method)
   * @param wrappingKeyId a key ID that represents a wrapping key stored in KMS
   * @return raw key bytes
   */
  ByteBuffer unwrapKey(ByteBuffer wrappedKey, String wrappingKeyId);

  /**
   * Initialize the KMS client with given properties.
   *
   * @param properties kms client properties
   */
  void initialize(Map<String, String> properties);

  /**
   * Close KMS Client to release underlying resources, this could be triggered in different threads
   * when KmsClient is shared by multiple encryption managers.
   */
  @Override
  default void close() {}

  /**
   * For KMS systems that support key generation, this class keeps the key generation result - the
   * raw secret key, and its wrap.
   */
  class KeyGenerationResult {
    private final ByteBuffer key;
    private final ByteBuffer wrappedKey;

    public KeyGenerationResult(ByteBuffer key, ByteBuffer wrappedKey) {
      this.key = key;
      this.wrappedKey = wrappedKey;
    }

    public ByteBuffer key() {
      return key;
    }

    public ByteBuffer wrappedKey() {
      return wrappedKey;
    }
  }
}

You can survey about this and realize its design, background and consideration by finding the discussion and design documents.

@roryqi
Copy link
Copy Markdown
Contributor

roryqi commented Apr 14, 2026

In general, I prefer that we have realized other systems user experience and provide a clear feature.

@roryqi
Copy link
Copy Markdown
Contributor

roryqi commented Apr 14, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants