diff --git a/cdap-app-fabric/src/main/java/io/cdap/cdap/app/guice/AppFabricServiceRuntimeModule.java b/cdap-app-fabric/src/main/java/io/cdap/cdap/app/guice/AppFabricServiceRuntimeModule.java index a6f666e95c17..8a53b3012815 100644 --- a/cdap-app-fabric/src/main/java/io/cdap/cdap/app/guice/AppFabricServiceRuntimeModule.java +++ b/cdap-app-fabric/src/main/java/io/cdap/cdap/app/guice/AppFabricServiceRuntimeModule.java @@ -151,6 +151,7 @@ import io.cdap.cdap.scheduler.CoreSchedulerService; import io.cdap.cdap.scheduler.Scheduler; import io.cdap.cdap.securestore.spi.SecretStore; +import io.cdap.cdap.security.encryption.guice.AeadEncryptionModule; import io.cdap.cdap.security.impersonation.DefaultOwnerAdmin; import io.cdap.cdap.security.impersonation.DefaultUGIProvider; import io.cdap.cdap.security.impersonation.OwnerAdmin; @@ -200,6 +201,7 @@ public Module getInMemoryModules() { new EntityVerifierModule(), new MasterCredentialProviderModule(), new OperationModule(), + new AeadEncryptionModule(), BootstrapModules.getInMemoryModule(), new AbstractModule() { @Override @@ -243,6 +245,7 @@ public Module getStandaloneModules() { new ProvisionerModule(), new MasterCredentialProviderModule(), new OperationModule(), + new AeadEncryptionModule(), BootstrapModules.getFileBasedModule(), new AbstractModule() { @Override @@ -298,6 +301,7 @@ public Module getDistributedModules() { new ProvisionerModule(), new MasterCredentialProviderModule(), new OperationModule(), + new AeadEncryptionModule(), BootstrapModules.getFileBasedModule(), new AbstractModule() { @Override diff --git a/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/app/services/AppFabricServer.java b/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/app/services/AppFabricServer.java index ef489954bcd3..102bdbd136b8 100644 --- a/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/app/services/AppFabricServer.java +++ b/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/app/services/AppFabricServer.java @@ -45,6 +45,8 @@ import io.cdap.cdap.internal.sysapp.SystemAppManagementService; import io.cdap.cdap.proto.id.NamespaceId; import io.cdap.cdap.scheduler.CoreSchedulerService; +import io.cdap.cdap.security.encryption.AeadCipherService; +import io.cdap.cdap.security.encryption.guice.AeadEncryptionModule; import io.cdap.cdap.sourcecontrol.RepositoryCleanupService; import io.cdap.cdap.sourcecontrol.operationrunner.SourceControlOperationRunner; import io.cdap.cdap.spi.data.transaction.TransactionRunner; @@ -97,6 +99,8 @@ public class AppFabricServer extends AbstractIdleService { private final SConfiguration sConf; private final boolean sslEnabled; private final TransactionRunner transactionRunner; + private final AeadCipherService userEncryptionAeadCipherService; + private final AeadCipherService dataStorageAeadCipherService; private Cancellable cancelHttpService; private Set handlers; @@ -130,7 +134,12 @@ public AppFabricServer(CConfiguration cConf, SConfiguration sConf, CommonNettyHttpServiceFactory commonNettyHttpServiceFactory, RunRecordTimeToLiveService runRecordTimeToLiveService, SourceControlOperationRunner sourceControlOperationRunner, - RepositoryCleanupService repositoryCleanupService) { + RepositoryCleanupService repositoryCleanupService, + @Named(AeadEncryptionModule.USER_CREDENTIAL_ENCRYPTION) + AeadCipherService userCredentialAeadCipherService, + @Named(AeadEncryptionModule.DATA_STORAGE_ENCRYPTION) + AeadCipherService dataStorageAeadCipherService + ) { this.hostname = hostname; this.discoveryService = discoveryService; this.handlers = handlers; @@ -158,6 +167,8 @@ public AppFabricServer(CConfiguration cConf, SConfiguration sConf, this.commonNettyHttpServiceFactory = commonNettyHttpServiceFactory; this.sourceControlOperationRunner = sourceControlOperationRunner; this.repositoryCleanupService = repositoryCleanupService; + this.userEncryptionAeadCipherService = userCredentialAeadCipherService; + this.dataStorageAeadCipherService = dataStorageAeadCipherService; } /** @@ -170,10 +181,6 @@ protected void startUp() throws Exception { Constants.Logging.COMPONENT_NAME, Constants.Service.APP_FABRIC_HTTP)); List> futuresList = new ArrayList<>(); - FeatureFlagsProvider featureFlagsProvider = new DefaultFeatureFlagsProvider(cConf); - if (Feature.NAMESPACED_SERVICE_ACCOUNTS.isEnabled(featureFlagsProvider)) { - futuresList.add(namespaceCredentialProviderService.start()); - } futuresList.addAll(ImmutableList.of( provisioningService.start(), applicationLifecycleService.start(), @@ -188,9 +195,18 @@ protected void startUp() throws Exception { runRecordCounterService.start(), runRecordTimeToLiveService.start(), sourceControlOperationRunner.start(), - repositoryCleanupService.start() + repositoryCleanupService.start(), + userEncryptionAeadCipherService.start(), + dataStorageAeadCipherService.start() )); Futures.allAsList(futuresList).get(); + // namespaceCredentialProviderService depends on dataStorageAeadCipherService, so we wait for + // all of them to start first. + FeatureFlagsProvider featureFlagsProvider = new DefaultFeatureFlagsProvider(cConf); + if (Feature.NAMESPACED_SERVICE_ACCOUNTS.isEnabled(featureFlagsProvider)) { + namespaceCredentialProviderService.startAndWait(); + } + // Create handler hooks List handlerHooks = handlerHookNames.stream() @@ -249,6 +265,8 @@ protected void shutDown() throws Exception { repositoryCleanupService.stopAndWait(); credentialProviderService.stopAndWait(); namespaceCredentialProviderService.stopAndWait(); + userEncryptionAeadCipherService.stopAndWait(); + dataStorageAeadCipherService.stopAndWait(); } private Cancellable startHttpService(NettyHttpService httpService) throws Exception { diff --git a/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/credential/CredentialIdentityManager.java b/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/credential/CredentialIdentityManager.java index 863370235cd6..a9678f87f1c8 100644 --- a/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/credential/CredentialIdentityManager.java +++ b/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/credential/CredentialIdentityManager.java @@ -23,6 +23,7 @@ import io.cdap.cdap.proto.credential.CredentialIdentity; import io.cdap.cdap.proto.id.CredentialIdentityId; import io.cdap.cdap.proto.id.CredentialProfileId; +import io.cdap.cdap.security.spi.encryption.CipherOperationException; import io.cdap.cdap.spi.data.StructuredTableContext; import io.cdap.cdap.spi.data.transaction.TransactionRunner; import io.cdap.cdap.spi.data.transaction.TransactionRunners; @@ -70,7 +71,11 @@ public Collection list(String namespace) throws IOExceptio */ public Optional get(CredentialIdentityId id) throws IOException { return TransactionRunners.run(transactionRunner, context -> { - return identityStore.get(context, id); + try { + return identityStore.get(context, id); + } catch (CipherOperationException e) { + throw new IOException("Failed to decrypt identity", e); + } }, IOException.class); } @@ -86,7 +91,7 @@ public Optional get(CredentialIdentityId id) throws IOExcept public void create(CredentialIdentityId id, CredentialIdentity identity) throws AlreadyExistsException, IOException, NotFoundException { TransactionRunners.run(transactionRunner, context -> { - if (identityStore.get(context, id).isPresent()) { + if (identityStore.exists(context, id)) { throw new AlreadyExistsException(String.format("Credential identity '%s:%s' already exists", id.getNamespace(), id.getName())); } @@ -106,7 +111,7 @@ public void create(CredentialIdentityId id, CredentialIdentity identity) public void update(CredentialIdentityId id, CredentialIdentity identity) throws IOException, NotFoundException { TransactionRunners.run(transactionRunner, context -> { - if (!identityStore.get(context, id).isPresent()) { + if (!identityStore.exists(context, id)) { throw new NotFoundException(String.format("Credential identity '%s:%s' not found", id.getNamespace(), id.getName())); } @@ -123,7 +128,7 @@ public void update(CredentialIdentityId id, CredentialIdentity identity) */ public void delete(CredentialIdentityId id) throws IOException, NotFoundException { TransactionRunners.run(transactionRunner, context -> { - if (!identityStore.get(context, id).isPresent()) { + if (!identityStore.exists(context, id)) { throw new NotFoundException(String.format("Credential identity '%s:%s' not found", id.getNamespace(), id.getName())); } @@ -136,10 +141,14 @@ private void validateAndWriteIdentity(StructuredTableContext context, Credential // Validate the referenced profile exists. CredentialProfileId profileId = new CredentialProfileId(identity.getProfileNamespace(), identity.getProfileName()); - if (!profileStore.get(context, profileId).isPresent()) { + if (!profileStore.exists(context, profileId)) { throw new NotFoundException(String.format("Credential profile '%s:%s' not found", profileId.getNamespace(), profileId.getName())); } - identityStore.write(context, id, identity); + try { + identityStore.write(context, id, identity); + } catch (CipherOperationException e) { + throw new IOException("Failed to encrypt identity", e); + } } } diff --git a/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/credential/CredentialProfileManager.java b/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/credential/CredentialProfileManager.java index 5681076f36f2..56db8ea02ccd 100644 --- a/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/credential/CredentialProfileManager.java +++ b/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/credential/CredentialProfileManager.java @@ -26,6 +26,7 @@ import io.cdap.cdap.proto.credential.CredentialProfile; import io.cdap.cdap.proto.id.CredentialIdentityId; import io.cdap.cdap.proto.id.CredentialProfileId; +import io.cdap.cdap.security.spi.encryption.CipherOperationException; import io.cdap.cdap.security.spi.credential.CredentialProvider; import io.cdap.cdap.security.spi.credential.ProfileValidationException; import io.cdap.cdap.spi.data.transaction.TransactionRunner; @@ -80,7 +81,11 @@ public Collection list(String namespace) throws IOException */ public Optional get(CredentialProfileId id) throws IOException { return TransactionRunners.run(transactionRunner, context -> { - return profileStore.get(context, id); + try { + return profileStore.get(context, id); + } catch (CipherOperationException e) { + throw new IOException("Failed to decrypt profile", e); + } }, IOException.class); } @@ -97,11 +102,15 @@ public void create(CredentialProfileId id, CredentialProfile profile) throws AlreadyExistsException, BadRequestException, IOException { validateProfile(profile); TransactionRunners.run(transactionRunner, context -> { - if (profileStore.get(context, id).isPresent()) { + if (profileStore.exists(context, id)) { throw new AlreadyExistsException(String.format("Credential profile '%s:%s' already exists", id.getNamespace(), id.getName())); } - profileStore.write(context, id, profile); + try { + profileStore.write(context, id, profile); + } catch (CipherOperationException e) { + throw new IOException("Failed to encrypt profile", e); + } }, AlreadyExistsException.class, IOException.class); } @@ -118,11 +127,15 @@ public void update(CredentialProfileId id, CredentialProfile profile) throws BadRequestException, IOException, NotFoundException { validateProfile(profile); TransactionRunners.run(transactionRunner, context -> { - if (!profileStore.get(context, id).isPresent()) { + if (!profileStore.exists(context, id)) { throw new NotFoundException(String.format("Credential profile '%s:%s' not found", id.getNamespace(), id.getName())); } - profileStore.write(context, id, profile); + try { + profileStore.write(context, id, profile); + } catch (CipherOperationException e) { + throw new IOException("Failed to encrypt profile", e); + } }, IOException.class, NotFoundException.class); } @@ -137,7 +150,7 @@ public void update(CredentialProfileId id, CredentialProfile profile) public void delete(CredentialProfileId id) throws ConflictException, IOException, NotFoundException { TransactionRunners.run(transactionRunner, context -> { - if (!profileStore.get(context, id).isPresent()) { + if (!profileStore.exists(context, id)) { throw new NotFoundException(String.format("Credential profile '%s:%s' not found", id.getNamespace(), id.getName())); } diff --git a/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/credential/store/CredentialIdentityStore.java b/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/credential/store/CredentialIdentityStore.java index 3ca48f0ff1e8..c07216daf806 100644 --- a/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/credential/store/CredentialIdentityStore.java +++ b/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/credential/store/CredentialIdentityStore.java @@ -21,6 +21,9 @@ import io.cdap.cdap.proto.credential.CredentialIdentity; import io.cdap.cdap.proto.id.CredentialIdentityId; import io.cdap.cdap.proto.id.CredentialProfileId; +import io.cdap.cdap.security.encryption.AeadCipherService; +import io.cdap.cdap.security.encryption.guice.AeadEncryptionModule; +import io.cdap.cdap.security.spi.encryption.CipherOperationException; import io.cdap.cdap.spi.data.StructuredRow; import io.cdap.cdap.spi.data.StructuredTable; import io.cdap.cdap.spi.data.StructuredTableContext; @@ -29,6 +32,7 @@ import io.cdap.cdap.spi.data.table.field.Range; import io.cdap.cdap.store.StoreDefinition.CredentialProviderStore; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -38,14 +42,26 @@ import java.util.Spliterators; import java.util.stream.Collectors; import java.util.stream.StreamSupport; +import javax.inject.Inject; +import javax.inject.Named; /** * Storage for credential identities. */ public class CredentialIdentityStore { + private static final byte[] CREDENTIAL_IDENTITY_STORE_AD = CredentialIdentityStore.class + .getCanonicalName().getBytes(StandardCharsets.UTF_8); private static final Gson GSON = new Gson(); + private final AeadCipherService dataStorageCipher; + + @Inject + public CredentialIdentityStore(@Named(AeadEncryptionModule.DATA_STORAGE_ENCRYPTION) + AeadCipherService dataStorageCipher) { + this.dataStorageCipher = dataStorageCipher; + } + /** * Lists entries in the credential identity table for a given namespace. * @@ -84,6 +100,24 @@ public Collection listForProfile(StructuredTableContext co } } + /** + * Returns whether an entry exists in the identity table. + * + * @param context The transaction context to use. + * @param id The identity reference to fetch. + * @return Whether the credential identity exists. + */ + public boolean exists(StructuredTableContext context, CredentialIdentityId id) + throws IOException { + StructuredTable table = context.getTable(CredentialProviderStore.CREDENTIAL_IDENTITIES); + Collection> key = Arrays.asList( + Fields.stringField(CredentialProviderStore.NAMESPACE_FIELD, + id.getNamespace()), + Fields.stringField(CredentialProviderStore.IDENTITY_NAME_FIELD, + id.getName())); + return table.read(key).isPresent(); + } + /** * Fetch an entry from the identity table. * @@ -93,15 +127,21 @@ public Collection listForProfile(StructuredTableContext co * @throws IOException If any failure reading from storage occurs. */ public Optional get(StructuredTableContext context, CredentialIdentityId id) - throws IOException { + throws CipherOperationException, IOException { StructuredTable table = context.getTable(CredentialProviderStore.CREDENTIAL_IDENTITIES); Collection> key = Arrays.asList( Fields.stringField(CredentialProviderStore.NAMESPACE_FIELD, id.getNamespace()), Fields.stringField(CredentialProviderStore.IDENTITY_NAME_FIELD, id.getName())); - return table.read(key).map(row -> GSON.fromJson(row - .getString(CredentialProviderStore.IDENTITY_DATA_FIELD), CredentialIdentity.class)); + Optional row = table.read(key); + if (!row.isPresent()) { + return Optional.empty(); + } + String decryptedData = new String( + dataStorageCipher.decrypt(row.get().getBytes(CredentialProviderStore.IDENTITY_DATA_FIELD), + CREDENTIAL_IDENTITY_STORE_AD), StandardCharsets.UTF_8); + return Optional.of(GSON.fromJson(decryptedData, CredentialIdentity.class)); } /** @@ -113,7 +153,7 @@ public Optional get(StructuredTableContext context, Credenti * @throws IOException If any failure reading from storage occurs. */ public void write(StructuredTableContext context, CredentialIdentityId id, - CredentialIdentity identity) throws IOException { + CredentialIdentity identity) throws CipherOperationException, IOException { StructuredTable identityTable = context.getTable(CredentialProviderStore.CREDENTIAL_IDENTITIES); Collection> row = Arrays.asList( @@ -121,8 +161,9 @@ public void write(StructuredTableContext context, CredentialIdentityId id, id.getNamespace()), Fields.stringField(CredentialProviderStore.IDENTITY_NAME_FIELD, id.getName()), - Fields.stringField(CredentialProviderStore.IDENTITY_DATA_FIELD, - GSON.toJson(identity)), + Fields.bytesField(CredentialProviderStore.IDENTITY_DATA_FIELD, + dataStorageCipher.encrypt(GSON.toJson(identity).getBytes(StandardCharsets.UTF_8), + CREDENTIAL_IDENTITY_STORE_AD)), Fields.stringField(CredentialProviderStore.IDENTITY_PROFILE_INDEX_FIELD, toProfileIndex(identity.getProfileNamespace(), identity.getProfileName()))); identityTable.upsert(row); diff --git a/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/credential/store/CredentialProfileStore.java b/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/credential/store/CredentialProfileStore.java index fbb76048c000..3ae720957515 100644 --- a/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/credential/store/CredentialProfileStore.java +++ b/cdap-app-fabric/src/main/java/io/cdap/cdap/internal/credential/store/CredentialProfileStore.java @@ -21,6 +21,9 @@ import io.cdap.cdap.common.NotFoundException; import io.cdap.cdap.proto.credential.CredentialProfile; import io.cdap.cdap.proto.id.CredentialProfileId; +import io.cdap.cdap.security.encryption.AeadCipherService; +import io.cdap.cdap.security.encryption.guice.AeadEncryptionModule; +import io.cdap.cdap.security.spi.encryption.CipherOperationException; import io.cdap.cdap.spi.data.StructuredRow; import io.cdap.cdap.spi.data.StructuredTable; import io.cdap.cdap.spi.data.StructuredTableContext; @@ -29,6 +32,7 @@ import io.cdap.cdap.spi.data.table.field.Range; import io.cdap.cdap.store.StoreDefinition.CredentialProviderStore; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -38,14 +42,26 @@ import java.util.Spliterators; import java.util.stream.Collectors; import java.util.stream.StreamSupport; +import javax.inject.Inject; +import javax.inject.Named; /** * Storage for credential identities. */ public class CredentialProfileStore { + private static final byte[] CREDENTIAL_PROFILE_STORE_AD = CredentialProviderStore.class + .getCanonicalName().getBytes(StandardCharsets.UTF_8); private static final Gson GSON = new Gson(); + private final AeadCipherService dataStorageCipher; + + @Inject + public CredentialProfileStore(@Named(AeadEncryptionModule.DATA_STORAGE_ENCRYPTION) + AeadCipherService dataStorageCipher) { + this.dataStorageCipher = dataStorageCipher; + } + /** * Lists entries in the credential profile table for a given namespace. * @@ -65,6 +81,23 @@ public Collection list(StructuredTableContext context, Stri } } + /** + * Returns whether an entry exists in the profile table. + * + * @param context The transaction context to use. + * @param id The profile reference to fetch. + * @return Whether the credential profile exists. + */ + public boolean exists(StructuredTableContext context, CredentialProfileId id) throws IOException { + StructuredTable table = context.getTable(CredentialProviderStore.CREDENTIAL_PROFILES); + Collection> key = Arrays.asList( + Fields.stringField(CredentialProviderStore.NAMESPACE_FIELD, + id.getNamespace()), + Fields.stringField(CredentialProviderStore.PROFILE_NAME_FIELD, + id.getName())); + return table.read(key).isPresent(); + } + /** * Fetch an entry from the profile table. * @@ -74,15 +107,21 @@ public Collection list(StructuredTableContext context, Stri * @throws IOException If any failure reading from storage occurs. */ public Optional get(StructuredTableContext context, CredentialProfileId id) - throws IOException { + throws CipherOperationException, IOException { StructuredTable table = context.getTable(CredentialProviderStore.CREDENTIAL_PROFILES); Collection> key = Arrays.asList( Fields.stringField(CredentialProviderStore.NAMESPACE_FIELD, id.getNamespace()), Fields.stringField(CredentialProviderStore.PROFILE_NAME_FIELD, id.getName())); - return table.read(key).map(row -> GSON.fromJson(row - .getString(CredentialProviderStore.PROFILE_DATA_FIELD), CredentialProfile.class)); + Optional row = table.read(key); + if (!row.isPresent()) { + return Optional.empty(); + } + String decryptedData = new String(dataStorageCipher + .decrypt(row.get().getBytes(CredentialProviderStore.PROFILE_DATA_FIELD), + CREDENTIAL_PROFILE_STORE_AD), StandardCharsets.UTF_8); + return Optional.of(GSON.fromJson(decryptedData, CredentialProfile.class)); } /** @@ -94,15 +133,16 @@ public Optional get(StructuredTableContext context, Credentia * @throws IOException If any failure reading from storage occurs. */ public void write(StructuredTableContext context, CredentialProfileId id, - CredentialProfile profile) throws IOException { + CredentialProfile profile) throws CipherOperationException, IOException { StructuredTable table = context.getTable(CredentialProviderStore.CREDENTIAL_PROFILES); Collection> row = Arrays.asList( Fields.stringField(CredentialProviderStore.NAMESPACE_FIELD, id.getNamespace()), Fields.stringField(CredentialProviderStore.PROFILE_NAME_FIELD, id.getName()), - Fields.stringField(CredentialProviderStore.PROFILE_DATA_FIELD, - GSON.toJson(profile))); + Fields.bytesField(CredentialProviderStore.PROFILE_DATA_FIELD, + dataStorageCipher.encrypt(GSON.toJson(profile).getBytes(StandardCharsets.UTF_8), + CREDENTIAL_PROFILE_STORE_AD))); table.upsert(row); } diff --git a/cdap-app-fabric/src/test/java/io/cdap/cdap/internal/credential/CredentialProviderTestBase.java b/cdap-app-fabric/src/test/java/io/cdap/cdap/internal/credential/CredentialProviderTestBase.java index 73842c91f96e..1acc9732e3ef 100644 --- a/cdap-app-fabric/src/test/java/io/cdap/cdap/internal/credential/CredentialProviderTestBase.java +++ b/cdap-app-fabric/src/test/java/io/cdap/cdap/internal/credential/CredentialProviderTestBase.java @@ -38,6 +38,7 @@ import io.cdap.cdap.proto.credential.ProvisionedCredential; import io.cdap.cdap.proto.id.CredentialProfileId; import io.cdap.cdap.security.authorization.AuthorizationEnforcementModule; +import io.cdap.cdap.security.encryption.NoOpAeadCipherService; import io.cdap.cdap.security.spi.authorization.ContextAccessEnforcer; import io.cdap.cdap.security.spi.credential.CredentialProvider; import io.cdap.cdap.security.spi.credential.ProfileValidationException; @@ -121,8 +122,9 @@ protected void configure() { // Setup credential managers. TransactionRunner runner = injector.getInstance(TransactionRunner.class); - CredentialProfileStore profileStore = new CredentialProfileStore(); - CredentialIdentityStore identityStore = new CredentialIdentityStore(); + CredentialProfileStore profileStore = new CredentialProfileStore(new NoOpAeadCipherService()); + CredentialIdentityStore identityStore = new CredentialIdentityStore( + new NoOpAeadCipherService()); credentialProfileManager = new CredentialProfileManager(identityStore, profileStore, runner, mockCredentialProviderLoader); credentialIdentityManager = new CredentialIdentityManager(identityStore, profileStore, diff --git a/cdap-data-fabric/src/main/java/io/cdap/cdap/store/StoreDefinition.java b/cdap-data-fabric/src/main/java/io/cdap/cdap/store/StoreDefinition.java index 0c71048b439f..10cb3304e4ae 100644 --- a/cdap-data-fabric/src/main/java/io/cdap/cdap/store/StoreDefinition.java +++ b/cdap-data-fabric/src/main/java/io/cdap/cdap/store/StoreDefinition.java @@ -1298,7 +1298,7 @@ public static final class CredentialProviderStore { .withId(CREDENTIAL_PROFILES) .withFields(Fields.stringType(NAMESPACE_FIELD), Fields.stringType(PROFILE_NAME_FIELD), - Fields.stringType(PROFILE_DATA_FIELD)) + Fields.bytesType(PROFILE_DATA_FIELD)) .withPrimaryKeys(NAMESPACE_FIELD, PROFILE_NAME_FIELD) .build(); @@ -1308,7 +1308,7 @@ public static final class CredentialProviderStore { .withFields(Fields.stringType(NAMESPACE_FIELD), Fields.stringType(IDENTITY_NAME_FIELD), Fields.stringType(IDENTITY_PROFILE_INDEX_FIELD), - Fields.stringType(IDENTITY_DATA_FIELD)) + Fields.bytesType(IDENTITY_DATA_FIELD)) .withPrimaryKeys(NAMESPACE_FIELD, IDENTITY_NAME_FIELD) .withIndexes(IDENTITY_PROFILE_INDEX_FIELD) .build();