, U extends ApplicationProperties> {
- /**
- * Returns the number of properties, excluding protection scheme properties.
- *
- * Example:
- *
- * key: E(value, key)
- * key.protected: aes/gcm/256
- * key2: value2
- *
- * would return size 2
- *
- * @return the count of real properties
- */
- int size();
-
- /**
- * Retrieves all known property keys.
- *
- * @return all known property keys
- */
- Set getPropertyKeys();
-
- /**
- * Returns the complete set of property keys, including any protection keys (i.e. 'x.y.z.protected').
- *
- * @return the set of property keys
- */
- Set getPropertyKeysIncludingProtectionSchemes();
-
- /**
- * Returns a list of the keys identifying "sensitive" properties. There is a default list,
- * and additional keys can be provided in the {@code nifi.sensitive.props.additional.keys} property in the ApplicationProperties.
- *
- * @return the list of sensitive property keys
- */
- List getSensitivePropertyKeys();
-
- /**
- * Returns a list of the keys identifying "sensitive" properties. There is a default list,
- * and additional keys can be provided in the {@code nifi.sensitive.props.additional.keys} property in the ApplicationProperties.
- *
- * @return the list of sensitive property keys
- */
- List getPopulatedSensitivePropertyKeys();
-
- /**
- * Returns true if any sensitive keys are protected.
- *
- * @return true if any key is protected; false otherwise
- */
- boolean hasProtectedKeys();
-
- /**
- * Returns a Map of the keys identifying "sensitive" properties that are currently protected and the "protection" key for each.
- * This may or may not include all properties marked as sensitive.
- *
- * @return the Map of protected property keys and the protection identifier for each
- */
- Map getProtectedPropertyKeys();
-
- /**
- * Returns true if the property identified by this key is considered sensitive in this instance of {@code ApplicationProperties}.
- * Some properties are sensitive by default, while others can be specified by
- * {@link ProtectedProperties#getAdditionalSensitivePropertiesKeys()}.
- *
- * @param key the key
- * @return true if it is sensitive
- */
- boolean isPropertySensitive(String key);
-
- /**
- * Returns the unprotected {@link ApplicationProperties} instance. If none of the properties
- * loaded are marked as protected, it will simply pass through the internal instance.
- * If any are protected, it will drop the protection scheme keys and translate each
- * protected value (encrypted, HSM-retrieved, etc.) into the raw value and store it
- * under the original key.
- *
- * If any property fails to unprotect, it will save that key and continue. After
- * attempting all properties, it will throw an exception containing all failed
- * properties. This is necessary because the order is not enforced, so all failed
- * properties should be gathered together.
- *
- * @return the ApplicationProperties instance with all raw values
- * @throws SensitivePropertyProtectionException if there is a problem unprotecting one or more keys
- */
- boolean isPropertyProtected(String key);
-
- /**
- * Returns the unprotected ApplicationProperties.
- * @return The unprotected properties
- * @throws SensitivePropertyProtectionException if there is a problem unprotecting one or more keys
- */
- U getUnprotectedProperties() throws SensitivePropertyProtectionException;
-
- /**
- * Registers a new {@link SensitivePropertyProvider}. This method will throw a {@link UnsupportedOperationException}
- * if a provider is already registered for the protection scheme.
- *
- * @param sensitivePropertyProvider the provider
- */
- void addSensitivePropertyProvider(SensitivePropertyProvider sensitivePropertyProvider);
-}
diff --git a/nifi-commons/nifi-property-protection-api/src/main/java/org/apache/nifi/properties/SensitivePropertyProvider.java b/nifi-commons/nifi-property-protection-api/src/main/java/org/apache/nifi/properties/SensitivePropertyProvider.java
deleted file mode 100644
index 2b57fc49fc6b..000000000000
--- a/nifi-commons/nifi-property-protection-api/src/main/java/org/apache/nifi/properties/SensitivePropertyProvider.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.nifi.properties;
-
-/**
- * Sensitive Property Provider abstracts persistence and retrieval of properties that require additional protection
- */
-public interface SensitivePropertyProvider {
- /**
- * Returns the key used to identify the provider implementation in {@code nifi.properties}.
- *
- * @return the key to persist in the sibling property
- */
- String getIdentifierKey();
-
- /**
- * Returns whether this SensitivePropertyProvider is supported with the current system
- * configuration.
- * @return Whether this SensitivePropertyProvider is supported
- */
- boolean isSupported();
-
- /**
- * Returns the "protected" form of this value. This is a form which can safely be persisted in the {@code nifi.properties} file without compromising the value.
- * An encryption-based provider would return a cipher text, while a remote-lookup provider could return a unique ID to retrieve the secured value.
- *
- * @param unprotectedValue the sensitive value
- * @param context The context of the value
- * @return the value to persist in the {@code nifi.properties} file
- */
- String protect(String unprotectedValue, ProtectedPropertyContext context) throws SensitivePropertyProtectionException;
-
- /**
- * Returns the "unprotected" form of this value. This is the raw sensitive value which is used by the application logic.
- * An encryption-based provider would decrypt a cipher text and return the plaintext, while a remote-lookup provider could retrieve the secured value.
- *
- * @param protectedValue the protected value read from the {@code nifi.properties} file
- * @param context The context of the value
- * @return the raw value to be used by the application
- */
- String unprotect(String protectedValue, ProtectedPropertyContext context) throws SensitivePropertyProtectionException;
-
- /**
- * Cleans up resources that may have been allocated/used by an SPP implementation
- */
- void cleanUp();
-}
diff --git a/nifi-commons/nifi-property-protection-api/src/main/java/org/apache/nifi/properties/SensitivePropertyProviderFactory.java b/nifi-commons/nifi-property-protection-api/src/main/java/org/apache/nifi/properties/SensitivePropertyProviderFactory.java
deleted file mode 100644
index 75bbee2a0f0e..000000000000
--- a/nifi-commons/nifi-property-protection-api/src/main/java/org/apache/nifi/properties/SensitivePropertyProviderFactory.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import org.apache.nifi.properties.scheme.ProtectionScheme;
-
-import java.util.Collection;
-
-/**
- * Sensitive Property Provider Factory abstracts instantiation of supported providers
- */
-public interface SensitivePropertyProviderFactory {
- /**
- * Get Provider for specified Protection Strategy
- *
- * @param protectionScheme Protection Strategy requested
- * @return Property Provider implementation
- */
- SensitivePropertyProvider getProvider(ProtectionScheme protectionScheme);
-
- /**
- * Get Supported Property Providers
- *
- * @return Collection of supported provider implementations
- */
- Collection getSupportedProviders();
-
- /**
- * Returns a ProtectedPropertyContext with the given property name. The ProtectedPropertyContext's
- * contextName will be the name found in a matching context mapping from bootstrap.conf, or 'default' if
- * no matching mapping was found.
- *
- * @param groupIdentifier The identifier of a group that contains the configuration property. The definition
- * of a group depends on the type of configuration file.
- * @param propertyName A property name
- * @return The property context, using any mappings configured in bootstrap.conf to match against the
- * provided group identifier (or the default context if none match).
- */
- ProtectedPropertyContext getPropertyContext(String groupIdentifier, String propertyName);
-}
diff --git a/nifi-commons/nifi-property-protection-api/src/main/java/org/apache/nifi/properties/scheme/ProtectionScheme.java b/nifi-commons/nifi-property-protection-api/src/main/java/org/apache/nifi/properties/scheme/ProtectionScheme.java
deleted file mode 100644
index cb703821fe66..000000000000
--- a/nifi-commons/nifi-property-protection-api/src/main/java/org/apache/nifi/properties/scheme/ProtectionScheme.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.nifi.properties.scheme;
-
-/**
- * Definition of Protection Scheme
- */
-public interface ProtectionScheme {
- /**
- * Get path of the protection scheme definition
- *
- * @return Protection scheme path
- */
- String getPath();
-}
diff --git a/nifi-commons/nifi-property-protection-api/src/main/java/org/apache/nifi/properties/scheme/ProtectionSchemeResolver.java b/nifi-commons/nifi-property-protection-api/src/main/java/org/apache/nifi/properties/scheme/ProtectionSchemeResolver.java
deleted file mode 100644
index adb780b1d22a..000000000000
--- a/nifi-commons/nifi-property-protection-api/src/main/java/org/apache/nifi/properties/scheme/ProtectionSchemeResolver.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.nifi.properties.scheme;
-
-/**
- * Protection Scheme Resolver abstracts resolution of Protection Scheme references from string arguments
- */
-public interface ProtectionSchemeResolver {
- /**
- * Get Protection Scheme
- *
- * @param scheme Scheme name required
- * @return Protection Scheme
- */
- ProtectionScheme getProtectionScheme(String scheme);
-}
diff --git a/nifi-commons/nifi-property-protection-api/src/main/java/org/apache/nifi/properties/scheme/StandardProtectionScheme.java b/nifi-commons/nifi-property-protection-api/src/main/java/org/apache/nifi/properties/scheme/StandardProtectionScheme.java
deleted file mode 100644
index c0ce8d930fe9..000000000000
--- a/nifi-commons/nifi-property-protection-api/src/main/java/org/apache/nifi/properties/scheme/StandardProtectionScheme.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.nifi.properties.scheme;
-
-import java.util.Objects;
-
-/**
- * Standard implementation of Protection Scheme with configurable parameters
- */
-public class StandardProtectionScheme implements ProtectionScheme {
- private String path;
-
- public StandardProtectionScheme(final String path) {
- this.path = Objects.requireNonNull(path, "Path required");
- }
-
- @Override
- public String getPath() {
- return path;
- }
-}
diff --git a/nifi-commons/nifi-property-protection-aws/pom.xml b/nifi-commons/nifi-property-protection-aws/pom.xml
deleted file mode 100644
index b722bba5eebb..000000000000
--- a/nifi-commons/nifi-property-protection-aws/pom.xml
+++ /dev/null
@@ -1,101 +0,0 @@
-
-
-
- 4.0.0
-
- org.apache.nifi
- nifi-commons
- 2.0.0-SNAPSHOT
-
- nifi-property-protection-aws
-
-
- org.slf4j
- slf4j-api
-
-
- org.apache.nifi
- nifi-property-utils
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-property-protection-api
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-property-protection-shared
- 2.0.0-SNAPSHOT
-
-
- org.apache.commons
- commons-lang3
-
-
- com.fasterxml.jackson.core
- jackson-databind
-
-
- com.fasterxml.jackson.core
- jackson-core
-
-
- software.amazon.awssdk
- regions
-
-
- software.amazon.awssdk
- auth
-
-
- software.amazon.awssdk
- kms
-
-
- software.amazon.awssdk
- aws-core
-
-
- software.amazon.awssdk
- sdk-core
-
-
- software.amazon.awssdk
- netty-nio-client
-
-
- software.amazon.awssdk
- apache-client
-
-
-
-
- software.amazon.awssdk
- secretsmanager
-
-
- software.amazon.awssdk
- netty-nio-client
-
-
- software.amazon.awssdk
- apache-client
-
-
-
-
-
diff --git a/nifi-commons/nifi-property-protection-aws/src/main/java/org/apache/nifi/properties/AwsKmsSensitivePropertyProvider.java b/nifi-commons/nifi-property-protection-aws/src/main/java/org/apache/nifi/properties/AwsKmsSensitivePropertyProvider.java
deleted file mode 100644
index 80a34f336d46..000000000000
--- a/nifi-commons/nifi-property-protection-aws/src/main/java/org/apache/nifi/properties/AwsKmsSensitivePropertyProvider.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import software.amazon.awssdk.core.SdkBytes;
-import software.amazon.awssdk.services.kms.KmsClient;
-import software.amazon.awssdk.services.kms.model.DecryptRequest;
-import software.amazon.awssdk.services.kms.model.DecryptResponse;
-import software.amazon.awssdk.services.kms.model.DescribeKeyRequest;
-import software.amazon.awssdk.services.kms.model.DescribeKeyResponse;
-import software.amazon.awssdk.services.kms.model.EncryptRequest;
-import software.amazon.awssdk.services.kms.model.EncryptResponse;
-import software.amazon.awssdk.services.kms.model.KeyMetadata;
-
-import java.util.Properties;
-
-/**
- * Amazon Web Services Key Management Service Sensitive Property Provider
- */
-public class AwsKmsSensitivePropertyProvider extends ClientBasedEncodedSensitivePropertyProvider {
- protected static final String KEY_ID_PROPERTY = "aws.kms.key.id";
-
- private static final String IDENTIFIER_KEY = "aws/kms";
-
- AwsKmsSensitivePropertyProvider(final KmsClient kmsClient, final Properties properties) throws SensitivePropertyProtectionException {
- super(kmsClient, properties);
- }
-
- @Override
- public String getIdentifierKey() {
- return IDENTIFIER_KEY;
- }
-
- /**
- * Close KMS Client when configured
- */
- @Override
- public void cleanUp() {
- final KmsClient kmsClient = getClient();
- if (kmsClient == null) {
- logger.debug("AWS KMS Client not configured");
- } else {
- kmsClient.close();
- }
- }
-
- /**
- * Validate Client and Key Identifier status when client is configured
- *
- * @param kmsClient KMS Client
- */
- @Override
- protected void validate(final KmsClient kmsClient) {
- if (kmsClient == null) {
- logger.debug("AWS KMS Client not configured");
- } else {
- final String keyId = getKeyId();
- try {
- final DescribeKeyRequest describeKeyRequest = DescribeKeyRequest.builder()
- .keyId(keyId)
- .build();
- final DescribeKeyResponse describeKeyResponse = kmsClient.describeKey(describeKeyRequest);
- final KeyMetadata keyMetadata = describeKeyResponse.keyMetadata();
- if (keyMetadata.enabled()) {
- logger.info("AWS KMS Key [{}] Enabled", keyId);
- } else {
- throw new SensitivePropertyProtectionException(String.format("AWS KMS Key [%s] Disabled", keyId));
- }
- } catch (final RuntimeException e) {
- throw new SensitivePropertyProtectionException(String.format("AWS KMS Key [%s] Validation Failed", keyId), e);
- }
- }
- }
-
- /**
- * Get encrypted bytes
- *
- * @param bytes Unprotected bytes
- * @return Encrypted bytes
- */
- @Override
- protected byte[] getEncrypted(final byte[] bytes) {
- final SdkBytes plainBytes = SdkBytes.fromByteArray(bytes);
- final EncryptRequest encryptRequest = EncryptRequest.builder()
- .keyId(getKeyId())
- .plaintext(plainBytes)
- .build();
- final EncryptResponse response = getClient().encrypt(encryptRequest);
- final SdkBytes encryptedData = response.ciphertextBlob();
- return encryptedData.asByteArray();
- }
-
- /**
- * Get decrypted bytes
- *
- * @param bytes Encrypted bytes
- * @return Decrypted bytes
- */
- @Override
- protected byte[] getDecrypted(final byte[] bytes) {
- final SdkBytes cipherBytes = SdkBytes.fromByteArray(bytes);
- final DecryptRequest decryptRequest = DecryptRequest.builder()
- .ciphertextBlob(cipherBytes)
- .keyId(getKeyId())
- .build();
- final DecryptResponse response = getClient().decrypt(decryptRequest);
- final SdkBytes decryptedData = response.plaintext();
- return decryptedData.asByteArray();
- }
-
- private String getKeyId() {
- return getProperties().getProperty(KEY_ID_PROPERTY);
- }
-}
diff --git a/nifi-commons/nifi-property-protection-aws/src/main/java/org/apache/nifi/properties/AwsSecretsManagerSensitivePropertyProvider.java b/nifi-commons/nifi-property-protection-aws/src/main/java/org/apache/nifi/properties/AwsSecretsManagerSensitivePropertyProvider.java
deleted file mode 100644
index cfd3cc5b825c..000000000000
--- a/nifi-commons/nifi-property-protection-aws/src/main/java/org/apache/nifi/properties/AwsSecretsManagerSensitivePropertyProvider.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient;
-import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueResponse;
-import software.amazon.awssdk.services.secretsmanager.model.ResourceNotFoundException;
-import software.amazon.awssdk.services.secretsmanager.model.SecretsManagerException;
-
-import java.util.Objects;
-import java.util.Optional;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-/**
- * Amazon Web Services Secrets Manager implementation of Sensitive Property Provider
- */
-public class AwsSecretsManagerSensitivePropertyProvider implements SensitivePropertyProvider {
- private static final String IDENTIFIER_KEY = "aws/secretsmanager";
-
- private final SecretsManagerClient client;
- private final ObjectMapper objectMapper;
-
- private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
- private final Lock readLock = rwLock.readLock();
- private final Lock writeLock = rwLock.writeLock();
-
- AwsSecretsManagerSensitivePropertyProvider(final SecretsManagerClient client) {
- this.client = client;
- this.objectMapper = new ObjectMapper();
- }
-
- @Override
- public String getIdentifierKey() {
- return IDENTIFIER_KEY;
- }
-
- @Override
- public boolean isSupported() {
- return client != null;
- }
-
- @Override
- public String protect(final String unprotectedValue, final ProtectedPropertyContext context)
- throws SensitivePropertyProtectionException {
- Objects.requireNonNull(context, "Property context must be provided");
- Objects.requireNonNull(unprotectedValue, "Property value must be provided");
-
- if (client == null) {
- throw new SensitivePropertyProtectionException("AWS Secrets Manager Provider Not Configured");
- }
-
- try {
- writeLock.lock();
- final String secretName = context.getContextName();
- final Optional secretKeyValuesOptional = getSecretKeyValues(context);
- final ObjectNode secretObject = secretKeyValuesOptional.orElse(objectMapper.createObjectNode());
-
- secretObject.put(context.getPropertyName(), unprotectedValue);
- final String secretString = objectMapper.writeValueAsString(secretObject);
-
- if (secretKeyValuesOptional.isPresent()) {
- client.putSecretValue(builder -> builder.secretId(secretName).secretString(secretString));
- } else {
- client.createSecret(builder -> builder.name(secretName).secretString(secretString));
- }
- return context.getContextKey();
- } catch (final SecretsManagerException | JsonProcessingException e) {
- throw new SensitivePropertyProtectionException(String.format("AWS Secrets Manager Secret Could Not Be Stored for [%s]", context), e);
- } finally {
- writeLock.unlock();
- }
- }
-
- @Override
- public String unprotect(final String protectedValue, final ProtectedPropertyContext context)
- throws SensitivePropertyProtectionException {
- Objects.requireNonNull(context, "Property context must be provided");
-
- if (client == null) {
- throw new SensitivePropertyProtectionException("AWS Secrets Manager Provider Not Configured");
- }
- try {
- readLock.lock();
-
- String propertyValue = null;
- final Optional secretKeyValuesOptional = getSecretKeyValues(context);
- if (secretKeyValuesOptional.isPresent()) {
- final ObjectNode secretKeyValues = secretKeyValuesOptional.get();
- final String propertyName = context.getPropertyName();
- if (secretKeyValues.has(propertyName)) {
- propertyValue = secretKeyValues.get(propertyName).textValue();
- }
- }
- if (propertyValue == null) {
- throw new SensitivePropertyProtectionException(
- String.format("AWS Secret Name [%s] Property Name [%s] not found", context.getContextName(), context.getPropertyName()));
- }
-
- return propertyValue;
- } finally {
- readLock.unlock();
- }
- }
-
- /**
- * Returns the optional parsed JSON from the matching secret, or empty if the secret does not exist.
- * @param context The property context
- * @return The optional parsed JSON, or empty if the secret does not exist
- */
- private Optional getSecretKeyValues(final ProtectedPropertyContext context) {
- try {
- final GetSecretValueResponse response = client.getSecretValue(builder -> builder.secretId(context.getContextName()));
-
- if (response.secretString() == null) {
- throw new SensitivePropertyProtectionException(String.format("AWS Secret Name [%s] string value not found",
- context.getContextKey()));
- }
- final JsonNode responseNode = objectMapper.readTree(response.secretString());
- if (!(responseNode instanceof ObjectNode)) {
- throw new SensitivePropertyProtectionException(String.format("AWS Secrets Manager Secret [%s] JSON parsing failed",
- context.getContextKey()));
- }
- return Optional.of((ObjectNode) responseNode);
- } catch (final ResourceNotFoundException e) {
- return Optional.empty();
- } catch (final SecretsManagerException e) {
- throw new SensitivePropertyProtectionException(String.format("AWS Secrets Manager Secret [%s] retrieval failed",
- context.getContextKey()), e);
- } catch (final JsonProcessingException e) {
- throw new SensitivePropertyProtectionException(String.format("AWS Secrets Manager Secret [%s] JSON parsing failed",
- context.getContextKey()), e);
- }
- }
-
- @Override
- public void cleanUp() {
- if (client != null) {
- client.close();
- }
- }
-}
diff --git a/nifi-commons/nifi-property-protection-aws/src/main/java/org/apache/nifi/properties/configuration/AbstractAwsClientProvider.java b/nifi-commons/nifi-property-protection-aws/src/main/java/org/apache/nifi/properties/configuration/AbstractAwsClientProvider.java
deleted file mode 100644
index 9b002b60e8a5..000000000000
--- a/nifi-commons/nifi-property-protection-aws/src/main/java/org/apache/nifi/properties/configuration/AbstractAwsClientProvider.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.nifi.properties.configuration;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.nifi.properties.BootstrapProperties;
-import org.apache.nifi.properties.SensitivePropertyProtectionException;
-import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
-import software.amazon.awssdk.auth.credentials.AwsCredentials;
-import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
-import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
-import software.amazon.awssdk.core.SdkClient;
-
-import java.util.Properties;
-
-/**
- * Amazon Web Services Service Client Provider base class
- */
-public abstract class AbstractAwsClientProvider extends BootstrapPropertiesClientProvider {
- private static final String ACCESS_KEY_PROPS_NAME = "aws.access.key.id";
-
- private static final String SECRET_KEY_PROPS_NAME = "aws.secret.access.key";
-
- private static final String REGION_KEY_PROPS_NAME = "aws.region";
-
- public AbstractAwsClientProvider() {
- super(BootstrapProperties.BootstrapPropertyKey.AWS_SENSITIVE_PROPERTY_PROVIDER_CONF);
- }
-
- /**
- * Get Configured Client using either Client Properties or AWS Default Credentials Provider
- *
- * @param clientProperties Client Properties
- * @return KMS Client
- */
- @Override
- protected T getConfiguredClient(final Properties clientProperties) {
- final String accessKey = clientProperties.getProperty(ACCESS_KEY_PROPS_NAME);
- final String secretKey = clientProperties.getProperty(SECRET_KEY_PROPS_NAME);
- final String region = clientProperties.getProperty(REGION_KEY_PROPS_NAME);
-
- if (StringUtils.isNoneBlank(accessKey, secretKey, region)) {
- logger.debug("AWS Credentials Location: Client Properties");
- try {
- final AwsBasicCredentials credentials = AwsBasicCredentials.create(accessKey, secretKey);
- return createClient(credentials, region);
- } catch (final RuntimeException e) {
- throw new SensitivePropertyProtectionException("AWS Client Builder Failed using Client Properties", e);
- }
- } else {
- logger.debug("AWS Credentials Location: Default Credentials Provider");
- try {
- final DefaultCredentialsProvider credentialsProvider = DefaultCredentialsProvider.builder().build();
- return createDefaultClient(credentialsProvider);
- } catch (final RuntimeException e) {
- throw new SensitivePropertyProtectionException("AWS Client Builder Failed using Default Credentials Provider", e);
- }
- }
- }
-
- /**
- * Create a client with the given credentials and region.
- * @param credentials AWS credentials
- * @param region AWS region
- * @return The created client
- */
- protected abstract T createClient(AwsCredentials credentials, String region);
-
- /**
- * Create a default client with the given credentials provider.
- * @param credentialsProvider AWS credentials provider
- * @return The created client
- */
- protected abstract T createDefaultClient(AwsCredentialsProvider credentialsProvider);
-}
diff --git a/nifi-commons/nifi-property-protection-aws/src/main/java/org/apache/nifi/properties/configuration/AwsKmsClientProvider.java b/nifi-commons/nifi-property-protection-aws/src/main/java/org/apache/nifi/properties/configuration/AwsKmsClientProvider.java
deleted file mode 100644
index d501735acae0..000000000000
--- a/nifi-commons/nifi-property-protection-aws/src/main/java/org/apache/nifi/properties/configuration/AwsKmsClientProvider.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.nifi.properties.configuration;
-
-import software.amazon.awssdk.auth.credentials.AwsCredentials;
-import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
-import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
-import software.amazon.awssdk.regions.Region;
-import software.amazon.awssdk.services.kms.KmsClient;
-
-import java.util.Collections;
-import java.util.Set;
-
-/**
- * Amazon Web Services Key Management Service Client Provider
- */
-public class AwsKmsClientProvider extends AbstractAwsClientProvider {
-
- protected static final String KEY_ID_PROPERTY = "aws.kms.key.id";
-
- @Override
- protected KmsClient createClient(final AwsCredentials credentials, final String region) {
- return KmsClient.builder()
- .credentialsProvider(StaticCredentialsProvider.create(credentials))
- .region(Region.of(region))
- .build();
- }
-
- @Override
- protected KmsClient createDefaultClient(final AwsCredentialsProvider credentialsProvider) {
- return KmsClient.builder().credentialsProvider(credentialsProvider).build();
- }
-
- @Override
- protected Set getRequiredPropertyNames() {
- return Collections.singleton(KEY_ID_PROPERTY);
- }
-}
diff --git a/nifi-commons/nifi-property-protection-aws/src/main/java/org/apache/nifi/properties/configuration/AwsSecretsManagerClientProvider.java b/nifi-commons/nifi-property-protection-aws/src/main/java/org/apache/nifi/properties/configuration/AwsSecretsManagerClientProvider.java
deleted file mode 100644
index d0863ddfda58..000000000000
--- a/nifi-commons/nifi-property-protection-aws/src/main/java/org/apache/nifi/properties/configuration/AwsSecretsManagerClientProvider.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.nifi.properties.configuration;
-
-import software.amazon.awssdk.auth.credentials.AwsCredentials;
-import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
-import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
-import software.amazon.awssdk.regions.Region;
-import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient;
-
-import java.util.Collections;
-import java.util.Set;
-
-/**
- * Amazon Web Services Secrets Manager Client Provider
- */
-public class AwsSecretsManagerClientProvider extends AbstractAwsClientProvider {
-
- @Override
- protected SecretsManagerClient createClient(final AwsCredentials credentials, final String region) {
- return SecretsManagerClient.builder()
- .credentialsProvider(StaticCredentialsProvider.create(credentials))
- .region(Region.of(region))
- .build();
- }
-
- @Override
- protected SecretsManagerClient createDefaultClient(final AwsCredentialsProvider credentialsProvider) {
- return SecretsManagerClient.builder().credentialsProvider(credentialsProvider).build();
- }
-
- @Override
- protected Set getRequiredPropertyNames() {
- return Collections.emptySet();
- }
-}
diff --git a/nifi-commons/nifi-property-protection-aws/src/test/java/org/apache/nifi/properties/AwsKmsSensitivePropertyProviderTest.java b/nifi-commons/nifi-property-protection-aws/src/test/java/org/apache/nifi/properties/AwsKmsSensitivePropertyProviderTest.java
deleted file mode 100644
index be747c6e93ca..000000000000
--- a/nifi-commons/nifi-property-protection-aws/src/test/java/org/apache/nifi/properties/AwsKmsSensitivePropertyProviderTest.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import software.amazon.awssdk.core.SdkBytes;
-import software.amazon.awssdk.services.kms.KmsClient;
-import software.amazon.awssdk.services.kms.model.DecryptRequest;
-import software.amazon.awssdk.services.kms.model.DecryptResponse;
-import software.amazon.awssdk.services.kms.model.DescribeKeyRequest;
-import software.amazon.awssdk.services.kms.model.DescribeKeyResponse;
-import software.amazon.awssdk.services.kms.model.EncryptRequest;
-import software.amazon.awssdk.services.kms.model.EncryptResponse;
-import software.amazon.awssdk.services.kms.model.KeyMetadata;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Base64;
-import java.util.Properties;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.mockito.ArgumentMatchers.any;
-
-@ExtendWith(MockitoExtension.class)
-public class AwsKmsSensitivePropertyProviderTest {
- private static final String PROPERTY_NAME = String.class.getSimpleName();
-
- private static final String PROPERTY = String.class.getName();
-
- private static final String ENCRYPTED_PROPERTY = Integer.class.getName();
-
- private static final byte[] ENCRYPTED_BYTES = ENCRYPTED_PROPERTY.getBytes(StandardCharsets.UTF_8);
-
- private static final String PROTECTED_PROPERTY = Base64.getEncoder().withoutPadding().encodeToString(ENCRYPTED_BYTES);
-
- private static final String KEY_ID = AwsKmsSensitivePropertyProvider.class.getSimpleName();
-
- private static final Properties PROPERTIES = new Properties();
-
- private static final String IDENTIFIER_KEY = "aws/kms";
-
- static {
- PROPERTIES.setProperty(AwsKmsSensitivePropertyProvider.KEY_ID_PROPERTY, KEY_ID);
- }
-
- @Mock
- private KmsClient kmsClient;
-
- private AwsKmsSensitivePropertyProvider provider;
-
- @BeforeEach
- public void setProvider() {
- final KeyMetadata keyMetadata = KeyMetadata.builder().enabled(true).build();
- final DescribeKeyResponse describeKeyResponse = DescribeKeyResponse.builder().keyMetadata(keyMetadata).build();
- when(kmsClient.describeKey(any(DescribeKeyRequest.class))).thenReturn(describeKeyResponse);
-
- provider = new AwsKmsSensitivePropertyProvider(kmsClient, PROPERTIES);
- }
-
- @Test
- public void testValidateClientNull() {
- final AwsKmsSensitivePropertyProvider provider = new AwsKmsSensitivePropertyProvider(null, PROPERTIES);
- assertNotNull(provider);
- }
-
- @Test
- public void testValidateKeyDisabled() {
- final KeyMetadata keyMetadata = KeyMetadata.builder().enabled(false).build();
- final DescribeKeyResponse describeKeyResponse = DescribeKeyResponse.builder().keyMetadata(keyMetadata).build();
- when(kmsClient.describeKey(any(DescribeKeyRequest.class))).thenReturn(describeKeyResponse);
-
- assertThrows(SensitivePropertyProtectionException.class, () -> new AwsKmsSensitivePropertyProvider(kmsClient, PROPERTIES));
- }
-
- @Test
- public void testCleanUp() {
- provider.cleanUp();
- verify(kmsClient).close();
- }
-
- @Test
- public void testProtect() {
- final SdkBytes blob = SdkBytes.fromUtf8String(ENCRYPTED_PROPERTY);
- final EncryptResponse encryptResponse = EncryptResponse.builder().ciphertextBlob(blob).build();
- when(kmsClient.encrypt(any(EncryptRequest.class))).thenReturn(encryptResponse);
-
- final String protectedProperty = provider.protect(PROPERTY, ProtectedPropertyContext.defaultContext(PROPERTY_NAME));
- assertEquals(PROTECTED_PROPERTY, protectedProperty);
- }
-
- @Test
- public void testUnprotect() {
- final SdkBytes blob = SdkBytes.fromUtf8String(PROPERTY);
- final DecryptResponse decryptResponse = DecryptResponse.builder().plaintext(blob).build();
- when(kmsClient.decrypt(any(DecryptRequest.class))).thenReturn(decryptResponse);
-
- final String property = provider.unprotect(PROTECTED_PROPERTY, ProtectedPropertyContext.defaultContext(PROPERTY_NAME));
- assertEquals(PROPERTY, property);
- }
-
- @Test
- public void testGetIdentifierKey() {
- final String identifierKey = provider.getIdentifierKey();
- assertEquals(IDENTIFIER_KEY, identifierKey);
- }
-}
diff --git a/nifi-commons/nifi-property-protection-aws/src/test/java/org/apache/nifi/properties/AwsSecretsManagerSensitivePropertyProviderTest.java b/nifi-commons/nifi-property-protection-aws/src/test/java/org/apache/nifi/properties/AwsSecretsManagerSensitivePropertyProviderTest.java
deleted file mode 100644
index 09f85e63e65b..000000000000
--- a/nifi-commons/nifi-property-protection-aws/src/test/java/org/apache/nifi/properties/AwsSecretsManagerSensitivePropertyProviderTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import software.amazon.awssdk.core.SdkBytes;
-import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient;
-import software.amazon.awssdk.services.secretsmanager.model.CreateSecretResponse;
-import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueResponse;
-import software.amazon.awssdk.services.secretsmanager.model.PutSecretValueResponse;
-import software.amazon.awssdk.services.secretsmanager.model.ResourceNotFoundException;
-
-import java.nio.charset.Charset;
-import java.util.function.Consumer;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-@ExtendWith(MockitoExtension.class)
-public class AwsSecretsManagerSensitivePropertyProviderTest {
- private static final String PROPERTY_NAME = "propertyName";
- private static final String PROPERTY_VALUE = "propertyValue";
-
- private static final String SECRET_STRING = String.format("{ \"%s\": \"%s\" }", PROPERTY_NAME, PROPERTY_VALUE);
-
- private static final String IDENTIFIER_KEY = "aws/secretsmanager";
-
- @Mock
- private SecretsManagerClient secretsManagerClient;
-
- private AwsSecretsManagerSensitivePropertyProvider provider;
-
- @BeforeEach
- public void setProvider() {
- provider = new AwsSecretsManagerSensitivePropertyProvider(secretsManagerClient);
- }
-
- @Test
- public void testValidateClientNull() {
- final AwsSecretsManagerSensitivePropertyProvider provider = new AwsSecretsManagerSensitivePropertyProvider(null);
- assertNotNull(provider);
- }
-
- @Test
- public void testValidateKeyNoSecretString() {
- final GetSecretValueResponse getSecretValueResponse = GetSecretValueResponse.builder()
- .secretBinary(SdkBytes.fromString("binary", Charset.defaultCharset())).build();
- when(secretsManagerClient.getSecretValue(any(Consumer.class))).thenReturn(getSecretValueResponse);
-
- assertThrows(SensitivePropertyProtectionException.class, () ->
- provider.unprotect("anyValue", ProtectedPropertyContext.defaultContext(PROPERTY_NAME)));
- }
-
- @Test
- public void testCleanUp() {
- provider.cleanUp();
- verify(secretsManagerClient).close();
- }
-
- @Test
- public void testProtectCreateSecret() {
- final String secretName = ProtectedPropertyContext.defaultContext(PROPERTY_NAME).getContextKey();
-
- when(secretsManagerClient.getSecretValue(any(Consumer.class))).thenThrow(ResourceNotFoundException.builder().message("Not found").build());
-
- final CreateSecretResponse createSecretResponse = CreateSecretResponse.builder()
- .name(secretName).build();
- when(secretsManagerClient.createSecret(any(Consumer.class))).thenReturn(createSecretResponse);
-
- final String protectedProperty = provider.protect(PROPERTY_VALUE, ProtectedPropertyContext.defaultContext(PROPERTY_NAME));
- assertEquals(secretName, protectedProperty);
- }
-
- @Test
- public void testProtectExistingSecret() {
- final String secretName = ProtectedPropertyContext.defaultContext(PROPERTY_NAME).getContextKey();
- final GetSecretValueResponse getSecretValueResponse = GetSecretValueResponse.builder().secretString(SECRET_STRING).build();
- when(secretsManagerClient.getSecretValue(any(Consumer.class))).thenReturn(getSecretValueResponse);
-
- final PutSecretValueResponse putSecretValueResponse = PutSecretValueResponse.builder()
- .name(secretName).build();
- when(secretsManagerClient.putSecretValue(any(Consumer.class))).thenReturn(putSecretValueResponse);
-
- final String protectedProperty = provider.protect(PROPERTY_VALUE, ProtectedPropertyContext.defaultContext(PROPERTY_NAME));
- assertEquals(secretName, protectedProperty);
- }
-
- @Test
- public void testUnprotect() {
- final GetSecretValueResponse getSecretValueResponse = GetSecretValueResponse.builder().secretString(SECRET_STRING).build();
- when(secretsManagerClient.getSecretValue(any(Consumer.class))).thenReturn(getSecretValueResponse);
-
- final String property = provider.unprotect("anyValue", ProtectedPropertyContext.defaultContext(PROPERTY_NAME));
- assertEquals(PROPERTY_VALUE, property);
- }
-
-
- @Test
- public void testGetIdentifierKey() {
- final String identifierKey = provider.getIdentifierKey();
- assertEquals(IDENTIFIER_KEY, identifierKey);
- }
-}
diff --git a/nifi-commons/nifi-property-protection-azure/pom.xml b/nifi-commons/nifi-property-protection-azure/pom.xml
deleted file mode 100644
index 96f939853c89..000000000000
--- a/nifi-commons/nifi-property-protection-azure/pom.xml
+++ /dev/null
@@ -1,104 +0,0 @@
-
-
-
- 4.0.0
-
- org.apache.nifi
- nifi-commons
- 2.0.0-SNAPSHOT
-
- nifi-property-protection-azure
-
-
-
- com.azure
- azure-sdk-bom
- 1.2.24
- import
- pom
-
-
-
-
-
- org.slf4j
- slf4j-api
-
-
- org.apache.nifi
- nifi-property-protection-api
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-property-utils
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-property-protection-shared
- 2.0.0-SNAPSHOT
-
-
- com.azure
- azure-core
-
-
- com.azure
- azure-security-keyvault-secrets
-
-
- com.azure
- azure-core-http-netty
-
-
- io.netty
- netty-tcnative-boringssl-static
-
-
-
-
- com.azure
- azure-security-keyvault-keys
-
-
- com.azure
- azure-core-http-netty
-
-
- io.netty
- netty-tcnative-boringssl-static
-
-
-
-
- com.azure
- azure-identity
-
-
- com.azure
- azure-core-http-netty
-
-
-
-
-
- com.microsoft.azure
- msal4j
- 1.15.1
-
-
-
diff --git a/nifi-commons/nifi-property-protection-azure/src/main/java/org/apache/nifi/properties/AzureKeyVaultKeySensitivePropertyProvider.java b/nifi-commons/nifi-property-protection-azure/src/main/java/org/apache/nifi/properties/AzureKeyVaultKeySensitivePropertyProvider.java
deleted file mode 100644
index 1d60b2a48319..000000000000
--- a/nifi-commons/nifi-property-protection-azure/src/main/java/org/apache/nifi/properties/AzureKeyVaultKeySensitivePropertyProvider.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import com.azure.security.keyvault.keys.models.KeyVaultKey;
-import com.azure.security.keyvault.keys.cryptography.CryptographyClient;
-import com.azure.security.keyvault.keys.cryptography.models.DecryptResult;
-import com.azure.security.keyvault.keys.cryptography.models.EncryptResult;
-import com.azure.security.keyvault.keys.cryptography.models.EncryptionAlgorithm;
-import com.azure.security.keyvault.keys.models.KeyOperation;
-import com.azure.security.keyvault.keys.models.KeyProperties;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Properties;
-
-/**
- * Microsoft Azure Key Vault Key Sensitive Property Provider using Cryptography Client for encryption operations
- */
-public class AzureKeyVaultKeySensitivePropertyProvider extends ClientBasedEncodedSensitivePropertyProvider {
- protected static final String ENCRYPTION_ALGORITHM_PROPERTY = "azure.keyvault.encryption.algorithm";
-
- protected static final List REQUIRED_OPERATIONS = Arrays.asList(KeyOperation.DECRYPT, KeyOperation.ENCRYPT);
-
- private static final String IDENTIFIER_KEY = "azure/keyvault/key";
-
- private EncryptionAlgorithm encryptionAlgorithm;
-
- AzureKeyVaultKeySensitivePropertyProvider(final CryptographyClient cryptographyClient, final Properties properties) {
- super(cryptographyClient, properties);
- }
-
- @Override
- public String getIdentifierKey() {
- return IDENTIFIER_KEY;
- }
-
- /**
- * Validate Client and Key Operations with Encryption Algorithm when configured
- *
- * @param cryptographyClient Cryptography Client
- */
- @Override
- protected void validate(final CryptographyClient cryptographyClient) {
- if (cryptographyClient == null) {
- logger.debug("Azure Cryptography Client not configured");
- } else {
- try {
- final KeyVaultKey keyVaultKey = cryptographyClient.getKey();
- final String id = keyVaultKey.getId();
- final KeyProperties keyProperties = keyVaultKey.getProperties();
- if (keyProperties.isEnabled()) {
- final List keyOperations = keyVaultKey.getKeyOperations();
- if (keyOperations.containsAll(REQUIRED_OPERATIONS)) {
- logger.info("Azure Key Vault Key [{}] Validated", id);
- } else {
- throw new SensitivePropertyProtectionException(String.format("Azure Key Vault Key [%s] Missing Operations %s", id, REQUIRED_OPERATIONS));
- }
- } else {
- throw new SensitivePropertyProtectionException(String.format("Azure Key Vault Key [%s] Disabled", id));
- }
- } catch (final RuntimeException e) {
- throw new SensitivePropertyProtectionException("Azure Key Vault Key Validation Failed", e);
- }
- final String algorithm = getProperties().getProperty(ENCRYPTION_ALGORITHM_PROPERTY);
- if (algorithm == null || algorithm.isEmpty()) {
- throw new SensitivePropertyProtectionException("Azure Key Vault Key Algorithm not configured");
- }
- encryptionAlgorithm = EncryptionAlgorithm.fromString(algorithm);
- }
- }
-
- /**
- * Get encrypted bytes
- *
- * @param bytes Unprotected bytes
- * @return Encrypted bytes
- */
- @Override
- protected byte[] getEncrypted(final byte[] bytes) {
- final EncryptResult encryptResult = getClient().encrypt(encryptionAlgorithm, bytes);
- return encryptResult.getCipherText();
- }
-
- /**
- * Get decrypted bytes
- *
- * @param bytes Encrypted bytes
- * @return Decrypted bytes
- */
- @Override
- protected byte[] getDecrypted(final byte[] bytes) {
- final DecryptResult decryptResult = getClient().decrypt(encryptionAlgorithm, bytes);
- return decryptResult.getPlainText();
- }
-}
diff --git a/nifi-commons/nifi-property-protection-azure/src/main/java/org/apache/nifi/properties/AzureKeyVaultSecretSensitivePropertyProvider.java b/nifi-commons/nifi-property-protection-azure/src/main/java/org/apache/nifi/properties/AzureKeyVaultSecretSensitivePropertyProvider.java
deleted file mode 100644
index e2cbfc70f719..000000000000
--- a/nifi-commons/nifi-property-protection-azure/src/main/java/org/apache/nifi/properties/AzureKeyVaultSecretSensitivePropertyProvider.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import com.azure.core.exception.ResourceNotFoundException;
-import com.azure.security.keyvault.secrets.SecretClient;
-import com.azure.security.keyvault.secrets.models.KeyVaultSecret;
-
-import java.util.Objects;
-
-/**
- * Microsoft Azure Key Vault Secret implementation of Sensitive Property Provider for externalized storage of properties
- */
-public class AzureKeyVaultSecretSensitivePropertyProvider implements SensitivePropertyProvider {
- private static final String FORWARD_SLASH = "/";
-
- private static final String PERIOD = "\\.";
-
- private static final String DASH = "-";
-
- private static final String IDENTIFIER_KEY = "azure/keyvault/secret";
-
- private SecretClient secretClient;
-
- AzureKeyVaultSecretSensitivePropertyProvider(final SecretClient secretClient) {
- this.secretClient = secretClient;
- }
-
- /**
- * Get Identifier key using Protection Scheme
- *
- * @return Identifier key
- */
- @Override
- public String getIdentifierKey() {
- return IDENTIFIER_KEY;
- }
-
- /**
- * Is Provider supported returns status based on configuration of Secret Client
- *
- * @return Supported status
- */
- @Override
- public boolean isSupported() {
- return secretClient != null;
- }
-
- /**
- * Protect value stores a Secret in Azure Key Vault using the Property Context Key as the Secret Name
- *
- * @param unprotectedValue Value to be stored
- * @param context Property Context containing Context Key used to store Secret
- * @return Key Vault Secret Identifier
- * @throws SensitivePropertyProtectionException Thrown when storing Secret failed
- */
- @Override
- public String protect(final String unprotectedValue, final ProtectedPropertyContext context) throws SensitivePropertyProtectionException {
- Objects.requireNonNull(unprotectedValue, "Value required");
- final String secretName = getSecretName(context);
- try {
- final KeyVaultSecret keyVaultSecret = secretClient.setSecret(secretName, unprotectedValue);
- return keyVaultSecret.getId();
- } catch (final RuntimeException e) {
- throw new SensitivePropertyProtectionException(String.format("Set Secret [%s] failed", secretName), e);
- }
- }
-
- /**
- * Unprotect value retrieves a Secret from Azure Key Vault using Property Context Key
- *
- * @param protectedValue Key Vault Secret Identifier is not used
- * @param context Property Context containing Context Key used to retrieve Secret
- * @return Secret Value
- * @throws SensitivePropertyProtectionException Thrown when Secret not found or retrieval failed
- */
- @Override
- public String unprotect(final String protectedValue, final ProtectedPropertyContext context) throws SensitivePropertyProtectionException {
- final String secretName = getSecretName(context);
- try {
- final KeyVaultSecret keyVaultSecret = secretClient.getSecret(secretName);
- return keyVaultSecret.getValue();
- } catch (final ResourceNotFoundException e) {
- throw new SensitivePropertyProtectionException(String.format("Secret [%s] not found", secretName), e);
- } catch (final RuntimeException e) {
- throw new SensitivePropertyProtectionException(String.format("Secret [%s] request failed", secretName), e);
- }
- }
-
- /**
- * Clean up not implemented
- */
- @Override
- public void cleanUp() {
-
- }
-
- private String getSecretName(final ProtectedPropertyContext context) {
- final String contextKey = Objects.requireNonNull(context, "Context required").getContextKey();
- // Replace forward slash and period with dash since Azure Key Vault Secret Names do not support certain characters
- return contextKey.replaceAll(FORWARD_SLASH, DASH).replaceAll(PERIOD, DASH);
- }
-}
diff --git a/nifi-commons/nifi-property-protection-azure/src/main/java/org/apache/nifi/properties/configuration/AzureClientProvider.java b/nifi-commons/nifi-property-protection-azure/src/main/java/org/apache/nifi/properties/configuration/AzureClientProvider.java
deleted file mode 100644
index bc48e45bbe97..000000000000
--- a/nifi-commons/nifi-property-protection-azure/src/main/java/org/apache/nifi/properties/configuration/AzureClientProvider.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.nifi.properties.configuration;
-
-import com.azure.core.credential.TokenCredential;
-import com.azure.identity.DefaultAzureCredentialBuilder;
-import org.apache.nifi.properties.BootstrapProperties;
-
-/**
- * Abstract Microsoft Azure Client Provider
- */
-public abstract class AzureClientProvider extends BootstrapPropertiesClientProvider {
- public AzureClientProvider() {
- super(BootstrapProperties.BootstrapPropertyKey.AZURE_KEYVAULT_SENSITIVE_PROPERTY_PROVIDER_CONF);
- }
-
- /**
- * Get Default Azure Token Credential using Default Credentials Builder for environment variables and system properties
- *
- * @return Token Credential
- */
- protected TokenCredential getDefaultTokenCredential() {
- return new DefaultAzureCredentialBuilder().build();
- }
-}
diff --git a/nifi-commons/nifi-property-protection-azure/src/main/java/org/apache/nifi/properties/configuration/AzureCryptographyClientProvider.java b/nifi-commons/nifi-property-protection-azure/src/main/java/org/apache/nifi/properties/configuration/AzureCryptographyClientProvider.java
deleted file mode 100644
index adf974ee2a19..000000000000
--- a/nifi-commons/nifi-property-protection-azure/src/main/java/org/apache/nifi/properties/configuration/AzureCryptographyClientProvider.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.nifi.properties.configuration;
-
-import com.azure.security.keyvault.keys.cryptography.CryptographyClient;
-import com.azure.security.keyvault.keys.cryptography.CryptographyClientBuilder;
-import org.apache.nifi.properties.SensitivePropertyProtectionException;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Properties;
-import java.util.Set;
-
-/**
- * Microsoft Azure Cryptography Client Provider
- */
-public class AzureCryptographyClientProvider extends AzureClientProvider {
- protected static final String KEY_ID_PROPERTY = "azure.keyvault.key.id";
-
- private static final Set REQUIRED_PROPERTY_NAMES = new HashSet<>(Collections.singletonList(KEY_ID_PROPERTY));
-
- /**
- * Get Configured Client using Default Azure Credentials Builder and configured Key Identifier
- *
- * @param clientProperties Client Properties
- * @return Cryptography Client
- */
- @Override
- protected CryptographyClient getConfiguredClient(final Properties clientProperties) {
- final String keyIdentifier = clientProperties.getProperty(KEY_ID_PROPERTY);
- logger.debug("Azure Cryptography Client with Key Identifier [{}]", keyIdentifier);
-
- try {
- return new CryptographyClientBuilder()
- .credential(getDefaultTokenCredential())
- .keyIdentifier(keyIdentifier)
- .buildClient();
- } catch (final RuntimeException e) {
- throw new SensitivePropertyProtectionException("Azure Cryptography Builder Client Failed using Default Credentials", e);
- }
- }
-
- /**
- * Get required property names for Azure Cryptography Client
- *
- * @return Required client property names
- */
- @Override
- protected Set getRequiredPropertyNames() {
- return REQUIRED_PROPERTY_NAMES;
- }
-}
diff --git a/nifi-commons/nifi-property-protection-azure/src/main/java/org/apache/nifi/properties/configuration/AzureSecretClientProvider.java b/nifi-commons/nifi-property-protection-azure/src/main/java/org/apache/nifi/properties/configuration/AzureSecretClientProvider.java
deleted file mode 100644
index 65432fa6c5eb..000000000000
--- a/nifi-commons/nifi-property-protection-azure/src/main/java/org/apache/nifi/properties/configuration/AzureSecretClientProvider.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.nifi.properties.configuration;
-
-import com.azure.core.credential.TokenCredential;
-import com.azure.identity.DefaultAzureCredentialBuilder;
-import com.azure.security.keyvault.secrets.SecretClient;
-import com.azure.security.keyvault.secrets.SecretClientBuilder;
-import org.apache.nifi.properties.SensitivePropertyProtectionException;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Properties;
-import java.util.Set;
-
-/**
- * Microsoft Azure Secret Client Provider
- */
-public class AzureSecretClientProvider extends AzureClientProvider {
- protected static final String URI_PROPERTY = "azure.keyvault.uri";
-
- private static final Set REQUIRED_PROPERTY_NAMES = new HashSet<>(Collections.singletonList(URI_PROPERTY));
-
- /**
- * Get Secret Client using Default Azure Credentials Builder and default configuration from environment variables
- *
- * @param clientProperties Client Properties
- * @return Secret Client
- */
- @Override
- protected SecretClient getConfiguredClient(final Properties clientProperties) {
- final String uri = clientProperties.getProperty(URI_PROPERTY);
- logger.debug("Azure Secret Client with URI [{}]", uri);
-
- try {
- final TokenCredential credential = new DefaultAzureCredentialBuilder().build();
- return new SecretClientBuilder()
- .credential(credential)
- .vaultUrl(uri)
- .buildClient();
- } catch (final RuntimeException e) {
- throw new SensitivePropertyProtectionException("Azure Secret Builder Client Failed using Default Credentials", e);
- }
- }
-
- /**
- * Get required property names for Azure Secret Client
- *
- * @return Required client property names
- */
- @Override
- protected Set getRequiredPropertyNames() {
- return REQUIRED_PROPERTY_NAMES;
- }
-}
diff --git a/nifi-commons/nifi-property-protection-azure/src/test/java/org/apache/nifi/properties/AzureKeyVaultKeySensitivePropertyProviderTest.java b/nifi-commons/nifi-property-protection-azure/src/test/java/org/apache/nifi/properties/AzureKeyVaultKeySensitivePropertyProviderTest.java
deleted file mode 100644
index 539a90e31de3..000000000000
--- a/nifi-commons/nifi-property-protection-azure/src/test/java/org/apache/nifi/properties/AzureKeyVaultKeySensitivePropertyProviderTest.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import com.azure.security.keyvault.keys.cryptography.CryptographyClient;
-import com.azure.security.keyvault.keys.cryptography.models.DecryptResult;
-import com.azure.security.keyvault.keys.cryptography.models.EncryptResult;
-import com.azure.security.keyvault.keys.cryptography.models.EncryptionAlgorithm;
-import com.azure.security.keyvault.keys.models.KeyProperties;
-import com.azure.security.keyvault.keys.models.KeyVaultKey;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Base64;
-import java.util.Properties;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.when;
-
-@ExtendWith(MockitoExtension.class)
-public class AzureKeyVaultKeySensitivePropertyProviderTest {
- private static final String PROPERTY_NAME = String.class.getSimpleName();
-
- private static final String PROPERTY = String.class.getName();
-
- private static final byte[] PROPERTY_BYTES = PROPERTY.getBytes(StandardCharsets.UTF_8);
-
- private static final String ENCRYPTED_PROPERTY = Integer.class.getName();
-
- private static final byte[] ENCRYPTED_BYTES = ENCRYPTED_PROPERTY.getBytes(StandardCharsets.UTF_8);
-
- private static final String PROTECTED_PROPERTY = Base64.getEncoder().withoutPadding().encodeToString(ENCRYPTED_BYTES);
-
- private static final String ID = KeyVaultKey.class.getSimpleName();
-
- private static final Properties PROPERTIES = new Properties();
-
- private static final EncryptionAlgorithm ALGORITHM = EncryptionAlgorithm.A256GCM;
-
- private static final String IDENTIFIER_KEY = "azure/keyvault/key";
-
- static {
- PROPERTIES.setProperty(AzureKeyVaultKeySensitivePropertyProvider.ENCRYPTION_ALGORITHM_PROPERTY, ALGORITHM.toString());
- }
-
- @Mock
- private CryptographyClient cryptographyClient;
-
- @Mock
- private KeyVaultKey keyVaultKey;
-
- @Mock
- private KeyProperties keyProperties;
-
- private AzureKeyVaultKeySensitivePropertyProvider provider;
-
- @BeforeEach
- public void setProvider() {
- when(keyProperties.isEnabled()).thenReturn(true);
- when(keyVaultKey.getId()).thenReturn(ID);
- when(keyVaultKey.getProperties()).thenReturn(keyProperties);
- when(keyVaultKey.getKeyOperations()).thenReturn(AzureKeyVaultKeySensitivePropertyProvider.REQUIRED_OPERATIONS);
- when(cryptographyClient.getKey()).thenReturn(keyVaultKey);
-
- provider = new AzureKeyVaultKeySensitivePropertyProvider(cryptographyClient, PROPERTIES);
- }
-
- @Test
- public void testValidateClientNull() {
- final AzureKeyVaultKeySensitivePropertyProvider provider = new AzureKeyVaultKeySensitivePropertyProvider(null, PROPERTIES);
- assertNotNull(provider);
- }
-
- @Test
- public void testProtect() {
- final EncryptResult encryptResult = new EncryptResult(ENCRYPTED_BYTES, ALGORITHM, ID);
- when(cryptographyClient.encrypt(eq(ALGORITHM), any(byte[].class))).thenReturn(encryptResult);
-
- final String protectedProperty = provider.protect(PROPERTY, ProtectedPropertyContext.defaultContext(PROPERTY_NAME));
- assertEquals(PROTECTED_PROPERTY, protectedProperty);
- }
-
- @Test
- public void testUnprotect() {
- final DecryptResult decryptResult = new DecryptResult(PROPERTY_BYTES, ALGORITHM, ID);
- when(cryptographyClient.decrypt(eq(ALGORITHM), any(byte[].class))).thenReturn(decryptResult);
-
- final String property = provider.unprotect(PROTECTED_PROPERTY, ProtectedPropertyContext.defaultContext(PROPERTY_NAME));
- assertEquals(PROPERTY, property);
- }
-
- @Test
- public void testGetIdentifierKey() {
- final String identifierKey = provider.getIdentifierKey();
- assertEquals(IDENTIFIER_KEY, identifierKey);
- }
-}
diff --git a/nifi-commons/nifi-property-protection-azure/src/test/java/org/apache/nifi/properties/AzureKeyVaultSecretSensitivePropertyProviderTest.java b/nifi-commons/nifi-property-protection-azure/src/test/java/org/apache/nifi/properties/AzureKeyVaultSecretSensitivePropertyProviderTest.java
deleted file mode 100644
index 399d2fb262af..000000000000
--- a/nifi-commons/nifi-property-protection-azure/src/test/java/org/apache/nifi/properties/AzureKeyVaultSecretSensitivePropertyProviderTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import com.azure.core.exception.AzureException;
-import com.azure.core.exception.ResourceNotFoundException;
-import com.azure.core.http.HttpResponse;
-import com.azure.security.keyvault.secrets.SecretClient;
-import com.azure.security.keyvault.secrets.models.KeyVaultSecret;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.when;
-
-@ExtendWith(MockitoExtension.class)
-public class AzureKeyVaultSecretSensitivePropertyProviderTest {
- private static final String PROPERTY_NAME = "property.name";
-
- private static final String SECRET_NAME = "default-property-name";
-
- private static final String PROPERTY = String.class.getName();
-
- private static final String PROTECTED_PROPERTY = KeyVaultSecret.class.getSimpleName();
-
- private static final String ID = KeyVaultSecret.class.getName();
-
- private static final String IDENTIFIER_KEY = "azure/keyvault/secret";
-
- @Mock
- private SecretClient secretClient;
-
- @Mock
- private KeyVaultSecret keyVaultSecret;
-
- @Mock
- private HttpResponse httpResponse;
-
- private AzureKeyVaultSecretSensitivePropertyProvider provider;
-
- @BeforeEach
- public void setProvider() {
- provider = new AzureKeyVaultSecretSensitivePropertyProvider(secretClient);
- }
-
- @Test
- public void testClientNull() {
- final AzureKeyVaultSecretSensitivePropertyProvider provider = new AzureKeyVaultSecretSensitivePropertyProvider(null);
- assertNotNull(provider);
- assertFalse(provider.isSupported());
- }
-
- @Test
- public void testProtect() {
- when(secretClient.setSecret(eq(SECRET_NAME), eq(PROPERTY))).thenReturn(keyVaultSecret);
- when(keyVaultSecret.getId()).thenReturn(ID);
-
- final ProtectedPropertyContext context = ProtectedPropertyContext.defaultContext(PROPERTY_NAME);
- final String protectedProperty = provider.protect(PROPERTY, context);
- assertEquals(ID, protectedProperty);
- }
-
- @Test
- public void testProtectException() {
- final ProtectedPropertyContext context = ProtectedPropertyContext.defaultContext(PROPERTY_NAME);
- final String secretName = context.getContextKey();
- when(secretClient.setSecret(eq(secretName), eq(PROPERTY))).thenThrow(new AzureException());
-
- assertThrows(SensitivePropertyProtectionException.class, () -> provider.protect(PROPERTY, context));
- }
-
- @Test
- public void testUnprotect() {
- when(secretClient.getSecret(eq(SECRET_NAME))).thenReturn(keyVaultSecret);
- when(keyVaultSecret.getValue()).thenReturn(PROPERTY);
-
- final ProtectedPropertyContext context = ProtectedPropertyContext.defaultContext(PROPERTY_NAME);
- final String property = provider.unprotect(PROTECTED_PROPERTY, context);
- assertEquals(PROPERTY, property);
- }
-
- @Test
- public void testUnprotectResourceNotFoundException() {
- when(secretClient.getSecret(eq(SECRET_NAME))).thenThrow(new ResourceNotFoundException(SECRET_NAME, httpResponse));
-
- final ProtectedPropertyContext context = ProtectedPropertyContext.defaultContext(PROPERTY_NAME);
- assertThrows(SensitivePropertyProtectionException.class, () -> provider.unprotect(PROTECTED_PROPERTY, context));
- }
-
- @Test
- public void testGetIdentifierKey() {
- final String identifierKey = provider.getIdentifierKey();
- assertEquals(IDENTIFIER_KEY, identifierKey);
- }
-}
diff --git a/nifi-commons/nifi-property-protection-azure/src/test/java/org/apache/nifi/properties/configuration/AzureCryptographyClientProviderTest.java b/nifi-commons/nifi-property-protection-azure/src/test/java/org/apache/nifi/properties/configuration/AzureCryptographyClientProviderTest.java
deleted file mode 100644
index 92ac1b9f11a1..000000000000
--- a/nifi-commons/nifi-property-protection-azure/src/test/java/org/apache/nifi/properties/configuration/AzureCryptographyClientProviderTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.nifi.properties.configuration;
-
-import com.azure.security.keyvault.keys.cryptography.CryptographyClient;
-import org.junit.jupiter.api.Test;
-
-import java.util.Optional;
-import java.util.Properties;
-
-import static org.junit.jupiter.api.Assertions.assertFalse;
-
-public class AzureCryptographyClientProviderTest {
-
- @Test
- public void testClientPropertiesNull() {
- final AzureCryptographyClientProvider provider = new AzureCryptographyClientProvider();
- final Optional optionalClient = provider.getClient(null);
- assertFalse(optionalClient.isPresent());
- }
-
- @Test
- public void testClientPropertiesKeyIdBlank() {
- final AzureCryptographyClientProvider provider = new AzureCryptographyClientProvider();
- final Properties clientProperties = new Properties();
- clientProperties.setProperty(AzureCryptographyClientProvider.KEY_ID_PROPERTY, "");
- final Optional optionalClient = provider.getClient(clientProperties);
- assertFalse(optionalClient.isPresent());
- }
-}
diff --git a/nifi-commons/nifi-property-protection-azure/src/test/java/org/apache/nifi/properties/configuration/AzureSecretClientProviderTest.java b/nifi-commons/nifi-property-protection-azure/src/test/java/org/apache/nifi/properties/configuration/AzureSecretClientProviderTest.java
deleted file mode 100644
index 417b52214041..000000000000
--- a/nifi-commons/nifi-property-protection-azure/src/test/java/org/apache/nifi/properties/configuration/AzureSecretClientProviderTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.nifi.properties.configuration;
-
-import com.azure.security.keyvault.secrets.SecretClient;
-import org.junit.jupiter.api.Test;
-
-import java.util.Optional;
-import java.util.Properties;
-
-import static org.junit.jupiter.api.Assertions.assertFalse;
-
-public class AzureSecretClientProviderTest {
-
- @Test
- public void testClientPropertiesNull() {
- final AzureSecretClientProvider provider = new AzureSecretClientProvider();
- final Optional optionalClient = provider.getClient(null);
- assertFalse(optionalClient.isPresent());
- }
-
- @Test
- public void testClientPropertiesUriBlank() {
- final AzureSecretClientProvider provider = new AzureSecretClientProvider();
- final Properties clientProperties = new Properties();
- clientProperties.setProperty(AzureSecretClientProvider.URI_PROPERTY, "");
- final Optional optionalClient = provider.getClient(clientProperties);
- assertFalse(optionalClient.isPresent());
- }
-}
diff --git a/nifi-commons/nifi-property-protection-cipher/pom.xml b/nifi-commons/nifi-property-protection-cipher/pom.xml
deleted file mode 100644
index 1a0aa6ce2528..000000000000
--- a/nifi-commons/nifi-property-protection-cipher/pom.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
- 4.0.0
-
- org.apache.nifi
- nifi-commons
- 2.0.0-SNAPSHOT
-
- nifi-property-protection-cipher
-
-
- org.apache.nifi
- nifi-property-protection-api
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-property-utils
- 2.0.0-SNAPSHOT
-
-
- commons-codec
- commons-codec
-
-
-
diff --git a/nifi-commons/nifi-property-protection-cipher/src/main/java/org/apache/nifi/properties/AesGcmSensitivePropertyProvider.java b/nifi-commons/nifi-property-protection-cipher/src/main/java/org/apache/nifi/properties/AesGcmSensitivePropertyProvider.java
deleted file mode 100644
index 70f94486b9b0..000000000000
--- a/nifi-commons/nifi-property-protection-cipher/src/main/java/org/apache/nifi/properties/AesGcmSensitivePropertyProvider.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import org.apache.commons.codec.DecoderException;
-import org.apache.commons.codec.binary.Hex;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.GCMParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-import java.nio.charset.StandardCharsets;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.Arrays;
-import java.util.Base64;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Sensitive Property Provider implementation using AES-GCM with configurable key sizes
- */
-public class AesGcmSensitivePropertyProvider implements SensitivePropertyProvider {
- private static final String ALGORITHM = "AES/GCM/NoPadding";
- private static final String SECRET_KEY_ALGORITHM = "AES";
- private static final String DELIMITER = "||"; // "|" is not a valid Base64 character, so ensured not to be present in cipher text
- private static final int IV_LENGTH = 12;
- private static final int TAG_LENGTH = 128;
- private static final int MIN_CIPHER_TEXT_LENGTH = IV_LENGTH * 4 / 3 + DELIMITER.length() + 1;
- private static final List VALID_KEY_LENGTHS = Arrays.asList(128, 192, 256);
-
- private static final String IDENTIFIER_KEY_FORMAT = "aes/gcm/%d";
- private static final int BITS_PER_BYTE = 8;
-
- private static final Base64.Encoder BASE_64_ENCODER = Base64.getEncoder();
- private static final Base64.Decoder BASE_64_DECODER = Base64.getDecoder();
-
- private final SecureRandom secureRandom;
- private final Cipher cipher;
- private final SecretKey key;
- private final String identifierKey;
-
- public AesGcmSensitivePropertyProvider(final String keyHex) {
- byte[] keyBytes = validateKey(keyHex);
-
- secureRandom = new SecureRandom();
- try {
- cipher = Cipher.getInstance(ALGORITHM);
- key = new SecretKeySpec(keyBytes, SECRET_KEY_ALGORITHM);
-
- final int keySize = keyBytes.length * BITS_PER_BYTE;
- identifierKey = String.format(IDENTIFIER_KEY_FORMAT, keySize);
- } catch (final NoSuchAlgorithmException | NoSuchPaddingException e) {
- throw new SensitivePropertyProtectionException(String.format("Cipher [%s] initialization failed", ALGORITHM), e);
- }
- }
-
- @Override
- public boolean isSupported() {
- return true;
- }
-
- /**
- * Returns the key used to identify the provider implementation in {@code nifi.properties}.
- *
- * @return the key to persist in the sibling property
- */
- @Override
- public String getIdentifierKey() {
- return identifierKey;
- }
-
- /**
- * Returns the encrypted cipher text.
- *
- * @param unprotectedValue the sensitive value
- * @param context The property context, unused in this provider
- * @return the value to persist in the {@code nifi.properties} file
- * @throws SensitivePropertyProtectionException if there is an exception encrypting the value
- */
- @Override
- public String protect(final String unprotectedValue, final ProtectedPropertyContext context) throws SensitivePropertyProtectionException {
- Objects.requireNonNull(unprotectedValue, "Value required");
-
- final byte[] iv = generateIV();
- try {
- cipher.init(Cipher.ENCRYPT_MODE, this.key, new GCMParameterSpec(TAG_LENGTH, iv));
-
- byte[] plainBytes = unprotectedValue.getBytes(StandardCharsets.UTF_8);
- byte[] cipherBytes = cipher.doFinal(plainBytes);
- return BASE_64_ENCODER.encodeToString(iv) + DELIMITER + BASE_64_ENCODER.encodeToString(cipherBytes);
- } catch (final BadPaddingException | IllegalBlockSizeException | InvalidAlgorithmParameterException | InvalidKeyException e) {
- throw new SensitivePropertyProtectionException("AES-GCM encryption failed", e);
- }
- }
-
- /**
- * Returns the decrypted plaintext.
- *
- * @param protectedValue the cipher text read from the {@code nifi.properties} file
- * @param context The property context, unused in this provider
- * @return the raw value to be used by the application
- * @throws SensitivePropertyProtectionException if there is an error decrypting the cipher text
- */
- @Override
- public String unprotect(final String protectedValue, final ProtectedPropertyContext context) throws SensitivePropertyProtectionException {
- if (protectedValue == null || protectedValue.trim().length() < MIN_CIPHER_TEXT_LENGTH) {
- throw new IllegalArgumentException("Cannot decrypt a cipher text shorter than " + MIN_CIPHER_TEXT_LENGTH + " chars");
- }
-
- if (!protectedValue.contains(DELIMITER)) {
- throw new IllegalArgumentException("The cipher text does not contain the delimiter " + DELIMITER + " -- it should be of the form Base64(IV) || Base64(cipherText)");
- }
- final String trimmedProtectedValue = protectedValue.trim();
-
- final String armoredIV = trimmedProtectedValue.substring(0, trimmedProtectedValue.indexOf(DELIMITER));
- final byte[] iv = BASE_64_DECODER.decode(armoredIV);
- if (iv.length < IV_LENGTH) {
- throw new IllegalArgumentException(String.format("The IV (%s bytes) must be at least %s bytes", iv.length, IV_LENGTH));
- }
-
- final String encodedCipherBytes = trimmedProtectedValue.substring(trimmedProtectedValue.indexOf(DELIMITER) + 2);
-
- try {
- final byte[] cipherBytes = BASE_64_DECODER.decode(encodedCipherBytes);
-
- cipher.init(Cipher.DECRYPT_MODE, this.key, new GCMParameterSpec(TAG_LENGTH, iv));
- final byte[] plainBytes = cipher.doFinal(cipherBytes);
- return new String(plainBytes, StandardCharsets.UTF_8);
- } catch (final BadPaddingException | IllegalBlockSizeException | InvalidAlgorithmParameterException | InvalidKeyException e) {
- throw new SensitivePropertyProtectionException("AES-GCM decryption failed", e);
- }
- }
-
- /**
- * No cleanup necessary
- */
- @Override
- public void cleanUp() { }
-
- private byte[] generateIV() {
- final byte[] iv = new byte[IV_LENGTH];
- secureRandom.nextBytes(iv);
- return iv;
- }
-
- private byte[] validateKey(String keyHex) {
- if (keyHex == null || keyHex.isEmpty()) {
- throw new SensitivePropertyProtectionException("AES Key not provided");
- }
- keyHex = formatHexKey(keyHex);
- if (!isHexKeyValid(keyHex)) {
- throw new SensitivePropertyProtectionException("AES Key not hexadecimal");
- }
- final byte[] key;
- try {
- key = Hex.decodeHex(keyHex);
- } catch (final DecoderException e) {
- throw new SensitivePropertyProtectionException("AES Key Hexadecimal decoding failed", e);
- }
- final int keyLengthBits = key.length * BITS_PER_BYTE;
- if (!VALID_KEY_LENGTHS.contains(keyLengthBits)) {
- throw new SensitivePropertyProtectionException(String.format("AES Key length not valid [%d]", keyLengthBits));
- }
- return key;
- }
-
- private static String formatHexKey(String input) {
- if (input == null || input.isEmpty()) {
- return "";
- }
- return input.replaceAll("[^0-9a-fA-F]", "").toLowerCase();
- }
-
- private static boolean isHexKeyValid(String key) {
- if (key == null || key.isEmpty()) {
- return false;
- }
- return key.matches("^[0-9a-fA-F]*$");
- }
-}
diff --git a/nifi-commons/nifi-property-protection-cipher/src/test/java/org/apache/nifi/properties/AesGcmSensitivePropertyProviderTest.java b/nifi-commons/nifi-property-protection-cipher/src/test/java/org/apache/nifi/properties/AesGcmSensitivePropertyProviderTest.java
deleted file mode 100644
index 5e01fc2be029..000000000000
--- a/nifi-commons/nifi-property-protection-cipher/src/test/java/org/apache/nifi/properties/AesGcmSensitivePropertyProviderTest.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import org.junit.jupiter.api.Test;
-
-import java.util.Base64;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-public class AesGcmSensitivePropertyProviderTest {
- private static final String HEXADECIMAL_KEY_32 = "12345678";
-
- private static final String HEXADECIMAL_KEY_128 = "12345678123456788765432187654321";
-
- private static final String HEXADECIMAL_KEY_256 = "1234567812345678876543218765432112345678123456788765432187654321";
-
- private static final String AES_GCM_128 = "aes/gcm/128";
-
- private static final String AES_GCM_256 = "aes/gcm/256";
-
- private static final ProtectedPropertyContext PROPERTY_CONTEXT = ProtectedPropertyContext.defaultContext("propertyName");
-
- private static final String PROPERTY_VALUE = "propertyValue";
-
- private static final String DELIMITER = "||";
-
- private static final String DELIMITER_PATTERN = "\\|\\|";
-
- private static final int DELIMITED_ELEMENTS = 2;
-
- private static final int INITIALIZATION_VECTOR_LENGTH = 12;
-
- @Test
- public void testInvalidKeyLength() {
- assertThrows(SensitivePropertyProtectionException.class, () -> new AesGcmSensitivePropertyProvider(HEXADECIMAL_KEY_32));
- }
-
- @Test
- public void testIsSupported() {
- final AesGcmSensitivePropertyProvider provider = new AesGcmSensitivePropertyProvider(HEXADECIMAL_KEY_128);
- assertTrue(provider.isSupported());
- }
-
- @Test
- public void testGetIdentifierKeyAesGcm128() {
- final AesGcmSensitivePropertyProvider provider = new AesGcmSensitivePropertyProvider(HEXADECIMAL_KEY_128);
- final String identifierKey = provider.getIdentifierKey();
- assertEquals(AES_GCM_128, identifierKey);
- }
-
- @Test
- public void testGetIdentifierKeyAesGcm256() {
- final AesGcmSensitivePropertyProvider provider = new AesGcmSensitivePropertyProvider(HEXADECIMAL_KEY_256);
- final String identifierKey = provider.getIdentifierKey();
- assertEquals(AES_GCM_256, identifierKey);
- }
-
- @Test
- public void testProtectUnprotectSuccess() {
- final AesGcmSensitivePropertyProvider provider = new AesGcmSensitivePropertyProvider(HEXADECIMAL_KEY_128);
-
- final String protectedPropertyValue = provider.protect(PROPERTY_VALUE, PROPERTY_CONTEXT);
- final String unprotectedPropertyValue = provider.unprotect(protectedPropertyValue, PROPERTY_CONTEXT);
-
- assertEquals(PROPERTY_VALUE, unprotectedPropertyValue);
- assertTrue(protectedPropertyValue.contains(DELIMITER));
-
- final String[] elements = protectedPropertyValue.split(DELIMITER_PATTERN);
- assertEquals(DELIMITED_ELEMENTS, elements.length);
-
- final String initializationVectorEncoded = elements[0];
- final byte[] initializationVector = Base64.getDecoder().decode(initializationVectorEncoded);
- assertEquals(INITIALIZATION_VECTOR_LENGTH, initializationVector.length);
- }
-
- @Test
- public void testProtectUnprotectDifferentKeyFailed() {
- final AesGcmSensitivePropertyProvider provider = new AesGcmSensitivePropertyProvider(HEXADECIMAL_KEY_128);
-
- final String protectedPropertyValue = provider.protect(PROPERTY_VALUE, PROPERTY_CONTEXT);
-
- final AesGcmSensitivePropertyProvider secondProvider = new AesGcmSensitivePropertyProvider(HEXADECIMAL_KEY_256);
- assertThrows(SensitivePropertyProtectionException.class, () -> secondProvider.unprotect(protectedPropertyValue, PROPERTY_CONTEXT));
- }
-
- @Test
- public void testUnprotectMinLengthRequired() {
- final AesGcmSensitivePropertyProvider provider = new AesGcmSensitivePropertyProvider(HEXADECIMAL_KEY_128);
-
- assertThrows(IllegalArgumentException.class, () -> provider.unprotect(HEXADECIMAL_KEY_32, PROPERTY_CONTEXT));
- }
-}
diff --git a/nifi-commons/nifi-property-protection-factory/pom.xml b/nifi-commons/nifi-property-protection-factory/pom.xml
deleted file mode 100644
index 8f8f853ade50..000000000000
--- a/nifi-commons/nifi-property-protection-factory/pom.xml
+++ /dev/null
@@ -1,157 +0,0 @@
-
-
-
- 4.0.0
-
- org.apache.nifi
- nifi-commons
- 2.0.0-SNAPSHOT
-
- nifi-property-protection-factory
-
-
-
- com.azure
- azure-sdk-bom
- 1.2.24
- import
- pom
-
-
- com.google.cloud
- libraries-bom
- ${gcp.sdk.version}
- pom
- import
-
-
-
-
-
- org.slf4j
- slf4j-api
-
-
- org.apache.nifi
- nifi-property-protection-api
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-property-utils
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-property-protection-shared
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-property-protection-aws
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-property-protection-azure
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-property-protection-cipher
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-property-protection-gcp
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-property-protection-hashicorp
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-properties
-
-
- com.azure
- azure-core-http-okhttp
-
-
- com.google.cloud
- google-cloud-kms
-
-
- commons-logging
- commons-logging
-
-
-
-
- com.azure
- azure-security-keyvault-secrets
-
-
- com.azure
- azure-core-http-netty
-
-
- io.netty
- netty-tcnative-boringssl-static
-
-
-
-
- com.azure
- azure-security-keyvault-keys
-
-
- com.azure
- azure-core-http-netty
-
-
- io.netty
- netty-tcnative-boringssl-static
-
-
-
-
- software.amazon.awssdk
- kms
-
-
- software.amazon.awssdk
- secretsmanager
-
-
- software.amazon.awssdk
- netty-nio-client
-
-
- software.amazon.awssdk
- apache-client
-
-
-
-
- commons-io
- commons-io
- test
-
-
-
diff --git a/nifi-commons/nifi-property-protection-factory/src/main/java/org/apache/nifi/properties/StandardSensitivePropertyProviderFactory.java b/nifi-commons/nifi-property-protection-factory/src/main/java/org/apache/nifi/properties/StandardSensitivePropertyProviderFactory.java
deleted file mode 100644
index feedb8e5d99d..000000000000
--- a/nifi-commons/nifi-property-protection-factory/src/main/java/org/apache/nifi/properties/StandardSensitivePropertyProviderFactory.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import com.azure.security.keyvault.keys.cryptography.CryptographyClient;
-import com.azure.security.keyvault.secrets.SecretClient;
-import com.google.cloud.kms.v1.KeyManagementServiceClient;
-
-import org.apache.nifi.properties.BootstrapProperties.BootstrapPropertyKey;
-import org.apache.nifi.properties.configuration.AwsKmsClientProvider;
-import org.apache.nifi.properties.configuration.AwsSecretsManagerClientProvider;
-import org.apache.nifi.properties.configuration.AzureCryptographyClientProvider;
-import org.apache.nifi.properties.configuration.AzureSecretClientProvider;
-import org.apache.nifi.properties.configuration.ClientProvider;
-import org.apache.nifi.properties.configuration.GoogleKeyManagementServiceClientProvider;
-import org.apache.nifi.properties.scheme.ProtectionScheme;
-import org.apache.nifi.util.NiFiBootstrapUtils;
-import org.apache.nifi.util.StringUtils;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import software.amazon.awssdk.services.kms.KmsClient;
-import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Properties;
-import java.util.function.Supplier;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-/**
- * Standard implementation of Sensitive Property Provider Factory with custom initialization for each provider
- */
-public class StandardSensitivePropertyProviderFactory implements SensitivePropertyProviderFactory {
- private static final Logger logger = LoggerFactory.getLogger(StandardSensitivePropertyProviderFactory.class);
-
- private static final List> PROVIDER_CLASSES = Arrays.asList(
- AesGcmSensitivePropertyProvider.class,
- AwsKmsSensitivePropertyProvider.class,
- AwsSecretsManagerSensitivePropertyProvider.class,
- AzureKeyVaultKeySensitivePropertyProvider.class,
- AzureKeyVaultSecretSensitivePropertyProvider.class,
- GcpKmsSensitivePropertyProvider.class,
- HashiCorpVaultKeyValueSensitivePropertyProvider.class,
- HashiCorpVaultTransitSensitivePropertyProvider.class
- );
-
- private Optional keyHex;
- private final Supplier bootstrapPropertiesSupplier;
- private final Map, SensitivePropertyProvider> providers;
- private Map customPropertyContextMap;
-
- /**
- * Factory default constructor to support java.util.ServiceLoader
- */
- public StandardSensitivePropertyProviderFactory() {
- this(null, null);
- }
-
- public void setKeyHex(final String hexadecimalKey) {
- this.keyHex = Optional.ofNullable(hexadecimalKey);
- }
-
- /**
- * Creates a StandardSensitivePropertyProviderFactory using the default bootstrap.conf location and
- * the keyHex extracted from this bootstrap.conf.
- */
- public static SensitivePropertyProviderFactory withDefaults() {
- return withKeyAndBootstrapSupplier(null, null);
- }
-
- /**
- * Creates a StandardSensitivePropertyProviderFactory using only the provided secret key hex. The default
- * bootstrap.conf will be used for any providers that may require it, but the provided keyHex will be used instead
- * of the one from the default bootstrap.conf.
- * @param keyHex The secret key hex for encrypting properties
- * @return A StandardSensitivePropertyProviderFactory
- */
- public static SensitivePropertyProviderFactory withKey(final String keyHex) {
- return new StandardSensitivePropertyProviderFactory(keyHex, null);
- }
-
- /**
- * Creates a new StandardSensitivePropertyProviderFactory using a separate keyHex and provided bootstrap.conf.
- * The provided keyHex will be used instead of the one from the bootstrap.conf.
- * @param keyHex The secret key hex for encrypting properties
- * @param bootstrapPropertiesSupplier A supplier for the BootstrapProperties that represent bootstrap.conf.
- * If the supplier returns null, the default bootstrap.conf will be used instead.
- * @return A StandardSensitivePropertyProviderFactory
- */
- public static SensitivePropertyProviderFactory withKeyAndBootstrapSupplier(final String keyHex,
- final Supplier bootstrapPropertiesSupplier) {
- return new StandardSensitivePropertyProviderFactory(keyHex, bootstrapPropertiesSupplier);
- }
-
- private StandardSensitivePropertyProviderFactory(final String keyHex, final Supplier bootstrapPropertiesSupplier) {
- this.keyHex = Optional.ofNullable(keyHex);
- this.bootstrapPropertiesSupplier = bootstrapPropertiesSupplier == null ? () -> null : bootstrapPropertiesSupplier;
- this.providers = new HashMap<>();
- this.customPropertyContextMap = null;
- }
-
- /**
- * Get Provider where Protection Scheme path starts with a prefix mapped to the Provider Class
- *
- * @param protectionScheme Protection Scheme requested
- * @return Sensitive Property Provider
- * @throws SensitivePropertyProtectionException Thrown when provider path not found for requested scheme
- */
- @Override
- public SensitivePropertyProvider getProvider(final ProtectionScheme protectionScheme) throws SensitivePropertyProtectionException {
- final String path = Objects.requireNonNull(protectionScheme, "Protection Scheme required").getPath();
- final Collection supportedProviders = getSupportedProviders();
- return supportedProviders.stream()
- .filter(provider -> provider.getIdentifierKey().startsWith(path))
- .findFirst()
- .orElseThrow(() -> new SensitivePropertyProtectionException(String.format("Protection Scheme [%s] not found", path)));
- }
-
- /**
- * Get Supported Sensitive Property Providers instantiates providers as needed and checks supported status
- *
- * @return Supported Sensitive Property Providers
- */
- @Override
- public Collection getSupportedProviders() {
- return PROVIDER_CLASSES
- .stream()
- .map(this::getProvider)
- .filter(SensitivePropertyProvider::isSupported)
- .collect(Collectors.toList());
- }
-
- @Override
- public ProtectedPropertyContext getPropertyContext(final String groupIdentifier, final String propertyName) {
- if (customPropertyContextMap == null) {
- populateCustomPropertyContextMap();
- }
- final String contextName = customPropertyContextMap.entrySet().stream()
- .filter(entry -> entry.getValue().matcher(groupIdentifier).find())
- .map(Map.Entry::getKey)
- .findFirst()
- .orElse(null);
- return ProtectedPropertyContext.contextFor(propertyName, contextName);
- }
-
- private void populateCustomPropertyContextMap() {
- final BootstrapProperties bootstrapProperties = getBootstrapProperties();
- customPropertyContextMap = new HashMap<>();
- final String contextMappingKeyPrefix = BootstrapPropertyKey.CONTEXT_MAPPING_PREFIX.getKey();
- bootstrapProperties.getPropertyKeys().stream()
- .filter(k -> k.contains(contextMappingKeyPrefix))
- .forEach(k -> customPropertyContextMap.put(StringUtils.substringAfter(k, contextMappingKeyPrefix), Pattern.compile(bootstrapProperties.getProperty(k))));
- }
-
- private String getKeyHex() {
- return keyHex.orElseGet(() -> getBootstrapProperties().getProperty(BootstrapPropertyKey.SENSITIVE_KEY)
- .orElseThrow(() -> new SensitivePropertyProtectionException("Could not read root key from bootstrap.conf")));
- }
-
- private BootstrapProperties getBootstrapProperties() {
- return Optional.ofNullable(bootstrapPropertiesSupplier.get()).orElseGet(() -> {
- try {
- return NiFiBootstrapUtils.loadBootstrapProperties();
- } catch (final IOException e) {
- logger.debug("Bootstrap Properties loading failed", e);
- return BootstrapProperties.EMPTY;
- }
- });
- }
-
- private Properties getClientProperties(final ClientProvider clientProvider) {
- final Optional clientProperties = clientProvider.getClientProperties(getBootstrapProperties());
- return clientProperties.orElse(null);
- }
-
- private SensitivePropertyProvider getProvider(final Class extends SensitivePropertyProvider> providerClass) throws SensitivePropertyProtectionException {
- SensitivePropertyProvider provider = providers.get(providerClass);
- if (provider == null) {
- if (AesGcmSensitivePropertyProvider.class.equals(providerClass)) {
- final String hexadecimalKey = getKeyHex();
- provider = new AesGcmSensitivePropertyProvider(hexadecimalKey);
- } else if (AwsKmsSensitivePropertyProvider.class.equals(providerClass)) {
- final AwsKmsClientProvider clientProvider = new AwsKmsClientProvider();
- final Properties clientProperties = getClientProperties(clientProvider);
- final Optional kmsClient = clientProvider.getClient(clientProperties);
- provider = new AwsKmsSensitivePropertyProvider(kmsClient.orElse(null), clientProperties);
- } else if (AwsSecretsManagerSensitivePropertyProvider.class.equals(providerClass)) {
- final AwsSecretsManagerClientProvider clientProvider = new AwsSecretsManagerClientProvider();
- final Properties clientProperties = getClientProperties(clientProvider);
- final Optional secretsManagerClient = clientProvider.getClient(clientProperties);
- provider = new AwsSecretsManagerSensitivePropertyProvider(secretsManagerClient.orElse(null));
- } else if (AzureKeyVaultKeySensitivePropertyProvider.class.equals(providerClass)) {
- final AzureCryptographyClientProvider clientProvider = new AzureCryptographyClientProvider();
- final Properties clientProperties = getClientProperties(clientProvider);
- final Optional cryptographyClient = clientProvider.getClient(clientProperties);
- provider = new AzureKeyVaultKeySensitivePropertyProvider(cryptographyClient.orElse(null), clientProperties);
- } else if (AzureKeyVaultSecretSensitivePropertyProvider.class.equals(providerClass)) {
- final AzureSecretClientProvider clientProvider = new AzureSecretClientProvider();
- final Properties clientProperties = getClientProperties(clientProvider);
- final Optional secretClient = clientProvider.getClient(clientProperties);
- provider = new AzureKeyVaultSecretSensitivePropertyProvider(secretClient.orElse(null));
- } else if (GcpKmsSensitivePropertyProvider.class.equals(providerClass)) {
- final GoogleKeyManagementServiceClientProvider clientProvider = new GoogleKeyManagementServiceClientProvider();
- final Properties clientProperties = getClientProperties(clientProvider);
- final Optional keyManagementServiceClient = clientProvider.getClient(clientProperties);
- provider = new GcpKmsSensitivePropertyProvider(keyManagementServiceClient.orElse(null), clientProperties);
- } else if (HashiCorpVaultKeyValueSensitivePropertyProvider.class.equals(providerClass)) {
- provider = new HashiCorpVaultKeyValueSensitivePropertyProvider(getBootstrapProperties());
- } else if (HashiCorpVaultTransitSensitivePropertyProvider.class.equals(providerClass)) {
- provider = new HashiCorpVaultTransitSensitivePropertyProvider(getBootstrapProperties());
- }
- }
-
- if (provider == null) {
- throw new UnsupportedOperationException(String.format("Provider class not supported [%s]", providerClass));
- }
-
- providers.put(providerClass, provider);
- return provider;
- }
-}
diff --git a/nifi-commons/nifi-property-protection-factory/src/main/java/org/apache/nifi/properties/scheme/PropertyProtectionScheme.java b/nifi-commons/nifi-property-protection-factory/src/main/java/org/apache/nifi/properties/scheme/PropertyProtectionScheme.java
deleted file mode 100644
index 51764e1ac596..000000000000
--- a/nifi-commons/nifi-property-protection-factory/src/main/java/org/apache/nifi/properties/scheme/PropertyProtectionScheme.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.nifi.properties.scheme;
-
-/**
- * Property Protection Schemes supported as arguments for encryption commands should not have direct references
- */
-enum PropertyProtectionScheme implements ProtectionScheme {
- AES_GCM("aes/gcm"),
-
- AWS_SECRETSMANAGER("aws/secretsmanager"),
-
- AWS_KMS("aws/kms"),
-
- AZURE_KEYVAULT_KEY("azure/keyvault/key"),
-
- AZURE_KEYVAULT_SECRET("azure/keyvault/secret"),
-
- GCP_KMS("gcp/kms"),
-
- HASHICORP_VAULT_KV("hashicorp/vault/kv"),
-
- HASHICORP_VAULT_TRANSIT("hashicorp/vault/transit");
-
- PropertyProtectionScheme(final String path) {
- this.path = path;
- }
-
- private final String path;
-
- @Override
- public String getPath() {
- return path;
- }
-}
diff --git a/nifi-commons/nifi-property-protection-factory/src/main/java/org/apache/nifi/properties/scheme/StandardProtectionSchemeResolver.java b/nifi-commons/nifi-property-protection-factory/src/main/java/org/apache/nifi/properties/scheme/StandardProtectionSchemeResolver.java
deleted file mode 100644
index 44557963e435..000000000000
--- a/nifi-commons/nifi-property-protection-factory/src/main/java/org/apache/nifi/properties/scheme/StandardProtectionSchemeResolver.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.nifi.properties.scheme;
-
-import org.apache.nifi.properties.SensitivePropertyProtectionException;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-/**
- * Standard implementation of Protection Scheme Resolver using Property Protection Scheme enumeration
- */
-public class StandardProtectionSchemeResolver implements ProtectionSchemeResolver {
- /**
- * Get Protection Scheme based on scheme matching one the supported Protection Property Scheme enumerated values
- *
- * @param scheme Scheme name required
- * @return Protection Scheme
- */
- @Override
- public ProtectionScheme getProtectionScheme(final String scheme) {
- Objects.requireNonNull(scheme, "Scheme required");
- return Arrays.stream(PropertyProtectionScheme.values())
- .filter(propertyProtectionScheme ->
- propertyProtectionScheme.name().equals(scheme) || scheme.startsWith(propertyProtectionScheme.getPath())
- )
- .findFirst()
- .orElseThrow(() -> new SensitivePropertyProtectionException(String.format("Protection Scheme [%s] not supported", scheme)));
- }
-
- public List getSupportedProtectionSchemes() {
- return Arrays.stream(PropertyProtectionScheme.values())
- .map(PropertyProtectionScheme::name)
- .collect(Collectors.toList());
- }
-}
diff --git a/nifi-commons/nifi-property-protection-factory/src/main/resources/META-INF/services/org.apache.nifi.properties.SensitivePropertyProviderFactory b/nifi-commons/nifi-property-protection-factory/src/main/resources/META-INF/services/org.apache.nifi.properties.SensitivePropertyProviderFactory
deleted file mode 100644
index f318d70c1596..000000000000
--- a/nifi-commons/nifi-property-protection-factory/src/main/resources/META-INF/services/org.apache.nifi.properties.SensitivePropertyProviderFactory
+++ /dev/null
@@ -1,15 +0,0 @@
-# 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.
-org.apache.nifi.properties.StandardSensitivePropertyProviderFactory
diff --git a/nifi-commons/nifi-property-protection-factory/src/main/resources/META-INF/services/org.apache.nifi.properties.scheme.ProtectionSchemeResolver b/nifi-commons/nifi-property-protection-factory/src/main/resources/META-INF/services/org.apache.nifi.properties.scheme.ProtectionSchemeResolver
deleted file mode 100644
index 28d1fcc31c1c..000000000000
--- a/nifi-commons/nifi-property-protection-factory/src/main/resources/META-INF/services/org.apache.nifi.properties.scheme.ProtectionSchemeResolver
+++ /dev/null
@@ -1,15 +0,0 @@
-# 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.
-org.apache.nifi.properties.scheme.StandardProtectionSchemeResolver
diff --git a/nifi-commons/nifi-property-protection-factory/src/test/java/org/apache/nifi/properties/StandardSensitivePropertyProviderFactoryTest.java b/nifi-commons/nifi-property-protection-factory/src/test/java/org/apache/nifi/properties/StandardSensitivePropertyProviderFactoryTest.java
deleted file mode 100644
index a17cd432bd06..000000000000
--- a/nifi-commons/nifi-property-protection-factory/src/test/java/org/apache/nifi/properties/StandardSensitivePropertyProviderFactoryTest.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import org.apache.commons.io.FilenameUtils;
-import org.apache.nifi.properties.scheme.ProtectionScheme;
-import org.apache.nifi.properties.scheme.StandardProtectionScheme;
-import org.apache.nifi.util.NiFiProperties;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardCopyOption;
-import java.util.Collection;
-import java.util.Properties;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-public class StandardSensitivePropertyProviderFactoryTest {
-
- private SensitivePropertyProviderFactory factory;
-
- private static final String BOOTSTRAP_KEY_HEX = "0123456789ABCDEFFEDCBA9876543210";
-
- private static final ProtectionScheme AES_GCM = new StandardProtectionScheme("aes/gcm");
- private static final ProtectionScheme AES_GCM_128 = new StandardProtectionScheme("aes/gcm/128");
- private static final ProtectionScheme HASHICORP_VAULT_TRANSIT = new StandardProtectionScheme("hashicorp/vault/transit/testing");
- private static final ProtectionScheme HASHICORP_VAULT_KV = new StandardProtectionScheme("hashicorp/vault/kv/testing");
-
- private static Path tempConfDir;
- private static Path bootstrapConf;
- private static Path hashicorpVaultBootstrapConf;
- private static Path nifiProperties;
- private static Path azureKeyVaultConf;
- private static String defaultBootstrapContents;
-
- @BeforeAll
- public static void initOnce() throws IOException {
- tempConfDir = Files.createTempDirectory("conf");
- bootstrapConf = Files.createTempFile("bootstrap", ".conf").toAbsolutePath();
- azureKeyVaultConf = Files.createTempFile("bootstrap-azure-keyvault", ".conf").toAbsolutePath();
- hashicorpVaultBootstrapConf = Files.createTempFile("bootstrap-hashicorp-vault", ".conf").toAbsolutePath();
-
- nifiProperties = Files.createTempFile("nifi", ".properties").toAbsolutePath();
-
- nifiProperties = Files.move(nifiProperties, tempConfDir.resolve("nifi.properties"));
-
- defaultBootstrapContents = String.format("%s=%s\n%s=%s\n%s=%s",
- "nifi.bootstrap.sensitive.key", BOOTSTRAP_KEY_HEX,
- "nifi.bootstrap.protection.azure.keyvault.conf", FilenameUtils.separatorsToUnix(azureKeyVaultConf.toString()),
- "nifi.bootstrap.protection.hashicorp.vault.conf", FilenameUtils.separatorsToUnix(hashicorpVaultBootstrapConf.toString()));
- bootstrapConf = writeDefaultBootstrapConf();
- System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, FilenameUtils.separatorsToUnix(nifiProperties.toString()));
- }
-
- @AfterAll
- public static void tearDownOnce() throws IOException {
- Files.deleteIfExists(bootstrapConf);
- Files.deleteIfExists(azureKeyVaultConf);
- Files.deleteIfExists(hashicorpVaultBootstrapConf);
- Files.deleteIfExists(nifiProperties);
- Files.deleteIfExists(tempConfDir);
- System.clearProperty(NiFiProperties.PROPERTIES_FILE_PATH);
- }
-
- @BeforeEach
- public void setFactory() {
- factory = StandardSensitivePropertyProviderFactory.withDefaults();
- }
-
- @Test
- public void testGetPropertyContextNotConfigured() {
- assertEquals("default/prop", factory.getPropertyContext("ldap-provider", "prop").getContextKey());
- }
-
- @Test
- public void testGetPropertyContext() throws IOException {
- writeBootstrapConf(defaultBootstrapContents + "\n" +
- "nifi.bootstrap.protection.context.mapping.ldap=ldap-.*");
- try {
- assertEquals("ldap/prop", factory.getPropertyContext("ldap-provider", "prop").getContextKey());
- assertEquals("ldap/prop", factory.getPropertyContext("ldap-user-group-provider", "prop").getContextKey());
- } finally {
- writeDefaultBootstrapConf();
- }
- }
-
- @Test
- public void testGetSupportedProviders() {
- final Collection providers = factory.getSupportedProviders();
- assertFalse(providers.isEmpty());
-
- final boolean aesProviderFound = providers.stream()
- .anyMatch(provider -> provider instanceof AesGcmSensitivePropertyProvider);
- assertTrue(aesProviderFound);
- }
-
- @Test
- public void testAzureKeyVaultSecret() throws IOException {
- final Properties properties = new Properties();
- properties.put("azure.keyvault.uri", "https://testing.vault.azure.net");
- configureAzureKeyVault(properties);
-
- final SensitivePropertyProvider provider = factory.getProvider(new StandardProtectionScheme("azure/keyvault/secret"));
- assertTrue(provider.isSupported());
- assertEquals(AzureKeyVaultSecretSensitivePropertyProvider.class, provider.getClass());
- }
-
- @Test
- public void testHashiCorpVaultKeyVaultSupported() throws IOException {
- final Properties properties = new Properties();
- properties.put("vault.kv.path", "testing");
- properties.put("vault.uri", "http://localhost:8200");
- properties.put("vault.token", "test-token");
- configureHashicorpVault(properties);
-
- final SensitivePropertyProvider provider = factory.getProvider(HASHICORP_VAULT_KV);
- assertTrue(provider.isSupported());
- assertEquals(HashiCorpVaultKeyValueSensitivePropertyProvider.class, provider.getClass());
- }
-
- @Test
- public void testHashiCorpVaultTransitSupported() throws IOException {
- final Properties properties = new Properties();
- properties.put("vault.transit.path", "testing");
- properties.put("vault.uri", "http://localhost:8200");
- properties.put("vault.token", "test-token");
- configureHashicorpVault(properties);
-
- final SensitivePropertyProvider provider = factory.getProvider(HASHICORP_VAULT_TRANSIT);
- assertTrue(provider.isSupported());
- assertEquals(HashiCorpVaultTransitSensitivePropertyProvider.class, provider.getClass());
- }
-
- @Test
- public void testHashiCorpVaultTransitExceptionWhenMissingProperties() throws IOException {
- final Properties properties = new Properties();
- properties.put("vault.uri", "http://localhost:8200");
- configureHashicorpVault(properties);
-
- assertThrows(SensitivePropertyProtectionException.class, () -> factory.getProvider(HASHICORP_VAULT_TRANSIT));
- }
-
- @Test
- public void testAesGcmWithoutKeySizeSupported() {
- final SensitivePropertyProvider provider = factory.getProvider(AES_GCM);
- assertEquals(AesGcmSensitivePropertyProvider.class, provider.getClass());
- assertTrue(provider.isSupported());
- }
-
- @Test
- public void testAesGcm128Supported() {
- final SensitivePropertyProvider provider = factory.getProvider(AES_GCM_128);
- assertEquals(AesGcmSensitivePropertyProvider.class, provider.getClass());
- assertTrue(provider.isSupported());
- }
-
-
- private static Path writeDefaultBootstrapConf() throws IOException {
- return writeBootstrapConf(defaultBootstrapContents);
- }
-
- private static Path writeBootstrapConf(final String contents) throws IOException {
- final Path tempBootstrapConf = Files.createTempFile("bootstrap", ".conf").toAbsolutePath();
- final Path bootstrapConf = Files.move(tempBootstrapConf, tempConfDir.resolve("bootstrap.conf"), StandardCopyOption.REPLACE_EXISTING);
-
- Files.write(bootstrapConf, contents.getBytes(StandardCharsets.UTF_8));
- return bootstrapConf;
- }
-
- private void configureHashicorpVault(final Properties properties) throws IOException {
- try (OutputStream out = new FileOutputStream(hashicorpVaultBootstrapConf.toFile())) {
- properties.store(out, hashicorpVaultBootstrapConf.toString());
- }
- }
-
- private void configureAzureKeyVault(final Properties properties) throws IOException {
- try (OutputStream out = new FileOutputStream(azureKeyVaultConf.toFile())) {
- properties.store(out, azureKeyVaultConf.toString());
- }
- }
-}
diff --git a/nifi-commons/nifi-property-protection-factory/src/test/java/org/apache/nifi/properties/scheme/StandardProtectionSchemeResolverTest.java b/nifi-commons/nifi-property-protection-factory/src/test/java/org/apache/nifi/properties/scheme/StandardProtectionSchemeResolverTest.java
deleted file mode 100644
index c8893b2231ee..000000000000
--- a/nifi-commons/nifi-property-protection-factory/src/test/java/org/apache/nifi/properties/scheme/StandardProtectionSchemeResolverTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.nifi.properties.scheme;
-
-import org.apache.nifi.properties.SensitivePropertyProtectionException;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-public class StandardProtectionSchemeResolverTest {
- private static final String AES_GCM = "AES_GCM";
-
- private static final String AES_GCM_PATH = "aes/gcm";
-
- private static final String AES_GCM_256_PATH = "aes/gcm/256";
-
- private static final String UNKNOWN = "UNKNOWN";
-
- private StandardProtectionSchemeResolver resolver;
-
- @BeforeEach
- public void setResolver() {
- resolver = new StandardProtectionSchemeResolver();
- }
-
- @Test
- public void getProtectionSchemeAesGcmFound() {
- final ProtectionScheme protectionScheme = resolver.getProtectionScheme(AES_GCM);
- assertNotNull(protectionScheme);
- assertEquals(AES_GCM_PATH, protectionScheme.getPath());
- }
-
- @Test
- public void getProtectionSchemeAesGcm256Found() {
- final ProtectionScheme protectionScheme = resolver.getProtectionScheme(AES_GCM_256_PATH);
- assertNotNull(protectionScheme);
- assertEquals(AES_GCM_PATH, protectionScheme.getPath());
- }
-
- @Test
- public void getProtectionSchemeUnknownNotFound() {
- final SensitivePropertyProtectionException exception = assertThrows(SensitivePropertyProtectionException.class, () -> resolver.getProtectionScheme(UNKNOWN));
- assertTrue(exception.getMessage().contains(UNKNOWN));
- }
-}
diff --git a/nifi-commons/nifi-property-protection-gcp/pom.xml b/nifi-commons/nifi-property-protection-gcp/pom.xml
deleted file mode 100644
index fd9d73190345..000000000000
--- a/nifi-commons/nifi-property-protection-gcp/pom.xml
+++ /dev/null
@@ -1,92 +0,0 @@
-
-
-
- 4.0.0
-
- org.apache.nifi
- nifi-commons
- 2.0.0-SNAPSHOT
-
- nifi-property-protection-gcp
-
-
-
- com.google.cloud
- libraries-bom
- ${gcp.sdk.version}
- pom
- import
-
-
-
-
-
- org.slf4j
- slf4j-api
-
-
- org.apache.nifi
- nifi-property-protection-api
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-property-utils
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-property-protection-shared
- 2.0.0-SNAPSHOT
-
-
- org.apache.commons
- commons-lang3
-
-
- com.google.api
- api-common
-
-
- com.google.api
- gax
-
-
- com.google.protobuf
- protobuf-java
-
-
- com.google.api.grpc
- proto-google-cloud-kms-v1
-
-
-
- com.google.guava
- guava
- ${guava.version}
-
-
- com.google.cloud
- google-cloud-kms
-
-
- commons-logging
- commons-logging
-
-
-
-
-
diff --git a/nifi-commons/nifi-property-protection-gcp/src/main/java/org/apache/nifi/properties/GcpKmsSensitivePropertyProvider.java b/nifi-commons/nifi-property-protection-gcp/src/main/java/org/apache/nifi/properties/GcpKmsSensitivePropertyProvider.java
deleted file mode 100644
index af76dc848135..000000000000
--- a/nifi-commons/nifi-property-protection-gcp/src/main/java/org/apache/nifi/properties/GcpKmsSensitivePropertyProvider.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import com.google.api.gax.rpc.ApiException;
-import com.google.cloud.kms.v1.CryptoKey;
-import com.google.cloud.kms.v1.CryptoKeyName;
-import com.google.cloud.kms.v1.CryptoKeyVersion;
-import com.google.cloud.kms.v1.DecryptResponse;
-import com.google.cloud.kms.v1.EncryptResponse;
-import com.google.cloud.kms.v1.KeyManagementServiceClient;
-import com.google.protobuf.ByteString;
-import org.apache.commons.lang3.StringUtils;
-
-import java.util.Properties;
-
-/**
- * Google Cloud Platform Key Management Service Sensitive Property Provider
- */
-public class GcpKmsSensitivePropertyProvider extends ClientBasedEncodedSensitivePropertyProvider {
- protected static final String PROJECT_PROPERTY = "gcp.kms.project";
- protected static final String LOCATION_PROPERTY = "gcp.kms.location";
- protected static final String KEYRING_PROPERTY = "gcp.kms.keyring";
- protected static final String KEY_PROPERTY = "gcp.kms.key";
-
- private static final String SCHEME_BASE_PATH = "gcp/kms";
-
- private CryptoKeyName cryptoKeyName;
-
- GcpKmsSensitivePropertyProvider(final KeyManagementServiceClient keyManagementServiceClient, final Properties properties) {
- super(keyManagementServiceClient, properties);
- }
-
- @Override
- public String getIdentifierKey() {
- return SCHEME_BASE_PATH;
- }
-
- /**
- * Close Client when configured
- */
- @Override
- public void cleanUp() {
- final KeyManagementServiceClient keyManagementServiceClient = getClient();
- if (keyManagementServiceClient == null) {
- logger.debug("GCP KMS Client not configured");
- } else {
- keyManagementServiceClient.close();
- }
- }
-
- /**
- * Validate Client and Key Operations with Encryption Algorithm when configured
- *
- * @param keyManagementServiceClient Key Management Service Client
- */
- @Override
- protected void validate(final KeyManagementServiceClient keyManagementServiceClient) {
- if (keyManagementServiceClient == null) {
- logger.debug("GCP KMS Client not configured");
- } else {
- final String project = getProperties().getProperty(PROJECT_PROPERTY);
- final String location = getProperties().getProperty(LOCATION_PROPERTY);
- final String keyring = getProperties().getProperty(KEYRING_PROPERTY);
- final String key = getProperties().getProperty(KEY_PROPERTY);
- if (StringUtils.isNoneBlank(project, location, keyring, key)) {
- cryptoKeyName = CryptoKeyName.of(project, location, keyring, key);
- try {
- final CryptoKey cryptoKey = keyManagementServiceClient.getCryptoKey(cryptoKeyName);
- final CryptoKeyVersion cryptoKeyVersion = cryptoKey.getPrimary();
- if (CryptoKeyVersion.CryptoKeyVersionState.ENABLED == cryptoKeyVersion.getState()) {
- logger.info("GCP KMS Crypto Key [{}] Validated", cryptoKeyName);
- } else {
- throw new SensitivePropertyProtectionException(String.format("GCP KMS Crypto Key [%s] Disabled", cryptoKeyName));
- }
- } catch (final ApiException e) {
- throw new SensitivePropertyProtectionException(String.format("GCP KMS Crypto Key [%s] Validation Failed", cryptoKeyName), e);
- }
- } else {
- throw new SensitivePropertyProtectionException("GCP KMS Missing Required Properties");
- }
- }
- }
-
- /**
- * Get encrypted bytes
- *
- * @param bytes Unprotected bytes
- * @return Encrypted bytes
- */
- @Override
- protected byte[] getEncrypted(final byte[] bytes) {
- final EncryptResponse encryptResponse = getClient().encrypt(cryptoKeyName, ByteString.copyFrom(bytes));
- return encryptResponse.getCiphertext().toByteArray();
- }
-
- /**
- * Get decrypted bytes
- *
- * @param bytes Encrypted bytes
- * @return Decrypted bytes
- */
- @Override
- protected byte[] getDecrypted(final byte[] bytes) {
- final DecryptResponse decryptResponse = getClient().decrypt(cryptoKeyName, ByteString.copyFrom(bytes));
- return decryptResponse.getPlaintext().toByteArray();
- }
-}
diff --git a/nifi-commons/nifi-property-protection-gcp/src/main/java/org/apache/nifi/properties/configuration/GoogleKeyManagementServiceClientProvider.java b/nifi-commons/nifi-property-protection-gcp/src/main/java/org/apache/nifi/properties/configuration/GoogleKeyManagementServiceClientProvider.java
deleted file mode 100644
index 2bb707d09d12..000000000000
--- a/nifi-commons/nifi-property-protection-gcp/src/main/java/org/apache/nifi/properties/configuration/GoogleKeyManagementServiceClientProvider.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.nifi.properties.configuration;
-
-import com.google.cloud.kms.v1.KeyManagementServiceClient;
-
-import org.apache.nifi.properties.BootstrapProperties;
-import org.apache.nifi.properties.SensitivePropertyProtectionException;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Properties;
-import java.util.Set;
-
-/**
- * Google Key Management Service Client Provider
- */
-public class GoogleKeyManagementServiceClientProvider extends BootstrapPropertiesClientProvider {
- public GoogleKeyManagementServiceClientProvider() {
- super(BootstrapProperties.BootstrapPropertyKey.GCP_KMS_SENSITIVE_PROPERTY_PROVIDER_CONF);
- }
-
- /**
- * Get Configured Client using default Key Management Service Client settings
- *
- * @param clientProperties Client Properties
- * @return Key Management Service Client
- */
- @Override
- protected KeyManagementServiceClient getConfiguredClient(final Properties clientProperties) {
- try {
- return KeyManagementServiceClient.create();
- } catch (final IOException e) {
- throw new SensitivePropertyProtectionException("Google Key Management Service Create Failed", e);
- }
- }
-
- @Override
- protected Set getRequiredPropertyNames() {
- return Collections.emptySet();
- }
-}
diff --git a/nifi-commons/nifi-property-protection-hashicorp/pom.xml b/nifi-commons/nifi-property-protection-hashicorp/pom.xml
deleted file mode 100644
index d4f2198c6383..000000000000
--- a/nifi-commons/nifi-property-protection-hashicorp/pom.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
- 4.0.0
-
- org.apache.nifi
- nifi-commons
- 2.0.0-SNAPSHOT
-
- nifi-property-protection-hashicorp
-
-
- org.apache.nifi
- nifi-property-protection-api
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-property-utils
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-hashicorp-vault-api
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-hashicorp-vault
- 2.0.0-SNAPSHOT
-
-
- org.springframework
- spring-core
-
-
-
diff --git a/nifi-commons/nifi-property-protection-hashicorp/src/main/java/org/apache/nifi/properties/AbstractHashiCorpVaultSensitivePropertyProvider.java b/nifi-commons/nifi-property-protection-hashicorp/src/main/java/org/apache/nifi/properties/AbstractHashiCorpVaultSensitivePropertyProvider.java
deleted file mode 100644
index 6ccb457ee1a0..000000000000
--- a/nifi-commons/nifi-property-protection-hashicorp/src/main/java/org/apache/nifi/properties/AbstractHashiCorpVaultSensitivePropertyProvider.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import org.apache.nifi.properties.BootstrapProperties.BootstrapPropertyKey;
-import org.apache.nifi.vault.hashicorp.HashiCorpVaultCommunicationService;
-import org.apache.nifi.vault.hashicorp.StandardHashiCorpVaultCommunicationService;
-import org.apache.nifi.vault.hashicorp.config.HashiCorpVaultConfiguration;
-import org.apache.nifi.vault.hashicorp.config.HashiCorpVaultConfiguration.VaultConfigurationKey;
-import org.springframework.core.env.PropertySource;
-
-import java.io.IOException;
-import java.nio.file.Paths;
-
-public abstract class AbstractHashiCorpVaultSensitivePropertyProvider implements SensitivePropertyProvider {
- private static final String VAULT_PREFIX = "vault";
-
- private final String path;
- private final HashiCorpVaultCommunicationService vaultCommunicationService;
- private final BootstrapProperties vaultBootstrapProperties;
-
- AbstractHashiCorpVaultSensitivePropertyProvider(final BootstrapProperties bootstrapProperties) {
- final String vaultBootstrapConfFilename = bootstrapProperties
- .getProperty(BootstrapPropertyKey.HASHICORP_VAULT_SENSITIVE_PROPERTY_PROVIDER_CONF).orElse(null);
- vaultBootstrapProperties = getVaultBootstrapProperties(vaultBootstrapConfFilename);
- path = getSecretsEnginePath(vaultBootstrapProperties);
- if (hasRequiredVaultProperties()) {
- try {
- vaultCommunicationService = new StandardHashiCorpVaultCommunicationService(getVaultPropertySource(vaultBootstrapConfFilename));
- } catch (final IOException e) {
- throw new SensitivePropertyProtectionException("Error configuring HashiCorpVaultCommunicationService", e);
- }
- } else {
- vaultCommunicationService = null;
- }
- }
-
- /**
- * Return the configured Secrets Engine path for this sensitive property provider.
- * @param vaultBootstrapProperties The Properties from the file located at bootstrap.protection.hashicorp.vault.conf
- * @return The Secrets Engine path
- */
- protected abstract String getSecretsEnginePath(final BootstrapProperties vaultBootstrapProperties);
-
- private static BootstrapProperties getVaultBootstrapProperties(final String vaultBootstrapConfFilename) {
- final BootstrapProperties vaultBootstrapProperties;
- if (vaultBootstrapConfFilename != null) {
- try {
- vaultBootstrapProperties = AbstractBootstrapPropertiesLoader.loadBootstrapProperties(
- Paths.get(vaultBootstrapConfFilename), VAULT_PREFIX);
- } catch (final IOException e) {
- throw new SensitivePropertyProtectionException("Could not load " + vaultBootstrapConfFilename, e);
- }
- } else {
- vaultBootstrapProperties = null;
- }
- return vaultBootstrapProperties;
- }
-
- private PropertySource> getVaultPropertySource(final String vaultBootstrapConfFilename) throws IOException {
- return HashiCorpVaultConfiguration.createPropertiesFileSource(vaultBootstrapConfFilename);
- }
-
- /**
- * Returns the Secrets Engine path.
- * @return The Secrets Engine path
- */
- protected String getPath() {
- return path;
- }
-
- protected HashiCorpVaultCommunicationService getVaultCommunicationService() {
- if (vaultCommunicationService == null) {
- throw new SensitivePropertyProtectionException("Vault Protection Scheme missing required properties");
- }
- return vaultCommunicationService;
- }
-
- @Override
- public boolean isSupported() {
- return hasRequiredVaultProperties();
- }
-
- private boolean hasRequiredVaultProperties() {
- return vaultBootstrapProperties != null
- && (vaultBootstrapProperties.getProperty(VaultConfigurationKey.URI.getKey()) != null)
- && hasRequiredSecretsEngineProperties(vaultBootstrapProperties);
- }
-
- /**
- * Return true if the relevant Secrets Engine-specific properties are configured.
- * @param vaultBootstrapProperties The Vault-specific bootstrap properties
- * @return true if the relevant Secrets Engine-specific properties are configured
- */
- protected boolean hasRequiredSecretsEngineProperties(final BootstrapProperties vaultBootstrapProperties) {
- return getSecretsEnginePath(vaultBootstrapProperties) != null;
- }
-
- /**
- * No cleanup necessary
- */
- @Override
- public void cleanUp() { }
-
- protected void requireNotBlank(final String value) {
- if (value == null || value.isEmpty()) {
- throw new IllegalArgumentException("Property value is null or empty");
- }
- }
-}
diff --git a/nifi-commons/nifi-property-protection-hashicorp/src/main/java/org/apache/nifi/properties/HashiCorpVaultKeyValueSensitivePropertyProvider.java b/nifi-commons/nifi-property-protection-hashicorp/src/main/java/org/apache/nifi/properties/HashiCorpVaultKeyValueSensitivePropertyProvider.java
deleted file mode 100644
index f846490e3eaf..000000000000
--- a/nifi-commons/nifi-property-protection-hashicorp/src/main/java/org/apache/nifi/properties/HashiCorpVaultKeyValueSensitivePropertyProvider.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import java.util.Objects;
-
-/**
- * Uses the HashiCorp Vault Key/Value version 1 Secrets Engine to store sensitive values.
- */
-public class HashiCorpVaultKeyValueSensitivePropertyProvider extends AbstractHashiCorpVaultSensitivePropertyProvider {
-
- private static final String KEY_VALUE_PATH = "vault.kv.path";
-
- private static final String IDENTIFIER_KEY_FORMAT = "hashicorp/vault/kv/%s";
-
- HashiCorpVaultKeyValueSensitivePropertyProvider(final BootstrapProperties bootstrapProperties) {
- super(bootstrapProperties);
- }
-
- @Override
- protected String getSecretsEnginePath(final BootstrapProperties vaultBootstrapProperties) {
- if (vaultBootstrapProperties == null) {
- return null;
- }
- return vaultBootstrapProperties.getProperty(KEY_VALUE_PATH);
- }
-
- @Override
- public String getIdentifierKey() {
- return String.format(IDENTIFIER_KEY_FORMAT, getPath());
- }
-
- /**
- * Stores the sensitive value in Vault and returns a description of the secret.
- *
- * @param unprotectedValue the sensitive value
- * @param context The property context, unused in this provider
- * @return the value to persist in the {@code nifi.properties} file
- * @throws SensitivePropertyProtectionException if there is an exception writing the secret
- */
- @Override
- public String protect(final String unprotectedValue, final ProtectedPropertyContext context) throws SensitivePropertyProtectionException {
- requireNotBlank(unprotectedValue);
- Objects.requireNonNull(context, "Context is required to protect a value");
-
- getVaultCommunicationService().writeKeyValueSecret(getPath(), context.getContextKey(), unprotectedValue);
- return String.format("%s/%s", getPath(), context.getContextKey());
- }
-
- /**
- * Returns the secret value, as read from Vault.
- *
- * @param protectedValue The value read from {@code nifi.properties} file. Ignored in this provider.
- * @param context The property context, from which the Vault secret name is pulled
- * @return the raw value to be used by the application
- * @throws SensitivePropertyProtectionException if there is an error retrieving the secret
- */
- @Override
- public String unprotect(final String protectedValue, final ProtectedPropertyContext context) throws SensitivePropertyProtectionException {
- Objects.requireNonNull(context, "Context is required to unprotect a value");
-
- return getVaultCommunicationService().readKeyValueSecret(getPath(), context.getContextKey())
- .orElseThrow(() -> new SensitivePropertyProtectionException(String
- .format("Secret [%s] not found in Vault Key/Value engine at [%s]", context.getContextKey(), getPath())));
- }
-}
diff --git a/nifi-commons/nifi-property-protection-hashicorp/src/main/java/org/apache/nifi/properties/HashiCorpVaultTransitSensitivePropertyProvider.java b/nifi-commons/nifi-property-protection-hashicorp/src/main/java/org/apache/nifi/properties/HashiCorpVaultTransitSensitivePropertyProvider.java
deleted file mode 100644
index 9b8cc4b98fea..000000000000
--- a/nifi-commons/nifi-property-protection-hashicorp/src/main/java/org/apache/nifi/properties/HashiCorpVaultTransitSensitivePropertyProvider.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-
-/**
- * Uses the HashiCorp Vault Transit Secrets Engine to encrypt sensitive values at rest.
- */
-public class HashiCorpVaultTransitSensitivePropertyProvider extends AbstractHashiCorpVaultSensitivePropertyProvider {
- private static final Charset PROPERTY_CHARSET = StandardCharsets.UTF_8;
- private static final String TRANSIT_PATH = "vault.transit.path";
-
- private static final String IDENTIFIER_KEY_FORMAT = "hashicorp/vault/transit/%s";
-
- HashiCorpVaultTransitSensitivePropertyProvider(final BootstrapProperties bootstrapProperties) {
- super(bootstrapProperties);
- }
-
- @Override
- protected String getSecretsEnginePath(final BootstrapProperties vaultBootstrapProperties) {
- if (vaultBootstrapProperties == null) {
- return null;
- }
- return vaultBootstrapProperties.getProperty(TRANSIT_PATH);
- }
-
- @Override
- public String getIdentifierKey() {
- return String.format(IDENTIFIER_KEY_FORMAT, getPath());
- }
-
- /**
- * Returns the encrypted cipher text.
- *
- * @param unprotectedValue the sensitive value
- * @param context The property context, unused in this provider
- * @return the value to persist in the {@code nifi.properties} file
- * @throws SensitivePropertyProtectionException if there is an exception encrypting the value
- */
- @Override
- public String protect(final String unprotectedValue, final ProtectedPropertyContext context) throws SensitivePropertyProtectionException {
- requireNotBlank(unprotectedValue);
- return getVaultCommunicationService().encrypt(getPath(), unprotectedValue.getBytes(PROPERTY_CHARSET));
- }
-
- /**
- * Returns the decrypted plaintext.
- *
- * @param protectedValue the cipher text read from the {@code nifi.properties} file
- * @param context The property context, unused in this provider
- * @return the raw value to be used by the application
- * @throws SensitivePropertyProtectionException if there is an error decrypting the cipher text
- */
- @Override
- public String unprotect(final String protectedValue, final ProtectedPropertyContext context) throws SensitivePropertyProtectionException {
- requireNotBlank(protectedValue);
- return new String(getVaultCommunicationService().decrypt(getPath(), protectedValue), PROPERTY_CHARSET);
- }
-}
diff --git a/nifi-commons/nifi-property-protection-hashicorp/src/test/java/org/apache/nifi/properties/HashiCorpVaultKeyValueSensitivePropertyProviderTest.java b/nifi-commons/nifi-property-protection-hashicorp/src/test/java/org/apache/nifi/properties/HashiCorpVaultKeyValueSensitivePropertyProviderTest.java
deleted file mode 100644
index d421de8d7bc0..000000000000
--- a/nifi-commons/nifi-property-protection-hashicorp/src/test/java/org/apache/nifi/properties/HashiCorpVaultKeyValueSensitivePropertyProviderTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-
-import java.util.Optional;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.mockito.Mockito.when;
-import static org.mockito.ArgumentMatchers.eq;
-
-@ExtendWith(MockitoExtension.class)
-public class HashiCorpVaultKeyValueSensitivePropertyProviderTest {
- private static final String IDENTIFIER_KEY = "hashicorp/vault/kv/null";
-
- @Mock
- private BootstrapProperties bootstrapProperties;
-
- @Test
- public void testGetIdentifierKeyPropertiesNotFound() {
- when(bootstrapProperties.getProperty(eq(BootstrapProperties.BootstrapPropertyKey.HASHICORP_VAULT_SENSITIVE_PROPERTY_PROVIDER_CONF))).thenReturn(Optional.empty());
- final HashiCorpVaultKeyValueSensitivePropertyProvider provider = new HashiCorpVaultKeyValueSensitivePropertyProvider(bootstrapProperties);
-
- final String identifierKey = provider.getIdentifierKey();
-
- assertEquals(IDENTIFIER_KEY, identifierKey);
- }
-
- @Test
- public void testIsSupportedPropertiesNotFound() {
- when(bootstrapProperties.getProperty(eq(BootstrapProperties.BootstrapPropertyKey.HASHICORP_VAULT_SENSITIVE_PROPERTY_PROVIDER_CONF))).thenReturn(Optional.empty());
- final HashiCorpVaultKeyValueSensitivePropertyProvider provider = new HashiCorpVaultKeyValueSensitivePropertyProvider(bootstrapProperties);
-
- assertFalse(provider.isSupported());
- }
-}
diff --git a/nifi-commons/nifi-property-protection-hashicorp/src/test/java/org/apache/nifi/properties/HashiCorpVaultTransitSensitivePropertyProviderTest.java b/nifi-commons/nifi-property-protection-hashicorp/src/test/java/org/apache/nifi/properties/HashiCorpVaultTransitSensitivePropertyProviderTest.java
deleted file mode 100644
index c4460462566a..000000000000
--- a/nifi-commons/nifi-property-protection-hashicorp/src/test/java/org/apache/nifi/properties/HashiCorpVaultTransitSensitivePropertyProviderTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-
-import java.util.Optional;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.when;
-
-@ExtendWith(MockitoExtension.class)
-public class HashiCorpVaultTransitSensitivePropertyProviderTest {
- private static final String IDENTIFIER_KEY = "hashicorp/vault/transit/null";
-
- @Mock
- private BootstrapProperties bootstrapProperties;
-
- @Test
- public void testGetIdentifierKeyPropertiesNotFound() {
- when(bootstrapProperties.getProperty(eq(BootstrapProperties.BootstrapPropertyKey.HASHICORP_VAULT_SENSITIVE_PROPERTY_PROVIDER_CONF))).thenReturn(Optional.empty());
- final HashiCorpVaultTransitSensitivePropertyProvider provider = new HashiCorpVaultTransitSensitivePropertyProvider(bootstrapProperties);
-
- final String identifierKey = provider.getIdentifierKey();
-
- assertEquals(IDENTIFIER_KEY, identifierKey);
- }
-
- @Test
- public void testIsSupportedPropertiesNotFound() {
- when(bootstrapProperties.getProperty(eq(BootstrapProperties.BootstrapPropertyKey.HASHICORP_VAULT_SENSITIVE_PROPERTY_PROVIDER_CONF))).thenReturn(Optional.empty());
- final HashiCorpVaultTransitSensitivePropertyProvider provider = new HashiCorpVaultTransitSensitivePropertyProvider(bootstrapProperties);
-
- assertFalse(provider.isSupported());
- }
-}
diff --git a/nifi-commons/nifi-property-protection-loader/pom.xml b/nifi-commons/nifi-property-protection-loader/pom.xml
deleted file mode 100644
index 8a9659178596..000000000000
--- a/nifi-commons/nifi-property-protection-loader/pom.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
- 4.0.0
-
- org.apache.nifi
- nifi-commons
- 2.0.0-SNAPSHOT
-
- nifi-property-protection-loader
-
-
- org.slf4j
- slf4j-api
-
-
- org.apache.nifi
- nifi-property-utils
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-property-protection-api
- 2.0.0-SNAPSHOT
-
-
-
diff --git a/nifi-commons/nifi-property-protection-loader/src/main/java/org/apache/nifi/properties/ApplicationPropertiesProtector.java b/nifi-commons/nifi-property-protection-loader/src/main/java/org/apache/nifi/properties/ApplicationPropertiesProtector.java
deleted file mode 100644
index d485c2e978ee..000000000000
--- a/nifi-commons/nifi-property-protection-loader/src/main/java/org/apache/nifi/properties/ApplicationPropertiesProtector.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Properties;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import static java.util.Arrays.asList;
-
-/**
- * Class performing unprotection activities before returning a clean
- * implementation of {@link ApplicationProperties}.
- * This encapsulates the sensitive property access logic from external consumers
- * of {@code ApplicationProperties}.
- *
- * @param The type of protected application properties
- * @param The type of standard application properties that backs the protected application properties
- */
-public class ApplicationPropertiesProtector, U extends ApplicationProperties>
- implements SensitivePropertyProtector {
- public static final String PROTECTED_KEY_SUFFIX = ".protected";
-
- private static final Logger logger = LoggerFactory.getLogger(ApplicationPropertiesProtector.class);
-
- private final T protectedProperties;
-
- private final Map localProviderCache = new HashMap<>();
-
- /**
- * Creates an instance containing the provided {@link ProtectedProperties}.
- *
- * @param protectedProperties the ProtectedProperties to contain
- */
- public ApplicationPropertiesProtector(final T protectedProperties) {
- this.protectedProperties = protectedProperties;
- logger.debug("Loaded {} properties (including {} protection schemes) into {}", getPropertyKeysIncludingProtectionSchemes().size(),
- getProtectedPropertyKeys().size(), this.getClass().getName());
- }
-
- /**
- * Returns the sibling property key which specifies the protection scheme for this key.
- *
- * Example:
- *
- * nifi.sensitive.key=ABCXYZ
- * nifi.sensitive.key.protected=aes/gcm/256
- *
- * nifi.sensitive.key -> nifi.sensitive.key.protected
- *
- * @param key the key identifying the sensitive property
- * @return the key identifying the protection scheme for the sensitive property
- */
- public static String getProtectionKey(final String key) {
- if (key == null || key.isEmpty()) {
- throw new IllegalArgumentException("Cannot find protection key for null key");
- }
-
- return key + PROTECTED_KEY_SUFFIX;
- }
-
- /**
- * Retrieves all known property keys.
- *
- * @return all known property keys
- */
- @Override
- public Set getPropertyKeys() {
- Set filteredKeys = getPropertyKeysIncludingProtectionSchemes();
- filteredKeys.removeIf(p -> p.endsWith(PROTECTED_KEY_SUFFIX));
- return filteredKeys;
- }
-
- @Override
- public int size() {
- return getPropertyKeys().size();
- }
-
- @Override
- public Set getPropertyKeysIncludingProtectionSchemes() {
- return protectedProperties.getApplicationProperties().getPropertyKeys();
- }
-
- /**
- * Splits a single string containing multiple property keys into a List. Delimited by ',' or ';' and ignores leading and trailing whitespace around delimiter.
- *
- * @param multipleProperties a single String containing multiple properties, i.e. "nifi.property.1; nifi.property.2, nifi.property.3"
- * @return a List containing the split and trimmed properties
- */
- private static List splitMultipleProperties(final String multipleProperties) {
- if (multipleProperties == null || multipleProperties.trim().isEmpty()) {
- return new ArrayList<>(0);
- } else {
- List properties = new ArrayList<>(asList(multipleProperties.split("\\s*[,;]\\s*")));
- for (int i = 0; i < properties.size(); i++) {
- properties.set(i, properties.get(i).trim());
- }
- return properties;
- }
- }
-
- private String getProperty(final String key) {
- return protectedProperties.getApplicationProperties().getProperty(key);
- }
-
- private String getAdditionalSensitivePropertiesKeys() {
- return getProperty(protectedProperties.getAdditionalSensitivePropertiesKeysName());
- }
-
- private String getAdditionalSensitivePropertiesKeysName() {
- return protectedProperties.getAdditionalSensitivePropertiesKeysName();
- }
-
- @Override
- public List getSensitivePropertyKeys() {
- final String additionalPropertiesString = getAdditionalSensitivePropertiesKeys();
- final String additionalPropertiesKeyName = protectedProperties.getAdditionalSensitivePropertiesKeysName();
- if (additionalPropertiesString == null || additionalPropertiesString.trim().isEmpty()) {
- return protectedProperties.getDefaultSensitiveProperties();
- } else {
- List additionalProperties = splitMultipleProperties(additionalPropertiesString);
- /* Remove this key if it was accidentally provided as a sensitive key
- * because we cannot protect it and read from it
- */
- if (additionalProperties.contains(additionalPropertiesKeyName)) {
- logger.warn("The key '{}' contains itself. This is poor practice and should be removed", additionalPropertiesKeyName);
- additionalProperties.remove(additionalPropertiesKeyName);
- }
- additionalProperties.addAll(protectedProperties.getDefaultSensitiveProperties());
- return additionalProperties;
- }
- }
-
- @Override
- public List getPopulatedSensitivePropertyKeys() {
- List allSensitiveKeys = getSensitivePropertyKeys();
- return allSensitiveKeys.stream().filter(k -> isNotBlank(getProperty(k))).collect(Collectors.toList());
- }
-
- @Override
- public boolean hasProtectedKeys() {
- final List sensitiveKeys = getSensitivePropertyKeys();
- for (String k : sensitiveKeys) {
- if (isPropertyProtected(k)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public Map getProtectedPropertyKeys() {
- final List sensitiveKeys = getSensitivePropertyKeys();
-
- final Map traditionalProtectedProperties = new HashMap<>();
- for (final String key : sensitiveKeys) {
- final String protection = getProperty(getProtectionKey(key));
- if (isNotBlank(protection) && isNotBlank(getProperty(key))) {
- traditionalProtectedProperties.put(key, protection);
- }
- }
-
- return traditionalProtectedProperties;
- }
-
- @Override
- public boolean isPropertySensitive(final String key) {
- // If the explicit check for ADDITIONAL_SENSITIVE_PROPERTIES_KEY is not here, this will loop infinitely
- return key != null && !key.equals(getAdditionalSensitivePropertiesKeysName()) && getSensitivePropertyKeys().contains(key.trim());
- }
-
- /**
- * Returns true if the property identified by this key is considered protected in this instance of {@code NiFiProperties}.
- * The property value is protected if the key is sensitive and the sibling key of key.protected is present.
- *
- * @param key the key
- * @return true if it is currently marked as protected
- * @see ApplicationPropertiesProtector#getSensitivePropertyKeys()
- */
- @Override
- public boolean isPropertyProtected(final String key) {
- return key != null && isPropertySensitive(key) && isNotBlank(getProperty(getProtectionKey(key)));
- }
-
- @Override
- public U getUnprotectedProperties() throws SensitivePropertyProtectionException {
- if (hasProtectedKeys()) {
- logger.debug("Protected Properties [{}] Sensitive Properties [{}]",
- getProtectedPropertyKeys().size(),
- getSensitivePropertyKeys().size());
-
- final Properties rawProperties = new Properties();
-
- final Set failedKeys = new HashSet<>();
-
- for (final String key : getPropertyKeys()) {
- /* Three kinds of keys
- * 1. protection schemes -- skip
- * 2. protected keys -- unprotect and copy
- * 3. normal keys -- copy over
- */
- if (key.endsWith(PROTECTED_KEY_SUFFIX)) {
- // Do nothing
- } else if (isPropertyProtected(key)) {
- try {
- rawProperties.setProperty(key, unprotectValue(key, getProperty(key)));
- } catch (final SensitivePropertyProtectionException e) {
- logger.warn("Failed to unprotect '{}'", key, e);
- failedKeys.add(key);
- }
- } else {
- rawProperties.setProperty(key, getProperty(key));
- }
- }
-
- if (!failedKeys.isEmpty()) {
- final String failed = failedKeys.size() == 1 ? failedKeys.iterator().next() : String.join(", ", failedKeys);
- throw new SensitivePropertyProtectionException(String.format("Failed unprotected properties: %s", failed));
- }
-
- return protectedProperties.createApplicationProperties(rawProperties);
- } else {
- logger.debug("No protected properties");
- return protectedProperties.getApplicationProperties();
- }
- }
-
- @Override
- public void addSensitivePropertyProvider(final SensitivePropertyProvider sensitivePropertyProvider) {
- Objects.requireNonNull(sensitivePropertyProvider, "Provider required");
-
- final String identifierKey = sensitivePropertyProvider.getIdentifierKey();
- if (localProviderCache.containsKey(identifierKey)) {
- throw new UnsupportedOperationException(String.format("Sensitive Property Provider Identifier [%s] override not supported", identifierKey));
- }
-
- localProviderCache.put(identifierKey, sensitivePropertyProvider);
- }
-
- @Override
- public String toString() {
- return String.format("%s Properties [%d]", getClass().getSimpleName(), getPropertyKeys().size());
- }
-
- /**
- * If the value is protected, unprotects it and returns it. If not, returns the original value.
- *
- * @param key the retrieved property key
- * @param retrievedValue the retrieved property value
- * @return the unprotected value
- */
- private String unprotectValue(final String key, final String retrievedValue) {
- // Checks if the key is sensitive and marked as protected
- if (isPropertyProtected(key)) {
- final String protectionSchemePath = getProperty(getProtectionKey(key));
-
- try {
- final SensitivePropertyProvider provider = findProvider(protectionSchemePath);
- return provider.unprotect(retrievedValue, ProtectedPropertyContext.defaultContext(key));
- } catch (final RuntimeException e) {
- throw new SensitivePropertyProtectionException(String.format("Property [%s] unprotect failed", key), e);
- }
- }
- return retrievedValue;
- }
-
- private SensitivePropertyProvider findProvider(final String protectionSchemePath) {
- Objects.requireNonNull(protectionSchemePath, "Protection Scheme Path required");
- return localProviderCache.entrySet()
- .stream()
- .filter(entry -> protectionSchemePath.startsWith(entry.getKey()))
- .findFirst()
- .map(Map.Entry::getValue)
- .orElseThrow(() -> new UnsupportedOperationException(String.format("Protection Scheme Path [%s] Provider not found", protectionSchemePath)));
- }
-
- private boolean isNotBlank(final String string) {
- return string != null && string.length() > 0;
- }
-}
diff --git a/nifi-commons/nifi-property-protection-loader/src/main/java/org/apache/nifi/property/protection/loader/PropertyProtectionURLClassLoader.java b/nifi-commons/nifi-property-protection-loader/src/main/java/org/apache/nifi/property/protection/loader/PropertyProtectionURLClassLoader.java
deleted file mode 100644
index 93a838121296..000000000000
--- a/nifi-commons/nifi-property-protection-loader/src/main/java/org/apache/nifi/property/protection/loader/PropertyProtectionURLClassLoader.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.nifi.property.protection.loader;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.stream.Stream;
-
-/**
- * Property Protection URL Class Loader uses the Current Thread Class Loader as the parent and loads libraries from a standard directory
- */
-public class PropertyProtectionURLClassLoader extends URLClassLoader {
- private static final String STANDARD_DIRECTORY = "lib/properties";
-
- private static final Logger logger = LoggerFactory.getLogger(PropertyProtectionURLClassLoader.class);
-
- public PropertyProtectionURLClassLoader(final ClassLoader parentClassLoader) {
- super(getPropertyProtectionUrls(), parentClassLoader);
- }
-
- private static URL[] getPropertyProtectionUrls() {
- final Path standardDirectory = Paths.get(STANDARD_DIRECTORY);
- if (Files.exists(standardDirectory)) {
- try (final Stream files = Files.list(standardDirectory)) {
- return files.map(Path::toUri)
- .map(uri -> {
- try {
- return uri.toURL();
- } catch (final MalformedURLException e) {
- throw new UncheckedIOException(String.format("Processing Property Protection libraries failed [%s]", standardDirectory), e);
- }
- })
- .toArray(URL[]::new);
- } catch (final IOException e) {
- throw new UncheckedIOException(String.format("Loading Property Protection libraries failed [%s]", standardDirectory), e);
- }
- } else {
- logger.warn("Property Protection libraries directory [{}] not found", standardDirectory);
- return new URL[0];
- }
- }
-}
diff --git a/nifi-commons/nifi-property-protection-loader/src/main/java/org/apache/nifi/property/protection/loader/PropertyProviderFactoryLoader.java b/nifi-commons/nifi-property-protection-loader/src/main/java/org/apache/nifi/property/protection/loader/PropertyProviderFactoryLoader.java
deleted file mode 100644
index 2505d9a98b8f..000000000000
--- a/nifi-commons/nifi-property-protection-loader/src/main/java/org/apache/nifi/property/protection/loader/PropertyProviderFactoryLoader.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.nifi.property.protection.loader;
-
-import org.apache.nifi.properties.SensitivePropertyProtectionException;
-import org.apache.nifi.properties.SensitivePropertyProviderFactory;
-
-import java.util.Iterator;
-import java.util.ServiceLoader;
-
-/**
- * Loader for Sensitive Property Provider Factory
- */
-public class PropertyProviderFactoryLoader {
- /**
- * Get Sensitive Property Provider Factory using ServiceLoader to find available implementations from META-INF directories
- *
- * @return Sensitive Property Provider Factory
- * @throws SensitivePropertyProtectionException Thrown when no implementations found
- */
- public SensitivePropertyProviderFactory getPropertyProviderFactory() {
- final ServiceLoader serviceLoader = ServiceLoader.load(SensitivePropertyProviderFactory.class);
- final Iterator factories = serviceLoader.iterator();
-
- if (factories.hasNext()) {
- return factories.next();
- } else {
- throw new SensitivePropertyProtectionException(String.format("No implementations found [%s]", SensitivePropertyProviderFactory.class.getName()));
- }
- }
-}
diff --git a/nifi-commons/nifi-property-protection-loader/src/main/java/org/apache/nifi/property/protection/loader/ProtectionSchemeResolverLoader.java b/nifi-commons/nifi-property-protection-loader/src/main/java/org/apache/nifi/property/protection/loader/ProtectionSchemeResolverLoader.java
deleted file mode 100644
index 5608299e25ca..000000000000
--- a/nifi-commons/nifi-property-protection-loader/src/main/java/org/apache/nifi/property/protection/loader/ProtectionSchemeResolverLoader.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.nifi.property.protection.loader;
-
-import org.apache.nifi.properties.SensitivePropertyProtectionException;
-import org.apache.nifi.properties.scheme.ProtectionSchemeResolver;
-
-import java.util.Iterator;
-import java.util.ServiceLoader;
-
-/**
- * Loader for Protection Scheme Resolver
- */
-public class ProtectionSchemeResolverLoader {
- /**
- * Get Protection Scheme Resolver using ServiceLoader to find available implementations from META-INF directories
- *
- * @return Protection Scheme Resolver
- * @throws SensitivePropertyProtectionException Thrown when no implementations found
- */
- public ProtectionSchemeResolver getProtectionSchemeResolver() {
- final ServiceLoader serviceLoader = ServiceLoader.load(ProtectionSchemeResolver.class);
- final Iterator factories = serviceLoader.iterator();
-
- if (factories.hasNext()) {
- return factories.next();
- } else {
- throw new SensitivePropertyProtectionException(String.format("No implementations found [%s]", ProtectionSchemeResolver.class.getName()));
- }
- }
-}
diff --git a/nifi-commons/nifi-property-protection-shared/pom.xml b/nifi-commons/nifi-property-protection-shared/pom.xml
deleted file mode 100644
index cb9adbc9501b..000000000000
--- a/nifi-commons/nifi-property-protection-shared/pom.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
- 4.0.0
-
- org.apache.nifi
- nifi-commons
- 2.0.0-SNAPSHOT
-
- nifi-property-protection-shared
-
-
- org.slf4j
- slf4j-api
-
-
- org.apache.nifi
- nifi-property-protection-api
- 2.0.0-SNAPSHOT
-
-
- org.apache.nifi
- nifi-property-utils
- 2.0.0-SNAPSHOT
-
-
-
diff --git a/nifi-commons/nifi-property-protection-shared/src/main/java/org/apache/nifi/properties/ClientBasedEncodedSensitivePropertyProvider.java b/nifi-commons/nifi-property-protection-shared/src/main/java/org/apache/nifi/properties/ClientBasedEncodedSensitivePropertyProvider.java
deleted file mode 100644
index c5753b395e31..000000000000
--- a/nifi-commons/nifi-property-protection-shared/src/main/java/org/apache/nifi/properties/ClientBasedEncodedSensitivePropertyProvider.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Properties;
-
-/**
- * Client-Based extension of Encoded Sensitive Property Provider
- *
- * @param Client Type
- */
-public abstract class ClientBasedEncodedSensitivePropertyProvider extends EncodedSensitivePropertyProvider {
- protected final Logger logger = LoggerFactory.getLogger(getClass());
-
- private final T client;
-
- private final Properties properties;
-
- public ClientBasedEncodedSensitivePropertyProvider(final T client,
- final Properties properties) {
- this.client = client;
- this.properties = properties;
- validate(client);
- }
-
- /**
- * Is Provider supported based on client status
- *
- * @return Provider supported status
- */
- @Override
- public boolean isSupported() {
- return client != null;
- }
-
- /**
- * Clean up resources should be overridden when client requires shutdown
- */
- @Override
- public void cleanUp() {
- logger.debug("Cleanup Started");
- }
-
- /**
- * Get Client Properties
- *
- * @return Client Properties
- */
- protected Properties getProperties() {
- return properties;
- }
-
- /**
- * Get Client
- *
- * @return Client can be null when not configured
- */
- protected T getClient() {
- if (client == null) {
- throw new IllegalStateException("Client not configured");
- }
- return client;
- }
-
- /**
- * Validate Provider and Client configuration
- *
- * @param configuredClient Configured Client
- */
- protected void validate(final T configuredClient) {
- if (configuredClient == null) {
- logger.debug("Client not configured");
- }
- }
-}
diff --git a/nifi-commons/nifi-property-protection-shared/src/main/java/org/apache/nifi/properties/EncodedSensitivePropertyProvider.java b/nifi-commons/nifi-property-protection-shared/src/main/java/org/apache/nifi/properties/EncodedSensitivePropertyProvider.java
deleted file mode 100644
index 1a1a2176f0b3..000000000000
--- a/nifi-commons/nifi-property-protection-shared/src/main/java/org/apache/nifi/properties/EncodedSensitivePropertyProvider.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.nifi.properties;
-
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.Base64;
-import java.util.Objects;
-
-/**
- * Encoded Sensitive Property Provider handles Base64 encoding and decoding of property values
- */
-public abstract class EncodedSensitivePropertyProvider implements SensitivePropertyProvider {
- private static final Charset VALUE_CHARACTER_SET = StandardCharsets.UTF_8;
-
- private static final Base64.Encoder ENCODER = Base64.getEncoder().withoutPadding();
-
- private static final Base64.Decoder DECODER = Base64.getDecoder();
-
- /**
- * Protect property value and return Base64-encoded representation of encrypted bytes
- *
- * @param unprotectedValue Unprotected property value to be encrypted
- * @param context Property Context
- * @return Base64-encoded representation of encrypted bytes
- */
- @Override
- public String protect(final String unprotectedValue, final ProtectedPropertyContext context) {
- Objects.requireNonNull(unprotectedValue, "Value required");
- Objects.requireNonNull(context, "Context required");
- try {
- final byte[] bytes = unprotectedValue.getBytes(VALUE_CHARACTER_SET);
- final byte[] encrypted = getEncrypted(bytes);
- return ENCODER.encodeToString(encrypted);
- } catch (final RuntimeException e) {
- final String message = String.format("Property [%s] Encryption Failed", context.getContextKey());
- throw new SensitivePropertyProtectionException(message, e);
- }
- }
-
- /**
- * Unprotect Base64-encoded representation of encrypted property value and return string
- *
- * @param protectedValue Base64-encoded representation of encrypted bytes
- * @param context Property Context
- * @return Decrypted property value string
- */
- @Override
- public String unprotect(final String protectedValue, final ProtectedPropertyContext context) {
- Objects.requireNonNull(protectedValue, "Value required");
- Objects.requireNonNull(context, "Context required");
- try {
- final byte[] decoded = DECODER.decode(protectedValue);
- final byte[] decrypted = getDecrypted(decoded);
- return new String(decrypted, VALUE_CHARACTER_SET);
- } catch (final RuntimeException e) {
- final String message = String.format("Property [%s] Decryption Failed", context.getContextKey());
- throw new SensitivePropertyProtectionException(message, e);
- }
- }
-
- /**
- * Get encrypted byte array representation of bytes
- *
- * @param bytes Unprotected bytes
- * @return Encrypted bytes
- */
- protected abstract byte[] getEncrypted(byte[] bytes);
-
- /**
- * Get decrypted byte array representation of encrypted bytes
- *
- * @param bytes Encrypted bytes
- * @return Decrypted bytes
- */
- protected abstract byte[] getDecrypted(byte[] bytes);
-}
diff --git a/nifi-commons/nifi-property-protection-shared/src/main/java/org/apache/nifi/properties/configuration/BootstrapPropertiesClientProvider.java b/nifi-commons/nifi-property-protection-shared/src/main/java/org/apache/nifi/properties/configuration/BootstrapPropertiesClientProvider.java
deleted file mode 100644
index ac8c82ad1887..000000000000
--- a/nifi-commons/nifi-property-protection-shared/src/main/java/org/apache/nifi/properties/configuration/BootstrapPropertiesClientProvider.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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.nifi.properties.configuration;
-
-import org.apache.nifi.properties.BootstrapProperties;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UncheckedIOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Properties;
-import java.util.Set;
-
-/**
- * Shared Client Provider for reading Client Properties from file referenced in configured Bootstrap Property Key
- *
- * @param Client Type
- */
-public abstract class BootstrapPropertiesClientProvider implements ClientProvider {
- protected final Logger logger = LoggerFactory.getLogger(getClass());
-
- private final BootstrapProperties.BootstrapPropertyKey bootstrapPropertyKey;
-
- public BootstrapPropertiesClientProvider(final BootstrapProperties.BootstrapPropertyKey bootstrapPropertyKey) {
- this.bootstrapPropertyKey = Objects.requireNonNull(bootstrapPropertyKey, "Bootstrap Property Key required");
- }
-
- /**
- * Get Client using Client Properties
- *
- * @param clientProperties Client Properties can be null
- * @return Configured Client or empty when Client Properties object is null
- */
- @Override
- public Optional getClient(final Properties clientProperties) {
- return isMissingProperties(clientProperties) ? Optional.empty() : Optional.of(getConfiguredClient(clientProperties));
- }
-
- /**
- * Get Client Properties from file referenced in Bootstrap Properties
- *
- * @param bootstrapProperties Bootstrap Properties
- * @return Client Properties or empty when not configured
- */
- @Override
- public Optional getClientProperties(final BootstrapProperties bootstrapProperties) {
- Objects.requireNonNull(bootstrapProperties, "Bootstrap Properties required");
- final String clientBootstrapPropertiesPath = bootstrapProperties.getProperty(bootstrapPropertyKey).orElse(null);
- if (clientBootstrapPropertiesPath == null || clientBootstrapPropertiesPath.isEmpty()) {
- logger.debug("Client Properties [{}] not configured", bootstrapPropertyKey);
- return Optional.empty();
- } else {
- final Path propertiesPath = Paths.get(clientBootstrapPropertiesPath);
- if (Files.exists(propertiesPath)) {
- try {
- final Properties clientProperties = new Properties();
- try (final InputStream inputStream = Files.newInputStream(propertiesPath)) {
- clientProperties.load(inputStream);
- }
- return Optional.of(clientProperties);
- } catch (final IOException e) {
- final String message = String.format("Loading Client Properties Failed [%s]", propertiesPath);
- throw new UncheckedIOException(message, e);
- }
- } else {
- logger.debug("Client Properties [{}] Path [{}] not found", bootstrapPropertyKey, propertiesPath);
- return Optional.empty();
- }
- }
- }
-
- /**
- * Get Configured Client using Client Properties
- *
- * @param clientProperties Client Properties
- * @return Configured Client
- */
- protected abstract T getConfiguredClient(final Properties clientProperties);
-
- /**
- * Get Property Names required for initializing client in order to perform initial validation
- *
- * @return Set of required client property names
- */
- protected abstract Set getRequiredPropertyNames();
-
- private boolean isMissingProperties(final Properties clientProperties) {
- return clientProperties == null || getRequiredPropertyNames().stream().anyMatch(propertyName -> {
- final String property = clientProperties.getProperty(propertyName);
- return property == null || property.isEmpty();
- });
- }
-}
diff --git a/nifi-commons/nifi-property-protection-shared/src/main/java/org/apache/nifi/properties/configuration/ClientProvider.java b/nifi-commons/nifi-property-protection-shared/src/main/java/org/apache/nifi/properties/configuration/ClientProvider.java
deleted file mode 100644
index cee6a9c5448f..000000000000
--- a/nifi-commons/nifi-property-protection-shared/src/main/java/org/apache/nifi/properties/configuration/ClientProvider.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.nifi.properties.configuration;
-
-import org.apache.nifi.properties.BootstrapProperties;
-
-import java.util.Optional;
-import java.util.Properties;
-
-/**
- * Client Provider responsible for reading Client Properties and instantiating client services
- *
- * @param Client Type
- */
-public interface ClientProvider {
- /**
- * Get Client Properties from Bootstrap Properties
- *
- * @param bootstrapProperties Bootstrap Properties
- * @return Client Properties or empty when not configured
- */
- Optional getClientProperties(BootstrapProperties bootstrapProperties);
-
- /**
- * Get Client using Client Properties
- *
- * @param properties Client Properties
- * @return Client or empty when not configured
- */
- Optional getClient(Properties properties);
-}
diff --git a/nifi-commons/nifi-property-utils/src/main/java/org/apache/nifi/properties/AbstractBootstrapPropertiesLoader.java b/nifi-commons/nifi-property-utils/src/main/java/org/apache/nifi/properties/AbstractBootstrapPropertiesLoader.java
index aa699e7bf294..2684870a8630 100644
--- a/nifi-commons/nifi-property-utils/src/main/java/org/apache/nifi/properties/AbstractBootstrapPropertiesLoader.java
+++ b/nifi-commons/nifi-property-utils/src/main/java/org/apache/nifi/properties/AbstractBootstrapPropertiesLoader.java
@@ -16,7 +16,6 @@
*/
package org.apache.nifi.properties;
-import org.apache.nifi.properties.BootstrapProperties.BootstrapPropertyKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -58,17 +57,6 @@ public abstract class AbstractBootstrapPropertiesLoader {
*/
protected abstract String getApplicationPropertiesFilePathSystemProperty();
- /**
- * Returns the key (if any) used to encrypt sensitive properties, extracted from
- * {@code $APPLICATION_HOME/conf/bootstrap.conf}.
- *
- * @return the key in hexadecimal format
- * @throws IOException if the file is not readable
- */
- public String extractKeyFromBootstrapFile() throws IOException {
- return extractKeyFromBootstrapFile(null);
- }
-
/**
* Loads the bootstrap.conf file into a BootstrapProperties object.
* @param bootstrapPath the path to the bootstrap file
@@ -100,24 +88,6 @@ public static BootstrapProperties loadBootstrapProperties(final Path bootstrapPa
}
}
- /**
- * Returns the key (if any) used to encrypt sensitive properties, extracted from
- * {@code $APPLICATION_HOME/conf/bootstrap.conf}.
- *
- * @param bootstrapPath the path to the bootstrap file (if null, returns the sensitive key
- * found in $APPLICATION_HOME/conf/bootstrap.conf)
- * @return the key in hexadecimal format
- * @throws IOException if the file is not readable
- */
- public String extractKeyFromBootstrapFile(final String bootstrapPath) throws IOException {
- final BootstrapProperties bootstrapProperties = loadBootstrapProperties(bootstrapPath);
-
- return bootstrapProperties.getProperty(BootstrapPropertyKey.SENSITIVE_KEY).orElseGet(() -> {
- logger.warn("No encryption key present in the bootstrap.conf file at {}", bootstrapProperties.getConfigFilePath());
- return "";
- });
- }
-
/**
* Returns the file for bootstrap.conf.
*
diff --git a/nifi-commons/nifi-property-utils/src/main/java/org/apache/nifi/properties/BootstrapProperties.java b/nifi-commons/nifi-property-utils/src/main/java/org/apache/nifi/properties/BootstrapProperties.java
index 9b440680d07b..1d97287dbea3 100644
--- a/nifi-commons/nifi-property-utils/src/main/java/org/apache/nifi/properties/BootstrapProperties.java
+++ b/nifi-commons/nifi-property-utils/src/main/java/org/apache/nifi/properties/BootstrapProperties.java
@@ -21,7 +21,6 @@
import java.util.Collections;
import java.util.Enumeration;
import java.util.Objects;
-import java.util.Optional;
import java.util.Properties;
import java.util.Set;
@@ -31,29 +30,6 @@
public class BootstrapProperties extends StandardReadableProperties {
private static final String PROPERTY_KEY_FORMAT = "%s.%s";
- public enum BootstrapPropertyKey {
- SENSITIVE_KEY("bootstrap.sensitive.key"),
- HASHICORP_VAULT_SENSITIVE_PROPERTY_PROVIDER_CONF("bootstrap.protection.hashicorp.vault.conf"),
- AWS_SENSITIVE_PROPERTY_PROVIDER_CONF("bootstrap.protection.aws.conf"),
- AZURE_KEYVAULT_SENSITIVE_PROPERTY_PROVIDER_CONF("bootstrap.protection.azure.keyvault.conf"),
- GCP_KMS_SENSITIVE_PROPERTY_PROVIDER_CONF("bootstrap.protection.gcp.kms.conf"),
- CONTEXT_MAPPING_PREFIX("bootstrap.protection.context.mapping.");
-
- private final String key;
-
- BootstrapPropertyKey(final String key) {
- this.key = key;
- }
-
- /**
- * Returns the property key.
- * @return The property key
- */
- public String getKey() {
- return key;
- }
- }
-
private final String propertyPrefix;
private final Path configFilePath;
@@ -65,7 +41,6 @@ public BootstrapProperties(final String propertyPrefix, final Properties propert
this.configFilePath = configFilePath;
this.filterProperties(properties);
-
}
/**
@@ -119,15 +94,6 @@ private String getPropertyKey(final String subKey) {
return String.format(PROPERTY_KEY_FORMAT, propertyPrefix, subKey);
}
- /**
- * Returns the optional property value with the given BootstrapPropertyKey.
- * @param key A BootstrapPropertyKey, representing properties in bootstrap.conf
- * @return The property value
- */
- public Optional getProperty(final BootstrapPropertyKey key) {
- return Optional.ofNullable(getProperty(getPropertyKey(key.key)));
- }
-
@Override
public String toString() {
return String.format("Bootstrap properties [%s] with prefix [%s]", configFilePath, propertyPrefix);
diff --git a/nifi-commons/pom.xml b/nifi-commons/pom.xml
index a8cfaedf8597..f5d62ce280de 100644
--- a/nifi-commons/pom.xml
+++ b/nifi-commons/pom.xml
@@ -41,15 +41,6 @@
nifi-property-encryptor
nifi-property-utils
nifi-properties
- nifi-property-protection-api
- nifi-property-protection-aws
- nifi-property-protection-azure
- nifi-property-protection-cipher
- nifi-property-protection-factory
- nifi-property-protection-gcp
- nifi-property-protection-hashicorp
- nifi-property-protection-loader
- nifi-property-protection-shared
nifi-record
nifi-record-path
nifi-repository-encryption
diff --git a/nifi-docs/src/main/asciidoc/administration-guide.adoc b/nifi-docs/src/main/asciidoc/administration-guide.adoc
index 9addc6b6c5de..2b9b5b9b4659 100644
--- a/nifi-docs/src/main/asciidoc/administration-guide.adoc
+++ b/nifi-docs/src/main/asciidoc/administration-guide.adoc
@@ -2025,19 +2025,6 @@ empty. NiFi writes the generated value to `nifi.properties` and logs a warning.
Clustered installations of NiFi require the same value to be configured on all nodes.
-[[encrypt-config_tool]]
-== Encrypted Passwords in Configuration Files
-
-In order to facilitate the secure setup of NiFi, you can use the `encrypt-config` command line utility to encrypt raw configuration values that NiFi decrypts in memory on startup. This extensible protection scheme transparently allows NiFi to use raw values in operation, while protecting them at rest.
-
-This is a change in behavior; prior to 1.0, all configuration values were stored in plaintext on the file system. POSIX file permissions were recommended to limit unauthorized access to these files.
-
-If no administrator action is taken, the configuration values remain unencrypted.
-
-For more information, see the <> section in the link:toolkit-guide.html[NiFi Toolkit Guide].
-
-Configuring each Sensitive Property Provider requires including the appropriate file reference property in `bootstrap.conf`. The default `bootstrap.conf` includes commented file reference properties for available providers.
-
[[hashicorp-vault-providers]]
=== HashiCorp Vault providers
Two encryption providers are currently configurable in the `bootstrap-hashicorp-vault.conf` file:
@@ -2240,14 +2227,9 @@ nifi.bootstrap.protection.context.mapping.ldap=ldap-.*
This would cause both of the above to be assigned a context of `"ldap/Manager Password"` instead of `"default/Manager Password"`.
[[admin-toolkit]]
== NiFi Toolkit Administrative Tools
-In addition to `encrypt-config`, the NiFi Toolkit also contains command line utilities for administrators to support NiFi maintenance in standalone and clustered environments. These utilities include:
+The NiFi Toolkit also contains command line utilities for administrators to support NiFi maintenance in standalone and clustered environments.
* CLI -- The `cli` tool enables administrators to interact with NiFi and NiFi Registry instances to automate tasks such as deploying versioned flows and managing process groups and cluster nodes.
-* File Manager -- The `file-manager` tool enables administrators to backup, install or restore a NiFi installation from backup.
-* Flow Analyzer -- The `flow-analyzer` tool produces a report that helps administrators understand the max amount of data which can be stored in backpressure for a given flow.
-* Node Manager -- The `node-manager` tool enables administrators to perform status checks on nodes as well as the ability to connect, disconnect, or remove nodes from the cluster.
-* Notify -- The `notify` tool enables administrators to send bulletins to the NiFi UI.
-* S2S -- The `s2s` tool enables administrators to send data into or out of NiFi flows over site-to-site.
For more information about each utility, see the link:toolkit-guide.html[NiFi Toolkit Guide].
@@ -3027,9 +3009,6 @@ if the service is still running, the Bootstrap will `kill` the process, or termi
|`java.arg.N`|Any number of JVM arguments can be passed to the NiFi JVM when the process is started. These arguments are defined by adding properties to _bootstrap.conf_ that
begin with `java.arg.`. The rest of the property name is not relevant, other than to differentiate property names, and will be ignored. The default includes
properties for minimum and maximum Java Heap size, the garbage collector to use, Java IO temporary directory, etc.
-|`nifi.bootstrap.sensitive.key`|The root key (in hexadecimal format) for encrypted sensitive configuration values. When NiFi is started, this root key is used to decrypt sensitive values from the _nifi.properties_ file into memory for later use.
-
-The Encrypt-Config Tool can be used to specify the root key, encrypt sensitive values in _nifi.properties_ and update _bootstrap.conf_. See the <> for an example.
|`nifi.diagnostics.on.shutdown.enabled`|(true or false) This property decides whether to run NiFi diagnostics before shutting down. The default value is `false`.
|`nifi.diagnostics.on.shutdown.verbose`|(true or false) This property decides whether to run NiFi diagnostics in verbose mode. The default value is `false`.
|`nifi.diagnostics.on.shutdown.directory`|This property specifies the location of the NiFi diagnostics directory. The default value is `./diagnostics`.
@@ -3917,7 +3896,6 @@ These properties pertain to various security features in NiFi. Many of these pro
|*Property*|*Description*
|`nifi.sensitive.props.key`|This is the password used to encrypt any sensitive property values that are configured in processors. By default, it is blank, but the system administrator should provide a value for it. It can be a string of any length, although the recommended minimum length is 10 characters. Be aware that once this password is set and one or more sensitive processor properties have been configured, this password should not be changed.
|`nifi.sensitive.props.algorithm`|The algorithm used to encrypt sensitive properties. The default value is `NIFI_PBKDF2_AES_GCM_256`.
-|`nifi.sensitive.props.additional.keys`|The comma separated list of properties in _nifi.properties_ to encrypt in addition to the default sensitive properties (see <>).
|`nifi.security.autoreload.enabled`|Specifies whether the SSL context factory should be automatically reloaded if updates to the keystore and truststore are detected. By default, it is set to `false`.
|`nifi.security.autoreload.interval`|Specifies the interval at which the keystore and truststore are checked for updates. Only applies if `nifi.security.autoreload.enabled` is set to `true`. The default value is `10 secs`.
|`nifi.security.keystore`*|The full path and name of the keystore. The default value is `./conf/keystore.p12`.
@@ -4331,33 +4309,6 @@ ZooKeeper “Connect String" property should be set to the same external ZooKeep
WARNING: Double check all configured properties for typos.
-[[sensitive_flow_migration]]
-==== Migrating a Flow with Sensitive Properties
-
-When a value is set for `nifi.sensitive.props.key` in _nifi.properties_, the specified key is used to encrypt sensitive properties in the flow (e.g. password fields in components). If the key needs to change, the Encrypt-Config tool in the NiFi Toolkit can migrate the sensitive properties key and update the _flow.json.gz_. Specifically, Encrypt-Config:
-
-1. Reads the existing _flow.json.gz_ and decrypts the sensitive values using the current key.
-2. Encrypts all the sensitive values with a specified new key.
-3. Updates the _nifi.properties_ and _flow.json.gz_ files or creates new versions of them.
-
-As an example, assume version 1.9.2 is the existing NiFi instance and the sensitive properties key is set to `password`. The goal is to move the 1.9.2 _flow.json.gz_ to a 1.10.0 instance with a new sensitive properties key: `new_password`. Running the following Encrypt-Config command would read in the _flow.json.gz_ and _nifi.properties_ files from 1.9.2 using the original sensitive properties key and write out new versions in 1.10.0 with the sensitive properties encrypted with the new password:
-
-```
-$ ./nifi-toolkit-1.10.0/bin/encrypt-config.sh -f /path/to/nifi/nifi-1.9.2/conf/flow.json.gz -g /path/to/nifi/nifi-1.10.0/conf/flow.json.gz -s new_password -n /path/to/nifi/nifi-1.9.2/conf/nifi
-.properties -o /path/to/nifi/nifi-1.10.0/conf/nifi.properties -x
-```
-
-where:
-
-* `-f` specifies the source _flow.json.gz_ (nifi-1.9.2)
-* `-g` specifies the destination _flow.json.gz_ (nifi-1.10.0)
-* `-s` specifies the new sensitive properties key (`new_password`)
-* `-n` specifies the source _nifi.properties_ (nifi-1.9.2)
-* `-o` specifies the destination _nifi.properties_ (nifi-1.10.0)
-* `-x` tells Encrypt-Config to only process the sensitive properties
-
-For more information see the <> section in the NiFi Toolkit Guide.
-
==== Updating the Sensitive Properties Algorithm
The following command can be used to read an existing flow configuration and set a new sensitive properties algorithm in _nifi.properties_:
diff --git a/nifi-docs/src/main/asciidoc/toolkit-guide.adoc b/nifi-docs/src/main/asciidoc/toolkit-guide.adoc
index 70f0ea8286fa..2e6c39056184 100644
--- a/nifi-docs/src/main/asciidoc/toolkit-guide.adoc
+++ b/nifi-docs/src/main/asciidoc/toolkit-guide.adoc
@@ -23,7 +23,6 @@ Apache NiFi Team
The NiFi Toolkit contains several command line utilities to setup and support NiFi in standalone and clustered environments. The utilities include:
* CLI -- The `cli` tool enables administrators to interact with NiFi and NiFi Registry instances to automate tasks such as deploying versioned flows and managing process groups and cluster nodes.
-* Encrypt Config -- The `encrypt-config` tool encrypts the sensitive keys in the _nifi.properties_ file to facilitate the setup of a secure NiFi instance.
The utilities are executed with scripts found in the `bin` folder of your NiFi Toolkit installation.
@@ -429,347 +428,6 @@ commands.add(new MyCommand());
To add a NiFi Registry command, perform the same steps, but extend from `AbstractNiFiRegistryCommand`, and add the command to `NiFiRegistryCommandGroup`.
-[[encrypt_config_tool]]
-== Encrypt-Config Tool
-The `encrypt-config` command line tool (invoked as `./bin/encrypt-config.sh` or `bin\encrypt-config.bat`) reads from a _nifi.properties_ file with plaintext sensitive configuration values, prompts for a root password or raw hexadecimal key, and encrypts each value. It replaces the plain values with the protected value in the same file, or writes to a new _nifi.properties_ file if specified.
-
-The default encryption algorithm utilized is AES-GCM with 256-bit keys.
-
-=== Usage
-To show help:
-
- ./bin/encrypt-config.sh -h
-
-==== NiFi
-The following are available options when targeting NiFi:
-
-* `-h`,`--help` Show usage information (this message)
-* `-v`,`--verbose` Sets verbose mode (default false)
-* `-n`,`--niFiProperties ` The _nifi.properties_ file containing unprotected config values (will be overwritten unless `-o` is specified)
-* `-o`,`--outputNiFiProperties ` The destination _nifi.properties_ file containing protected config values (will not modify input _nifi.properties_)
-* `-l`,`--loginIdentityProviders ` The _login-identity-providers.xml_ file containing unprotected config values (will be overwritten unless `-i` is specified)
-* `-i`,`--outputLoginIdentityProviders ` The destination _login-identity-providers.xml_ file containing protected config values (will not modify input _login-identity-providers.xml_)
-* `-a`,`--authorizers ` The _authorizers.xml_ file containing unprotected config values (will be overwritten unless `-u` is specified)
-* `-u`,`--outputAuthorizers ` The destination _authorizers.xml_ file containing protected config values (will not modify input _authorizers.xml_)
-* `-f`,`--flowJson ` The _flow.json.gz_ file currently protected with old password (will be overwritten unless `-g` is specified)
-* `-g`,`--outputFlowJson ` The destination _flow.json.gz_ file containing protected config values (will not modify input _flow.json.gz_)
-* `-b`,`--bootstrapConf ` The bootstrap.conf file to persist root key and to optionally provide any configuration for the protection scheme.
-* `-B`,`--outputBootstrapConf ` The destination _bootstrap.conf_ file to persist root key. If specified, the input _bootstrap.conf_ will not be modified.
-* `-S`,`--protectionScheme ` Selects the protection scheme for encrypted properties. Valid values are: [<>, <>, <>, <>, <>, <>, <>, <>] (default is AES_GCM)
-* `-k`,`--key ` The raw hexadecimal key to use to encrypt the sensitive properties
-* `-e`,`--oldKey ` The old raw hexadecimal key to use during key migration
-* `-H`,`--oldProtectionScheme ` The old protection scheme to use during encryption migration (see --protectionScheme for possible values). Default is AES_GCM
-* `-p`,`--password ` The password from which to derive the key to use to encrypt the sensitive properties
-* `-w`,`--oldPassword ` The old password from which to derive the key during migration
-* `-r`,`--useRawKey` If provided, the secure console will prompt for the raw key value in hexadecimal form
-* `-m`,`--migrate` If provided, the _nifi.properties_ and/or _login-identity-providers.xml_ sensitive properties will be re-encrypted with the new scheme
-* `-x`,`--encryptFlowJsonOnly` If provided, the properties in _flow.json.gz_ will be re-encrypted with a new key but the _nifi.properties_ and/or _login-identity-providers.xml_ files will not be modified
-* `-s`,`--propsKey ` The password or key to use to encrypt the sensitive processor properties in _flow.json.gz_
-* `-A`,`--newFlowAlgorithm ` The algorithm to use to encrypt the sensitive processor properties in _flow.json.gz_
-
-==== NiFi Registry
-The following are available options when targeting NiFi Registry using the `--nifiRegistry` flag:
-
-* `-h`,`--help` Show usage information (this message)
-* `-v`,`--verbose` Sets verbose mode (default false)
-* `-p`,`--password ` Protect the files using a password-derived key. If an argument is not provided to this flag, interactive mode will be triggered to prompt the user to enter the password.
-* `-k`,`--key ` Protect the files using a raw hexadecimal key. If an argument is not provided to this flag, interactive mode will be triggered to prompt the user to enter the key.
-* `-S`,`--protectionScheme ` Selects the protection scheme for encrypted properties. Valid values are: [<>, <>, <>, <>, <>, <>, <>, <>] (default is AES_GCM)
-* `-w`,`--oldPassword ` If the input files are already protected using a password-derived key, this specifies the old password so that the files can be unprotected before re-protecting.
-* `-e`,`--oldKey ` If the input files are already protected using a key, this specifies the raw hexadecimal key so that the files can be unprotected before re-protecting.
-* `-H`,`--oldProtectionScheme ` The old protection scheme to use during encryption migration (see --protectionScheme for possible values). Default is AES_GCM.
-* `-b`,`--bootstrapConf ` The _bootstrap.conf_ file containing no root key or an existing root key, and any other protection scheme configuration properties. If a new password or key is specified (using -p or -k) and no output _bootstrap.conf_ file is specified, then this file will be overwritten to persist the new master key.
-* `-B`,`--outputBootstrapConf ` The destination _bootstrap.conf_ file to persist root key. If specified, the input _bootstrap.conf_ will not be modified.
-* `-r`,`--nifiRegistryProperties ` The _nifi-registry.properties_ file containing unprotected config values, overwritten if no output file specified.
-* `-R`,`--outputNifiRegistryProperties ` The destination _nifi-registry.properties_ file containing protected config values.
-* `-a`,`--authorizersXml ` The _authorizers.xml_ file containing unprotected config values, overwritten if no output file specified.
-* `-u`,`--outputAuthorizersXml ` The destination _authorizers.xml_ file containing protected config values.
-* `-i`,`--identityProvidersXml ` The _identity-providers.xml_ file containing unprotected config values, overwritten if no output file specified.
-* `-I`,`--outputIdentityProvidersXml ` The destination _identity-providers.xml_ file containing protected config values.
-
-=== Protection Schemes
-The protection scheme can be selected during encryption using the `--protectionScheme` flag. During migration, the former protection scheme is specified using the `--oldProtectionScheme` flag. This distinction allows a set of protected configuration files to be migrated not only to a new key, but to a completely different protection scheme.
-
-==== AES_GCM [[AES_GCM]]
-The default protection scheme, `AES-G/CM` simply encrypts sensitive properties and marks their protection as either `aes/gcm/256` or `aes/gcm/256` as appropriate. This protection is all done within NiFi itself.
-
-==== HASHICORP_VAULT_TRANSIT [[HASHICORP_VAULT_TRANSIT]]
-This protection scheme uses https://www.vaultproject.io/docs/secrets/transit[HashiCorp Vault Transit Secrets Engine] to outsource encryption to a configured Vault server. All HashiCorp Vault configuration is stored in the `bootstrap-hashicorp-vault.conf` file, as referenced in the `bootstrap.conf` of a NiFi or NiFi Registry instance. Therefore, when using the HASHICORP_VAULT_TRANSIT protection scheme, the `nifi(.registry)?.bootstrap.protection.hashicorp.vault.conf` property in the `bootstrap.conf` specified using the `-b` flag must be available to the Encrypt Configuration Tool and must be configured as described in the <> section in the link:administration-guide.html[NiFi Administration Guide].
-
-==== HASHICORP_VAULT_KV [[HASHICORP_VAULT_KV]]
-This protection scheme uses https://www.vaultproject.io/docs/secrets/kv/kv-v1[HashiCorp Vault Key Value Secrets Engine Version 1] to store sensitive values as Vault Secrets. All HashiCorp Vault configuration is stored in the `bootstrap-hashicorp-vault.conf` file, as referenced in the `bootstrap.conf` of a NiFi or NiFi Registry instance. Therefore, when using the HASHICORP_VAULT_KV protection scheme, the `nifi(.registry)?.bootstrap.protection.hashicorp.vault.conf` property in the `bootstrap.conf` specified using the `-b` flag must be available to the Encrypt Configuration Tool and must be configured as described in the <> section in the link:administration-guide.html[NiFi Administration Guide].
-
-==== AWS_KMS [[AWS_KMS]]
-This protection scheme uses https://aws.amazon.com/kms/[AWS Key Management] Service for encryption and decryption. AWS KMS configuration properties can be stored in the `bootstrap-aws.conf` file, as referenced in the `bootstrap.conf` of NiFi or NiFi Registry. If the configuration properties are not specified in `bootstrap-aws.conf`, then the provider will attempt to use the AWS default credentials provider, which checks standard environment variables and system properties. Therefore, when using the AWS_KMS protection scheme, the `nifi(.registry)?.bootstrap.protection.aws.conf` property in the `bootstrap.conf` specified using the `-b` flag must be available to the Encrypt Configuration Tool and must be configured as described in the <> section in the link:administration-guide.html[NiFi Administration Guide].
-
-==== AWS_SECRETSMANAGER [[AWS_SECRETSMANAGER]]
-This protection scheme uses https://aws.amazon.com/secrets-manager/[AWS Secrets Manager] Service to store sensitive values as AWS Secrets. AWS Secrets Manager configuration properties can be stored in the `bootstrap-aws.conf` file, as referenced in the `bootstrap.conf` of NiFi or NiFi Registry. If the configuration properties are not specified in `bootstrap-aws.conf`, then the provider will attempt to use the AWS default credentials provider, which checks standard environment variables and system properties. Therefore, when using the AWS_SECRETS_MANAGER protection scheme, the `nifi(.registry)?.bootstrap.protection.aws.conf` property in the `bootstrap.conf` specified using the `-b` flag must be available to the Encrypt Configuration Tool and must be configured as described in the <> section in the link:administration-guide.html[NiFi Administration Guide].
-
-==== Microsoft Azure Key Vault Sensitive Property Providers
-
-Azure Key Vault configuration properties can be stored in the `bootstrap-azure.conf` file, as referenced in the
-`bootstrap.conf` of NiFi or NiFi Registry.
-
-Azure Key Vault providers will use the
-https://docs.microsoft.com/en-us/java/api/com.azure.identity.defaultazurecredential[DefaultAzureCredential]
-for authentication.
-The https://docs.microsoft.com/en-us/java/api/overview/azure/identity-readme#key-concepts[Azure Identity] client library
-describes the process for credentials resolution, which leverages environment variables, system properties, and falls
-back to
-https://docs.microsoft.com/en-us/java/api/overview/azure/identity-readme#managed-identity-support[Managed Identity]
-authentication.
-
-When using Azure Key Vault providers, `bootstrap.conf` must contain the
-`nifi.bootstrap.protection.azure.keyvault.conf` property. The `bootstrap.conf` file location must be specified using the
-`-b` argument when running the Encrypt Config Tool.
-
-===== AZURE_KEYVAULT_KEY [[AZURE_KEYVAULT_KEY]]
-
-This protection scheme uses keys managed by
-https://docs.microsoft.com/en-us/azure/key-vault/keys/about-keys[Azure Key Vault Keys] for encryption and decryption.
-
-See <> in the NiFi System
-Administrator's Guide for required properties.
-
-===== AZURE_KEYVAULT_SECRET [[AZURE_KEYVAULT_SECRET]]
-
-This protection scheme uses secrets managed by
-https://docs.microsoft.com/en-us/azure/key-vault/secrets/about-secrets[Azure Key Vault Secrets] for storing and
-retrieving sensitive property values.
-
-See <> in the NiFi System
-Administrator's Guide for required properties.
-
-==== GCP_KMS [[GCP_KMS]]
-This protection scheme uses Google Cloud Key Management Service (https://cloud.google.com/security-key-management[Google Cloud Key Management Service]) for encryption and decryption. Google Cloud KMS configuration properties are to be stored in the `bootstrap-gcp.conf` file, as referenced in the `bootstrap.conf` of NiFi or NiFi Registry. Credentials must be configured as per the following documentation: https://cloud.google.com/kms/docs/reference/libraries[Google Cloud KMS documentation]. Therefore, when using the GCP_KMS protection scheme, the `nifi(.registry)?.bootstrap.protection.gcp.kms.conf` property in the `bootstrap.conf` specified using the `-b` flag must be available to the Encrypt Configuration Tool and must be configured as described in the <> section in the link:administration-guide.html[NiFi Administration Guide].
-
-=== Examples
-
-==== NiFi
-As an example of how the tool works, assume that you have installed the tool on a machine supporting 256-bit encryption and with the following existing values in the _nifi.properties_ file:
-
-[source]
-----
-# security properties #
-nifi.sensitive.props.key=thisIsABadSensitiveKeyPassword
-nifi.sensitive.props.algorithm=NIFI_PBKDF2_AES_GCM_256
-nifi.sensitive.props.additional.keys=
-
-nifi.security.keystore=/path/to/keystore.jks
-nifi.security.keystoreType=JKS
-nifi.security.keystorePasswd=thisIsABadKeystorePassword
-nifi.security.keyPasswd=thisIsABadKeyPassword
-nifi.security.truststore=
-nifi.security.truststoreType=
-nifi.security.truststorePasswd=
-----
-
-Enter the following arguments when using the tool:
-
-----
-encrypt-config.sh \
--b bootstrap.conf \
--k 0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210 \
--n nifi.properties
-----
-
-As a result, the _nifi.properties_ file is overwritten with protected properties and sibling encryption identifiers (`aes/gcm/256`, the currently supported algorithm):
-
-[source]
-----
-# security properties #
-nifi.sensitive.props.key=n2z+tTTbHuZ4V4V2||uWhdasyDXD4ZG2lMAes/vqh6u4vaz4xgL4aEbF4Y/dXevqk3ulRcOwf1vc4RDQ==
-nifi.sensitive.props.key.protected=aes/gcm/256
-nifi.sensitive.props.algorithm=NIFI_PBKDF2_AES_GCM_256
-nifi.sensitive.props.additional.keys=
-
-nifi.security.keystore=/path/to/keystore.jks
-nifi.security.keystoreType=JKS
-nifi.security.keystorePasswd=oBjT92hIGRElIGOh||MZ6uYuWNBrOA6usq/Jt3DaD2e4otNirZDytac/w/KFe0HOkrJR03vcbo
-nifi.security.keystorePasswd.protected=aes/gcm/256
-nifi.security.keyPasswd=ac/BaE35SL/esLiJ||+ULRvRLYdIDA2VqpE0eQXDEMjaLBMG2kbKOdOwBk/hGebDKlVg==
-nifi.security.keyPasswd.protected=aes/gcm/256
-nifi.security.truststore=
-nifi.security.truststoreType=
-nifi.security.truststorePasswd=
-----
-
-Additionally, the _bootstrap.conf_ file is updated with the encryption key as follows:
-
-[source]
-----
-# Root key in hexadecimal format for encrypted sensitive configuration values
-nifi.bootstrap.sensitive.key=0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210
-----
-
-Sensitive configuration values are encrypted by the tool by default, however you can encrypt any additional properties, if desired. To encrypt additional properties, specify them as comma-separated values in the `nifi.sensitive.props.additional.keys` property.
-
-If the _nifi.properties_ file already has valid protected values, those property values are not modified by the tool.
-
-When applied to _login-identity-providers.xml_ and _authorizers.xml_, the property elements are updated with an `encryption` attribute:
-
-Example of protected _login-identity-providers.xml_:
-
-[source]
-----
-
-
- ldap-provider
- org.apache.nifi.ldap.LdapProvider
- START_TLS
- someuser
- q4r7WIgN0MaxdAKM||SGgdCTPGSFEcuH4RraMYEdeyVbOx93abdWTVSWvh1w+klA
-
- Uah59TWX+Ru5GY5p||B44RT/LJtC08QWA5ehQf01JxIpf0qSJUzug25UwkF5a50g
-
- ...
-
-----
-
-Example of protected _authorizers.xml_:
-
-[source]
-----
-
-
- ldap-user-group-provider
- org.apache.nifi.ldap.tenants.LdapUserGroupProvider
- START_TLS
- someuser
- q4r7WIgN0MaxdAKM||SGgdCTPGSFEcuH4RraMYEdeyVbOx93abdWTVSWvh1w+klA
-
- Uah59TWX+Ru5GY5p||B44RT/LJtC08QWA5ehQf01JxIpf0qSJUzug25UwkF5a50g
-
- ...
-
-----
-
-==== NiFi Registry
-As an example of how the tool works, assume that you have installed the tool on a machine supporting 256-bit encryption and with the following existing values in the _nifi-registry.properties_ file:
-
-----
-# security properties #
-nifi.registry.security.keystore=/path/to/keystore.jks
-nifi.registry.security.keystoreType=JKS
-nifi.registry.security.keystorePasswd=thisIsABadKeystorePassword
-nifi.registry.security.keyPasswd=thisIsABadKeyPassword
-nifi.registry.security.truststore=
-nifi.registry.security.truststoreType=
-nifi.registry.security.truststorePasswd=
-----
-
-Enter the following arguments when using the tool:
-
-----
-./bin/encrypt-config.sh --nifiRegistry \
--b bootstrap.conf \
--k 0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210 \
--r nifi-registry.properties
-----
-
-As a result, the _nifi-registry.properties_ file is overwritten with protected properties and sibling encryption identifiers (`aes/gcm/256`, the currently supported algorithm):
-
-----
-# security properties #
-nifi.registry.security.keystore=/path/to/keystore.jks
-nifi.registry.security.keystoreType=JKS
-nifi.registry.security.keystorePasswd=oBjT92hIGRElIGOh||MZ6uYuWNBrOA6usq/Jt3DaD2e4otNirZDytac/w/KFe0HOkrJR03vcbo
-nifi.registry.security.keystorePasswd.protected=aes/gcm/256
-nifi.registry.security.keyPasswd=ac/BaE35SL/esLiJ||+ULRvRLYdIDA2VqpE0eQXDEMjaLBMG2kbKOdOwBk/hGebDKlVg==
-nifi.registry.security.keyPasswd.protected=aes/gcm/256
-nifi.registry.security.truststore=
-nifi.registry.security.truststoreType=
-nifi.registry.security.truststorePasswd=
-----
-
-When applied to _identity-providers.xml_ or _authorizers.xml_, the property elements are updated with an `encryption` attribute. For example:
-
-----
-
-
- ldap-provider
- org.apache.nifi.registry.security.ldap.LdapProvider
- START_TLS
- someuser
- q4r7WIgN0MaxdAKM||SGgdCTPGSFEcuH4RraMYEdeyVbOx93abdWTVSWvh1w+klA
- /path/to/keystore.jks
- Uah59TWX+Ru5GY5p||B44RT/LJtC08QWA5ehQf01JxIpf0qSJUzug25UwkF5a50g
- JKS
- ...
-
-----
-
-Additionally, the _bootstrap.conf_ file is updated with the encryption key as follows:
-
-----
-# Root key in hexadecimal format for encrypted sensitive configuration values
-nifi.registry.bootstrap.sensitive.key=0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210
-----
-
-Sensitive configuration values are encrypted by the tool by default, however you can encrypt any additional properties, if desired.
-To encrypt additional properties, specify them as comma-separated values in the `nifi.registry.sensitive.props.additional.keys` property.
-
-
-If the _nifi-registry.properties_ file already has valid protected values and you wish to protect additional values using the
-same root key already present in your _bootstrap.conf_, then run the tool without specifying a new key:
-
-----
-# bootstrap.conf already contains root key property
-# nifi-registy.properties has been updated for nifi.registry.sensitive.props.additional.keys=...
-
-./bin/encrypt-config.sh --nifiRegistry -b bootstrap.conf -r nifi-registry.properties
-----
-
-[sensitive_property_key_migration]
-=== Sensitive Property Key Migration
-
-In order to change the key used to encrypt the sensitive values, provide the new key or password using the `-k` or `-p` flags as usual,
-and provide the existing key or password using `--old-key` or `--old-password` respectively. This will allow the toolkit to decrypt the
-existing values and re-encrypt them, and update _bootstrap.conf_ with the new key. Only one of the key or password needs to be specified
-for each phase (old vs. new), and any combination is sufficient:
-
-* old key -> new key
-* old key -> new password
-* old password -> new key
-* old password -> new password
-
-In order to change the protection scheme (e.g., migrating from AES encryption to Vault encryption), specify the `--protectionScheme`
-and `--oldProtectionScheme` in the migration command.
-
-The following is an example of the commands for protection scheme migration from AES_GCM to AWS_KMS then back. Execute these commands at the `nifi` directory with the `nifi-toolkit` directory as a sibling directory. In addition, make sure to update `bootstrap-aws.conf` with your AWS KMS Key ARN/ID and have your credentials and region configured.
-
-
-This command encrypts nifi.properties with the AES_GCM protection scheme
-----
-./../nifi-toolkit-*-SNAPSHOT/bin/encrypt-config.sh \
--b conf/bootstrap.conf \
--n conf/nifi.properties \
--k 0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210 \
--v
-----
-This command migrates nifi.properties from using AES_GCM to using AWS_KMS protection scheme
-----
-./../nifi-toolkit-*-SNAPSHOT/bin/encrypt-config.sh \
--b conf/bootstrap.conf \
--n conf/nifi.properties \
--S AWS_KMS \
--H AES_GCM \
--e 0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210 \
--m \
--v
-----
-This command migrates nifi.properties back from AWS_KMS to AES_GCM protection scheme
-----
-./../nifi-toolkit-*-SNAPSHOT/bin/encrypt-config.sh \
--b conf/bootstrap.conf \
--n conf/nifi.properties \
--S AES_GCM \
--k 0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210 \
--H AWS_KMS \
--m \
--v
-----
-
[export_import_all_flows]
=== Export All Flows
You can use the `export-all-flows` to perform the following tasks:
diff --git a/nifi-framework-bundle/nifi-framework-nar-bom/pom.xml b/nifi-framework-bundle/nifi-framework-nar-bom/pom.xml
index f5021eb4e088..65e3202b6ab7 100644
--- a/nifi-framework-bundle/nifi-framework-nar-bom/pom.xml
+++ b/nifi-framework-bundle/nifi-framework-nar-bom/pom.xml
@@ -153,18 +153,6 @@
2.0.0-SNAPSHOT
provided