You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@nifi.apache.org by GitBox <gi...@apache.org> on 2021/06/14 16:05:57 UTC

[GitHub] [nifi] gresockj opened a new pull request #5154: NIFI-8447: Adding Transit Engine HC Vault SPP

gresockj opened a new pull request #5154:
URL: https://github.com/apache/nifi/pull/5154


   <!--
     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.
   -->
   #### Description of PR
   
   This covers both NIFI-8444 and NIFI-8447, and implements a new HashiCorpVaultTransitSensitivePropertyProvider that uses Vault's Transit Secrets Engine.
   
   To test, stand up a Vault instance and fill in the appropriate properties now available in bootstrap.conf.  This provider is disabled with the default configuration, and can be enabled as described in the bootstrap.conf properties comments.
   
   In order to streamline the review of the contribution we ask you
   to ensure the following steps have been taken:
   
   ### For all changes:
   - [x] Is there a JIRA ticket associated with this PR? Is it referenced 
        in the commit message?
   
   - [x]X Does your PR title start with **NIFI-XXXX** where XXXX is the JIRA number you are trying to resolve? Pay particular attention to the hyphen "-" character.
   
   - [x] Has your PR been rebased against the latest commit within the target branch (typically `main`)?
   
   - [x] Is your initial contribution a single, squashed commit? _Additional commits in response to PR reviewer feedback should be made on this branch and pushed to allow change tracking. Do not `squash` or use `--force` when pushing to allow for clean monitoring of changes._
   
   ### For code changes:
   - [x Have you ensured that the full suite of tests is executed via `mvn -Pcontrib-check clean install` at the root `nifi` folder?
   - [x] Have you written or updated unit tests to verify your changes?
   - [x] Have you verified that the full build is successful on JDK 8?
   - [x] Have you verified that the full build is successful on JDK 11?
   - [ ] If adding new dependencies to the code, are these dependencies licensed in a way that is compatible for inclusion under [ASF 2.0](http://www.apache.org/legal/resolved.html#category-a)? 
   - [ ] If applicable, have you updated the `LICENSE` file, including the main `LICENSE` file under `nifi-assembly`?
   - [ ] If applicable, have you updated the `NOTICE` file, including the main `NOTICE` file found under `nifi-assembly`?
   - [ ] If adding new Properties, have you added `.displayName` in addition to .name (programmatic access) for each of the new properties?
   
   ### For documentation related changes:
   - [x] Have you ensured that format looks appropriate for the output in which it is rendered?
   
   ### Note:
   Please ensure that once the PR is submitted, you check GitHub Actions CI for build issues and submit an update to your PR as soon as possible.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [nifi] exceptionfactory commented on a change in pull request #5154: NIFI-8447: Adding Transit Engine HC Vault SPP

Posted by GitBox <gi...@apache.org>.
exceptionfactory commented on a change in pull request #5154:
URL: https://github.com/apache/nifi/pull/5154#discussion_r654806383



##########
File path: nifi-commons/nifi-sensitive-property-provider/src/test/java/org/apache/nifi/properties/StandardSensitivePropertyProviderFactoryTest.java
##########
@@ -45,32 +48,38 @@
     private static final String AD_HOC_KEY_HEX = "123456789ABCDEFFEDCBA98765432101";
 
     private static Path tempConfDir;
-    private static Path mockBootstrapConf;
-    private static Path mockNifiProperties;
+    private static Path bootstrapConf;
+    private static Path hashicorpVaultBootstrapConf;
+    private static Path nifiProperties;
 
     private static NiFiProperties niFiProperties;
 
     @BeforeClass
     public static void initOnce() throws IOException {
         Security.addProvider(new BouncyCastleProvider());
         tempConfDir = Files.createTempDirectory("conf");
-        mockBootstrapConf = Files.createTempFile("bootstrap", ".conf").toAbsolutePath();
+        bootstrapConf = Files.createTempFile("bootstrap", ".conf").toAbsolutePath();
+        hashicorpVaultBootstrapConf = Files.createTempFile("bootstrap-hashicorp-vault", ".conf").toAbsolutePath();

Review comment:
       This value appears to be causing failures on the Windows automated build due to forward slashes being treated as escape characters when writing out the temporary file contents.  One approach used in `SetSingleUserCredentials.getNiFiProperties()` is Apache Commons IO `FilenameUtils.separatorsToUnix()`, which changes separators to forward slashes on all platforms.

##########
File path: nifi-commons/nifi-property-utils/src/main/java/org/apache/nifi/properties/AbstractBootstrapPropertiesLoader.java
##########
@@ -74,13 +76,27 @@ public String extractKeyFromBootstrapFile() throws IOException {
      * @throws IOException If the file is not readable
      */
     public BootstrapProperties loadBootstrapProperties(final String bootstrapPath) throws IOException {
-        final Properties properties = new Properties();
         final Path bootstrapFilePath = getBootstrapFile(bootstrapPath).toPath();
-        try (final InputStream bootstrapInput = Files.newInputStream(bootstrapFilePath)) {
+       return loadBootstrapProperties(bootstrapFilePath, getApplicationPrefix());
+    }
+
+    /**
+     * Loads a properties file into a BootstrapProperties object.
+     * @param bootstrapPath The path to the properties file
+     * @param propertyPrefix The property prefix to enforce
+     * @return The BootstrapProperties
+     * @throws IOException If the properties file could not be read
+     */
+    public static BootstrapProperties loadBootstrapProperties(final Path bootstrapPath, final String propertyPrefix) throws IOException {
+        Objects.requireNonNull(bootstrapPath, "Bootstrap path must be provided");
+        Objects.requireNonNull(propertyPrefix, "Property prefix must be provided");
+
+        final Properties properties = new Properties();
+        try (final InputStream bootstrapInput = Files.newInputStream(bootstrapPath)) {
             properties.load(bootstrapInput);
-            return new BootstrapProperties(getApplicationPrefix(), properties, bootstrapFilePath);
+            return new BootstrapProperties(propertyPrefix, properties, bootstrapPath);
         } catch (final IOException e) {
-            logger.error("Cannot read from bootstrap.conf file at {}", bootstrapFilePath);
+            logger.debug("Cannot read from bootstrap.conf file at {}", bootstrapPath);

Review comment:
       Instead of changing this log method and others from error to debug, removing the log and including the path in the exception message seems like a more concise approach.

##########
File path: nifi-commons/nifi-sensitive-property-provider/src/main/java/org/apache/nifi/properties/HashiCorpVaultTransitSensitivePropertyProvider.java
##########
@@ -0,0 +1,92 @@
+/*
+ * 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.lang3.StringUtils;
+
+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";
+
+    HashiCorpVaultTransitSensitivePropertyProvider(final BootstrapProperties bootstrapProperties) {
+        super(bootstrapProperties);
+    }
+
+    @Override
+    protected String getSecretsEnginePath(final BootstrapProperties vaultBootstrapProperties) {
+        if (vaultBootstrapProperties == null) {
+            return null;
+        }
+        final String transitPath = vaultBootstrapProperties.getProperty(TRANSIT_PATH);
+        // Validate transit path
+        try {
+            PropertyProtectionScheme.fromIdentifier(getProtectionScheme().getIdentifier(transitPath));
+        } catch (IllegalArgumentException e) {
+            throw new SensitivePropertyProtectionException(TRANSIT_PATH + " contains unsupported characters");

Review comment:
       It would be helpful to include the actual `transitPath` value, as well as the `IllegalArgumentException` as the cause or part of the exception message.

##########
File path: nifi-docs/src/main/asciidoc/toolkit-guide.adoc
##########
@@ -466,6 +470,40 @@ The following are available options when targeting NiFi Registry using the `--ni
  * `-I`,`--outputIdentityProvidersXml <file>`    The destination _identity-providers.xml_ file containing protected config values.
  * `--decrypt`                                    Can be used with `-r` to decrypt a previously encrypted NiFi Registry Properties file. Decrypted content is printed to STDOUT.
 
+=== 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
+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
+This protection scheme uses HashiCorp Vault's Transit Secrets Engine (https://www.vaultproject.io/docs/secrets/transit) 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 follows:
+
+===== Required properties
+[options="header,footer"]
+|===
+|Property Name|Description|Default
+|`vault.uri`|The HashiCorp Vault URI (e.g., `https://vault-server:8200`).  If not set, this provider will be disabled.|_none_
+|`vault.authPropertiesFilename`|Filename of a properties file containing Vault authentication properties.  See the `Authentication-specific property keys` section of https://docs.spring.io/spring-vault/docs/2.3.x/reference/html/#vault.core.environment-vault-configuration" for all authentication property keys. If not set, this provider will be disabled.|_none_
+|`vault.transit.path`|The HashiCorp Vault `path` specifying the Transit Secrets Engine (e.g., `nifi-transit`).  Valid characters include alphanumeric, dash, and underscore.|_none_
+|===
+
+===== Optional properties
+[options="header,footer"]
+|===
+|Property Name|Description|Default
+|`vault.connection.timeout`|The connection timeout of the Vault client|`5 secs`
+|`vault.read.timeout`|The read timeout of the Vault client|`15 secs`
+|`vault.ssl.enabledCipherSuites`|A comma-separated list of the enabled TLS cipher suites|_none_
+|`vault.ssl.enabledProtocols`|A comma-separated list of the enabled TLS protocols|_none_
+|`vault.ssl.key-store`|Path to a keystore.  Required if the Vault server is TLS-enabled|_none_
+|`vault.ssl.key-store-type`|Keystore type (JKS or PKCS12).  Required if the Vault server is TLS-enabled|_none_

Review comment:
       Can the BCFKS format be supported here, or is this dependent on the Spring Vault code?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [nifi] exceptionfactory commented on a change in pull request #5154: NIFI-8447: Adding Transit Engine HC Vault SPP

Posted by GitBox <gi...@apache.org>.
exceptionfactory commented on a change in pull request #5154:
URL: https://github.com/apache/nifi/pull/5154#discussion_r654806383



##########
File path: nifi-commons/nifi-sensitive-property-provider/src/test/java/org/apache/nifi/properties/StandardSensitivePropertyProviderFactoryTest.java
##########
@@ -45,32 +48,38 @@
     private static final String AD_HOC_KEY_HEX = "123456789ABCDEFFEDCBA98765432101";
 
     private static Path tempConfDir;
-    private static Path mockBootstrapConf;
-    private static Path mockNifiProperties;
+    private static Path bootstrapConf;
+    private static Path hashicorpVaultBootstrapConf;
+    private static Path nifiProperties;
 
     private static NiFiProperties niFiProperties;
 
     @BeforeClass
     public static void initOnce() throws IOException {
         Security.addProvider(new BouncyCastleProvider());
         tempConfDir = Files.createTempDirectory("conf");
-        mockBootstrapConf = Files.createTempFile("bootstrap", ".conf").toAbsolutePath();
+        bootstrapConf = Files.createTempFile("bootstrap", ".conf").toAbsolutePath();
+        hashicorpVaultBootstrapConf = Files.createTempFile("bootstrap-hashicorp-vault", ".conf").toAbsolutePath();

Review comment:
       This value appears to be causing failures on the Windows automated build due to back slashes being treated as escape characters when writing out the temporary file contents.  One approach used in `SetSingleUserCredentials.getNiFiProperties()` is Apache Commons IO `FilenameUtils.separatorsToUnix()`, which changes separators to forward slashes on all platforms.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [nifi] gresockj commented on a change in pull request #5154: NIFI-8447: Adding Transit Engine HC Vault SPP

Posted by GitBox <gi...@apache.org>.
gresockj commented on a change in pull request #5154:
URL: https://github.com/apache/nifi/pull/5154#discussion_r654345509



##########
File path: nifi-commons/nifi-property-utils/src/main/java/org/apache/nifi/properties/BootstrapProperties.java
##########
@@ -79,8 +107,53 @@ private String getPropertyKey(final String subKey) {
         return Optional.ofNullable(getProperty(getPropertyKey(BOOTSTRAP_SENSITIVE_KEY)));
     }
 
+    /**
+     * Returns the location of the HashiCorp Vault sensitive property provider
+     * @return The location of the HashiCorp Vault sensitive property provider
+     */
+    public Optional<String> getHashiCorpVaultPropertiesFile() {
+        return Optional.ofNullable(getProperty(getPropertyKey(BOOTSTRAP_SPP_HASHICORP_VAULT_PROPERTIES)));
+    }
+
     @Override
     public String toString() {
         return String.format("Bootstrap properties [%s] with prefix [%s]", configFilePath, propertyPrefix);
     }
+
+    /**
+     * An empty instance of BootstrapProperties.
+     */
+    public static final BootstrapProperties EMPTY = new BootstrapProperties("", new Properties(), Paths.get("conf/bootstrap.conf")) {
+        @Override
+        public Set<String> getPropertyKeys() {
+            return null;
+        }
+
+        @Override
+        public String getProperty(String key) {
+            return null;
+        }
+
+        @Override
+        public String getProperty(String key, String defaultValue) {
+            return null;
+        }
+
+        @Override
+        public int size() {
+            return 0;
+        }
+    };
+
+    private static boolean isBlank(final String string) {
+        return (string == null) || string.isEmpty() || string.trim().isEmpty();
+    }
+
+    /**
+     * Returns the property prefix for these properties (e.g., 'nifi').
+     * @return The property prefix
+     */
+    public String getPropertyPrefix() {

Review comment:
       Actually this was part of something I abandoned, so I'll just remove it.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [nifi] gresockj commented on a change in pull request #5154: NIFI-8447: Adding Transit Engine HC Vault SPP

Posted by GitBox <gi...@apache.org>.
gresockj commented on a change in pull request #5154:
URL: https://github.com/apache/nifi/pull/5154#discussion_r658148884



##########
File path: nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/bootstrap-hashicorp-vault.conf
##########
@@ -0,0 +1,52 @@
+#
+# 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.
+#
+
+# HashiCorp Vault Sensitive Property Providers (not enabled if the vault.uri is not set)
+vault.uri=
+
+# Location of a properties file with authentication properties as seen in
+# Spring Vault: https://docs.spring.io/spring-vault/docs/2.3.x/reference/html/#vault.core.environment-vault-configuration
+# If not set, all Spring Vault authentication properties must be included in bootstrap-hashicorp-vault.conf
+# If authentication properties are provided in both locations, the ones in bootstrap-hashicorp-vault.conf take precedence.
+# Note that if vault.authentication is not set in either location, its default value is 'token'.
+vault.authPropertiesFilename=
+
+## Example vault authentication properties
+## Certification authentication (also requires ssl properties to be configured)
+# vault.authentication=CERT
+
+## Token authentication (default)
+# vault.token=<token value>
+
+## Token authentication (the default)
+# vault.token

Review comment:
       Whoops.  And yes, I like your suggestion.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [nifi] exceptionfactory commented on a change in pull request #5154: NIFI-8447: Adding Transit Engine HC Vault SPP

Posted by GitBox <gi...@apache.org>.
exceptionfactory commented on a change in pull request #5154:
URL: https://github.com/apache/nifi/pull/5154#discussion_r656302120



##########
File path: nifi-commons/nifi-sensitive-property-provider/src/main/java/org/apache/nifi/properties/HashiCorpVaultTransitSensitivePropertyProvider.java
##########
@@ -0,0 +1,92 @@
+/*
+ * 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.lang3.StringUtils;
+
+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";
+
+    HashiCorpVaultTransitSensitivePropertyProvider(final BootstrapProperties bootstrapProperties) {
+        super(bootstrapProperties);
+    }
+
+    @Override
+    protected String getSecretsEnginePath(final BootstrapProperties vaultBootstrapProperties) {
+        if (vaultBootstrapProperties == null) {
+            return null;
+        }
+        final String transitPath = vaultBootstrapProperties.getProperty(TRANSIT_PATH);
+        // Validate transit path
+        try {
+            PropertyProtectionScheme.fromIdentifier(getProtectionScheme().getIdentifier(transitPath));
+        } catch (IllegalArgumentException e) {
+            throw new SensitivePropertyProtectionException(String.format("{} [{}] contains unsupported characters", TRANSIT_PATH, transitPath), e);

Review comment:
       It looks like the placeholders should be `%s` instead of `{}` since this it not a logging message.
   ```suggestion
               throw new SensitivePropertyProtectionException(String.format("%s [%s] contains unsupported characters", TRANSIT_PATH, transitPath), e);
   ```

##########
File path: nifi-commons/nifi-property-utils/src/main/java/org/apache/nifi/properties/AbstractBootstrapPropertiesLoader.java
##########
@@ -121,8 +136,7 @@ private File getBootstrapFile(final String bootstrapPath) throws IOException {
             if (confDir.exists() && confDir.canRead()) {
                 expectedBootstrapFile = new File(confDir, BOOTSTRAP_CONF);
             } else {
-                logger.error("Cannot read from bootstrap.conf file at {} -- conf/ directory is missing or permissions are incorrect", confDir.getAbsolutePath());
-                throw new IOException("Cannot read from bootstrap.conf");
+                throw new IOException(String.format("Cannot read {} directory for {}", confDir, bootstrapPath));

Review comment:
       It looks like the placeholder values should be changed:
   ```suggestion
                   throw new IOException(String.format("Cannot read %s directory for %s", confDir, bootstrapPath));
   ```

##########
File path: nifi-commons/nifi-sensitive-property-provider/src/main/java/org/apache/nifi/properties/HashiCorpVaultTransitSensitivePropertyProvider.java
##########
@@ -0,0 +1,92 @@
+/*
+ * 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.lang3.StringUtils;
+
+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";
+
+    HashiCorpVaultTransitSensitivePropertyProvider(final BootstrapProperties bootstrapProperties) {
+        super(bootstrapProperties);
+    }
+
+    @Override
+    protected String getSecretsEnginePath(final BootstrapProperties vaultBootstrapProperties) {
+        if (vaultBootstrapProperties == null) {
+            return null;
+        }
+        final String transitPath = vaultBootstrapProperties.getProperty(TRANSIT_PATH);
+        // Validate transit path
+        try {
+            PropertyProtectionScheme.fromIdentifier(getProtectionScheme().getIdentifier(transitPath));
+        } catch (IllegalArgumentException e) {
+            throw new SensitivePropertyProtectionException(String.format("{} [{}] contains unsupported characters", TRANSIT_PATH, transitPath), e);
+        }
+
+        return transitPath;
+    }
+
+    @Override
+    protected PropertyProtectionScheme getProtectionScheme() {
+        return PropertyProtectionScheme.HASHICORP_VAULT_TRANSIT;
+    }
+
+    @Override
+    protected boolean hasRequiredSecretsEngineProperties(final BootstrapProperties vaultBootstrapProperties) {
+        return getSecretsEnginePath(vaultBootstrapProperties) != null;
+    }
+
+    /**
+     * Returns the encrypted cipher text.
+     *
+     * @param unprotectedValue the sensitive value
+     * @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) throws SensitivePropertyProtectionException {
+        if (StringUtils.isBlank(unprotectedValue)) {
+            throw new IllegalArgumentException("Cannot encrypt an empty value");
+        }
+
+        return getVaultCommunicationService().encrypt(getPath(), unprotectedValue.getBytes(PROPERTY_CHARSET));
+    }
+
+    /**
+     * Returns the decrypted plaintext.
+     *
+     * @param protectedValue the cipher text read from the {@code nifi.properties} file
+     * @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) throws SensitivePropertyProtectionException {
+        if (StringUtils.isBlank(protectedValue)) {
+            throw new IllegalArgumentException("Cannot encrypt an empty value");

Review comment:
       It looks like this message should be updated:
   ```suggestion
               throw new IllegalArgumentException("Cannot decrypt an empty value");
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [nifi] exceptionfactory commented on a change in pull request #5154: NIFI-8447: Adding Transit Engine HC Vault SPP

Posted by GitBox <gi...@apache.org>.
exceptionfactory commented on a change in pull request #5154:
URL: https://github.com/apache/nifi/pull/5154#discussion_r658138996



##########
File path: nifi-commons/nifi-vault-utils/src/main/java/org/apache/nifi/vault/hashicorp/config/HashiCorpVaultConfiguration.java
##########
@@ -16,31 +16,124 @@
  */
 package org.apache.nifi.vault.hashicorp.config;
 
+import org.apache.nifi.util.FormatUtils;
 import org.apache.nifi.vault.hashicorp.HashiCorpVaultConfigurationException;
 import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.PropertySource;
 import org.springframework.core.env.StandardEnvironment;
 import org.springframework.core.io.FileSystemResource;
 import org.springframework.core.io.support.ResourcePropertySource;
+import org.springframework.vault.client.RestTemplateFactory;
 import org.springframework.vault.config.EnvironmentVaultConfiguration;
+import org.springframework.vault.support.ClientOptions;
+import org.springframework.vault.support.SslConfiguration;
 
 import java.io.IOException;
 import java.nio.file.Paths;
+import java.time.Duration;
+import java.util.concurrent.TimeUnit;
 
 /**
  * A Vault configuration that uses the NiFiVaultEnvironment.
  */
 public class HashiCorpVaultConfiguration extends EnvironmentVaultConfiguration {
+    public enum VaultConfigurationKey {
+        AUTH_PROPERTIES_FILENAME("vault.authPropertiesFilename"),

Review comment:
       Following the convention of some other NiFi properties, what do you think about renaming this to `vault.authentication.properties.file`?
   ```suggestion
           AUTHENTICATION_PROPERTIES_FILE("vault.authentication.properties.file"),
   ```

##########
File path: nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/bootstrap-hashicorp-vault.conf
##########
@@ -0,0 +1,52 @@
+#
+# 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.
+#
+
+# HashiCorp Vault Sensitive Property Providers (not enabled if the vault.uri is not set)
+vault.uri=
+
+# Location of a properties file with authentication properties as seen in
+# Spring Vault: https://docs.spring.io/spring-vault/docs/2.3.x/reference/html/#vault.core.environment-vault-configuration
+# If not set, all Spring Vault authentication properties must be included in bootstrap-hashicorp-vault.conf
+# If authentication properties are provided in both locations, the ones in bootstrap-hashicorp-vault.conf take precedence.
+# Note that if vault.authentication is not set in either location, its default value is 'token'.
+vault.authPropertiesFilename=
+
+## Example vault authentication properties
+## Certification authentication (also requires ssl properties to be configured)
+# vault.authentication=CERT
+
+## Token authentication (default)
+# vault.token=<token value>
+
+## Token authentication (the default)
+# vault.token

Review comment:
       The `vault.token` property example appears to be duplicated.  Perhaps changing this example to just use token authentication would be more straightforward?
   ```suggestion
   # Example Token Authentication
   # vault.authentication=TOKEN
   # vault.token=<token value>
   ```

##########
File path: nifi-registry/nifi-registry-core/nifi-registry-resources/src/main/resources/conf/bootstrap-hashicorp-vault.conf
##########
@@ -0,0 +1,52 @@
+#
+# 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.
+#
+
+# HashiCorp Vault Sensitive Property Providers (not enabled if the vault.uri is not set)
+vault.uri=
+
+# Location of a properties file with authentication properties as seen in
+# Spring Vault: https://docs.spring.io/spring-vault/docs/2.3.x/reference/html/#vault.core.environment-vault-configuration
+# If not set, all Spring Vault authentication properties must be included in bootstrap-hashicorp-vault.conf
+# If authentication properties are provided in both locations, the ones in bootstrap-hashicorp-vault.conf take precedence.
+# Note that if vault.authentication is not set in either location, its default value is 'token'.
+vault.authPropertiesFilename=
+
+## Example vault authentication properties
+## Certification authentication (also requires ssl properties to be configured)
+# vault.authentication=CERT
+
+## Token authentication (default)
+# vault.token=<token value>
+
+## Token authentication (the default)
+# vault.token

Review comment:
       See related comment on example properties.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [nifi] asfgit closed pull request #5154: NIFI-8447: Adding Transit Engine HC Vault SPP

Posted by GitBox <gi...@apache.org>.
asfgit closed pull request #5154:
URL: https://github.com/apache/nifi/pull/5154


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [nifi] gresockj commented on a change in pull request #5154: NIFI-8447: Adding Transit Engine HC Vault SPP

Posted by GitBox <gi...@apache.org>.
gresockj commented on a change in pull request #5154:
URL: https://github.com/apache/nifi/pull/5154#discussion_r654778816



##########
File path: nifi-commons/nifi-sensitive-property-provider/src/main/java/org/apache/nifi/properties/PropertyProtectionScheme.java
##########
@@ -24,7 +24,8 @@
  * SensitivePropertyProvider.
  */
 public enum PropertyProtectionScheme {
-    AES_GCM("aes/gcm/(128|192|256)", "aes/gcm/%s", "AES Sensitive Property Provider", true);
+    AES_GCM("aes/gcm/(128|192|256)", "aes/gcm/%s", "AES Sensitive Property Provider", true),
+    HASHICORP_VAULT_TRANSIT("vault/transit/[a-z0-9-]+", "vault/transit/%s", "HashiCorp Vault Transit Engine Sensitive Property Provider", false);

Review comment:
       This could be any valid path in Vault, and will be the value of vault.transit.path in the bootstrap-hashicorp-vault.conf file.  So if vault.transit.path=nifi-transit, then the scheme will be "hashicorp/vault/transit/nifi-transit", and the SPP will create a Vault path called "transit/keys/nifi-transit".   I chose to let this path be configurable to give the user the flexibility to fit it into an existing Vault naming scheme they might have.  The only mention I can find of character restrictions in Vault key paths is this post, which seems to say only slashes are reserved characters: https://groups.google.com/g/vault-tool/c/_E2N0SLryv8.  However, I chose to restrict this so that it wasn't wide open.  I think this means I need some validation to ensure their configured transit path matches the regex, however, so I'll add that.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [nifi] gresockj commented on a change in pull request #5154: NIFI-8447: Adding Transit Engine HC Vault SPP

Posted by GitBox <gi...@apache.org>.
gresockj commented on a change in pull request #5154:
URL: https://github.com/apache/nifi/pull/5154#discussion_r654826401



##########
File path: nifi-docs/src/main/asciidoc/toolkit-guide.adoc
##########
@@ -466,6 +470,40 @@ The following are available options when targeting NiFi Registry using the `--ni
  * `-I`,`--outputIdentityProvidersXml <file>`    The destination _identity-providers.xml_ file containing protected config values.
  * `--decrypt`                                    Can be used with `-r` to decrypt a previously encrypted NiFi Registry Properties file. Decrypted content is printed to STDOUT.
 
+=== 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
+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
+This protection scheme uses HashiCorp Vault's Transit Secrets Engine (https://www.vaultproject.io/docs/secrets/transit) 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 follows:
+
+===== Required properties
+[options="header,footer"]
+|===
+|Property Name|Description|Default
+|`vault.uri`|The HashiCorp Vault URI (e.g., `https://vault-server:8200`).  If not set, this provider will be disabled.|_none_
+|`vault.authPropertiesFilename`|Filename of a properties file containing Vault authentication properties.  See the `Authentication-specific property keys` section of https://docs.spring.io/spring-vault/docs/2.3.x/reference/html/#vault.core.environment-vault-configuration" for all authentication property keys. If not set, this provider will be disabled.|_none_
+|`vault.transit.path`|The HashiCorp Vault `path` specifying the Transit Secrets Engine (e.g., `nifi-transit`).  Valid characters include alphanumeric, dash, and underscore.|_none_
+|===
+
+===== Optional properties
+[options="header,footer"]
+|===
+|Property Name|Description|Default
+|`vault.connection.timeout`|The connection timeout of the Vault client|`5 secs`
+|`vault.read.timeout`|The read timeout of the Vault client|`15 secs`
+|`vault.ssl.enabledCipherSuites`|A comma-separated list of the enabled TLS cipher suites|_none_
+|`vault.ssl.enabledProtocols`|A comma-separated list of the enabled TLS protocols|_none_
+|`vault.ssl.key-store`|Path to a keystore.  Required if the Vault server is TLS-enabled|_none_
+|`vault.ssl.key-store-type`|Keystore type (JKS or PKCS12).  Required if the Vault server is TLS-enabled|_none_

Review comment:
       Actually I think it can be supported.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org