Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
16d33fd
Initial prototype of catalog federation just passing special properti…
dennishuo Feb 7, 2025
3b1aa16
Defined internal representation classes for connection config
XJDKC Mar 3, 2025
1d1650b
Construct and initialize federated iceberg catalog based on connectio…
XJDKC Mar 3, 2025
205ef1e
Apply the same spec renames to the internal ConnectionConfiguration r…
dennishuo Mar 19, 2025
c8484e0
Manually pick @XJDKC fixes for integration tests and omittign secrets…
dennishuo Mar 19, 2025
acb5bec
Fix internal connection structs with updated naming from spec PR
dennishuo Mar 20, 2025
300553f
Push CreateCatalogRequest down to PolarisAdminService::createCatalog …
dennishuo Mar 27, 2025
4ad235e
Add new interface UserSecretsManager along with a default implementation
dennishuo Mar 30, 2025
cc17ae5
Wire in UserSecretsManager to createCatalog and federated Iceberg API…
dennishuo Mar 30, 2025
6700fb2
Since we already use commons-codec DigestUtils.sha256Hex, use that fo…
dennishuo Apr 3, 2025
10b2966
Rename the persistence-objects corresponding to API model objects wit…
dennishuo Apr 4, 2025
fd7ae59
Use UserSecretsManagerFactory to Produce the UserSecretsManager (#1)
XJDKC Apr 4, 2025
cbe362d
Gate all federation logic behind a new FeatureConfiguration - ENABLE_…
dennishuo Apr 4, 2025
3e85244
Also rename some variables and method names to be consistent with pri…
dennishuo Apr 4, 2025
9be6ee3
Merge branch 'main' of github.com:dennishuo/polaris into dhuo-catalog…
dennishuo Apr 4, 2025
7d5c9e1
Merge branch 'main' of github.com:dennishuo/polaris into dhuo-catalog…
dennishuo Apr 10, 2025
31a7333
Merge branch 'main' of github.com:dennishuo/polaris into dhuo-catalog…
dennishuo Apr 14, 2025
03af9f5
Change ConnectionType and AuthenticationType to be stored as int code…
dennishuo Apr 14, 2025
544ce82
Add javadoc comment to IcebergCatalogPropertiesProvider
dennishuo Apr 15, 2025
beaa34e
Add some constraints on the expected format of the URN in UserSecretR…
dennishuo Apr 17, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.polaris.core.entity.PolarisEntity;
import org.apache.polaris.core.entity.PolarisEntityCore;

/**
* A minimal in-memory implementation of UserSecretsManager that should only be used for test and
Expand All @@ -48,7 +48,8 @@ public class UnsafeInMemorySecretsManager implements UserSecretsManager {
/** {@inheritDoc} */
@Override
@Nonnull
public UserSecretReference writeSecret(@Nonnull String secret, @Nonnull PolarisEntity forEntity) {
public UserSecretReference writeSecret(
@Nonnull String secret, @Nonnull PolarisEntityCore forEntity) {
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

// For illustrative purposes and to exercise the control flow of requiring both the stored
// secret as well as the secretReferencePayload to recover the original secret, we'll use
// basic XOR encryption and store the randomly generated key in the reference payload.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
*/
package org.apache.polaris.core.secrets;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
import java.util.HashMap;
Expand Down Expand Up @@ -56,7 +58,10 @@ public class UserSecretReference {

/**
* @param urn A string which should be self-sufficient to retrieve whatever secret material that
* is stored in the remote secret store.
* is stored in the remote secret store and also to identify an implementation of the
* UserSecretsManager which is capable of interpreting this concrete UserSecretReference.
* Should be of the form:
* 'urn:polaris-secret:<secret-manager-type>:<type-specific-identifier>
* @param referencePayload Optionally, any additional information that is necessary to fully
* reconstitute the original secret based on what is retrieved by the {@code urn}; this
* payload may include hashes/checksums, encryption key ids, OTP encryption keys, additional
Expand All @@ -65,10 +70,28 @@ public class UserSecretReference {
public UserSecretReference(
@JsonProperty(value = "urn", required = true) @Nonnull String urn,
@JsonProperty(value = "referencePayload") @Nullable Map<String, String> referencePayload) {
// TODO: Add better/standardized parsing and validation of URN syntax
Preconditions.checkArgument(
urn.startsWith("urn:polaris-secret:") && urn.split(":").length >= 4,
"Invalid secret URN '%s'; must be of the form "
+ "'urn:polaris-secret:<secret-manager-type>:<type-specific-identifier>'",
urn);
Comment on lines +73 to +78
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

this.urn = urn;
this.referencePayload = Objects.requireNonNullElse(referencePayload, new HashMap<>());
}

/**
* Since UserSecretReference objects are specific to UserSecretManager implementations, the
* "secret-manager-type" portion of the URN should be used to validate that a URN is valid for a
* given implementation and to dispatch to the correct implementation at runtime if multiple
* concurrent implementations are possible in a given runtime environment.
*/
@JsonIgnore
public String getUserSecretManagerTypeFromUrn() {
// TODO: Add better/standardized parsing and validation of URN syntax
Copy link
Contributor

Choose a reason for hiding this comment

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

My understanding is the format won't change, but we will just make the parsing / validation more structured -- that's cool with me

return urn.split(":")[2];
}

public @Nonnull String getUrn() {
return urn;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
package org.apache.polaris.core.secrets;

import jakarta.annotation.Nonnull;
import org.apache.polaris.core.entity.PolarisEntity;
import org.apache.polaris.core.entity.PolarisEntityCore;

/**
* Manages secrets specified by users of the Polaris API, either directly or as an intermediary
Expand All @@ -32,25 +32,25 @@ public interface UserSecretsManager {
/**
* Persist the {@code secret} under a new URN {@code secretUrn} and return a {@code
* UserSecretReference} that can subsequently be used by this same UserSecretsManager to retrieve
* the original secret. The {@code forEntity} is provided for an implementation to optionally
* extract other identifying metadata such as entity type, name, etc., to store alongside the
* remotely stored secret to facilitate operational management of the secrets outside of the core
* Polaris service (for example, to perform garbage-collection if the Polaris service fails to
* delete managed secrets in the external system when associated entities are deleted.
* the original secret. The {@code forEntity} is provided for an implementation to extract other
* identifying metadata such as entity type, id, name, etc., to store alongside the remotely
* stored secret to facilitate operational management of the secrets outside of the core Polaris
* service (for example, to perform garbage-collection if the Polaris service fails to delete
* managed secrets in the external system when associated entities are deleted).
*
* @param secret The secret to store
* @param forEntity The PolarisEntity that is associated with the secret
* @return A reference object that can be used to retrieve the secret which is safe to store in
* its entirety within a persisted PolarisEntity
*/
@Nonnull
UserSecretReference writeSecret(@Nonnull String secret, @Nonnull PolarisEntity forEntity);
UserSecretReference writeSecret(@Nonnull String secret, @Nonnull PolarisEntityCore forEntity);

/**
* Retrieve a secret using the {@code secretReference}. See {@link UserSecretReference} for
* details about identifiers and payloads.
*
* @param secretReference Identifier and any associated payload used for retrieving the secret
* @param secretReference Reference object for retrieving the original secret
* @return The stored secret, or null if it no longer exists
*/
@Nonnull
Expand All @@ -60,7 +60,7 @@ public interface UserSecretsManager {
* Delete a stored secret. See {@link UserSecretReference} for details about identifiers and
* payloads.
*
* @param secretReference Identifier and any associated payload used for retrieving the secret
* @param secretReference Reference object for retrieving the original secret
*/
void deleteSecret(@Nonnull UserSecretReference secretReference);
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ void testOAuthClientCredentialsParameters() throws JsonProcessingException {
+ " \"tokenUri\": \"https://myorg-my_account.snowflakecomputing.com/polaris/api/catalog/v1/oauth/tokens\","
+ " \"clientId\": \"client-id\","
+ " \"clientSecretReference\": {"
+ " \"urn\": \"urn:polaris-secret:keystore-id-12345\","
+ " \"urn\": \"urn:polaris-secret:secretmanager-impl:keystore-id-12345\","
+ " \"referencePayload\": {"
+ " \"hash\": \"a1b2c3\","
+ " \"encryption-key\": \"z0y9x8\""
Expand Down Expand Up @@ -94,7 +94,7 @@ void testBearerAuthenticationParameters() throws JsonProcessingException {
+ " \"authenticationParameters\": {"
+ " \"authenticationTypeCode\": 2,"
+ " \"bearerTokenReference\": {"
+ " \"urn\": \"urn:polaris-secret:keystore-id-12345\","
+ " \"urn\": \"urn:polaris-secret:secretmanager-impl:keystore-id-12345\","
+ " \"referencePayload\": {"
+ " \"hash\": \"a1b2c3\","
+ " \"encryption-key\": \"z0y9x8\""
Expand Down