-
Notifications
You must be signed in to change notification settings - Fork 121
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes #269. Support secret keys names.
- Loading branch information
Showing
18 changed files
with
458 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,10 @@ | ||
* xref:index.adoc[Index] | ||
* xref:config/config.adoc[Config] | ||
* xref:interceptors/interceptors.adoc[Interceptors] | ||
* Extensions | ||
** xref:config-sources/config-sources.adoc[Config Sources] | ||
** xref:converters/converters.adoc[Converters] | ||
** xref:interceptors/interceptors.adoc[Interceptors] | ||
** xref:cdi/cdi.adoc[CDI] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
:doctype: book | ||
include::../attributes.adoc[] | ||
|
||
[[cdi-extensions]] | ||
|
||
= Config | ||
|
||
* <<secret-keys>> | ||
|
||
include::secret-keys.adoc[] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
[[secret-keys]] | ||
== Secret Keys | ||
|
||
When configuration properties contain passwords or other kinds of secrets, Smallrye Config can hide them to | ||
prevent accidental exposure of such values. | ||
|
||
**This is no way a replacement for securing secrets. ** Proper security mechanisms must still be used to secure | ||
secrets. However, there is still the basic problem that passwords and secrets are generally encoded simply as | ||
strings. | ||
|
||
Secret Keys provides a way to "lock" the configuration so that secrets do not appear unless explicitly enabled. | ||
|
||
=== Configuration | ||
|
||
Secret Keys requires the list of Config property names that must be hidden. This can be supplied in | ||
`SmallRyeConfigBuilder.withSecretKeys` and initialized with `SmallRyeConfigFactory`. From this point forward, any | ||
config name retrieved from the `Config` instance that matches the Secret Keys will throw a `SecurityException`. | ||
|
||
=== Unlock Keys | ||
|
||
Access to the Secret Keys, is available via the APIs `io.smallrye.config.SecretKeys.doUnlocked(java.lang.Runnable)` and | ||
`io.smallrye.config.SecretKeys.doUnlocked(java.util.function.Supplier<T>)`. | ||
|
||
[source,java] | ||
---- | ||
String secretValue = SecretKeys.doUnlocked(() -> { | ||
config.getValue("secret", String.class); | ||
}); | ||
---- | ||
|
||
Secret Keyes are only unlocked in the context of `doUnlocked`. Once the execution completes, the secrets become | ||
locked again. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
implementation/src/main/java/io/smallrye/config/LoggingConfigSourceInterceptor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package io.smallrye.config; | ||
|
||
import static io.smallrye.config.SecretKeys.doLocked; | ||
|
||
public class LoggingConfigSourceInterceptor implements ConfigSourceInterceptor { | ||
@Override | ||
public ConfigValue getValue(final ConfigSourceInterceptorContext context, final String name) { | ||
try { | ||
// Unlocked keys will run here. | ||
ConfigValue configValue = doLocked(() -> context.proceed(name)); | ||
if (configValue != null) | ||
ConfigLogging.log.lookup(configValue.getName(), getLocation(configValue), configValue.getValue()); | ||
else | ||
ConfigLogging.log.notFound(name); | ||
return configValue; | ||
} catch (SecurityException e) { | ||
// Handled next, to omit the values to log from the secret. | ||
} | ||
|
||
// Locked keys here. | ||
final ConfigValue secret = context.proceed(name); | ||
if (secret != null) | ||
ConfigLogging.log.lookup(secret.getName(), "secret", "secret"); | ||
else | ||
ConfigLogging.log.notFound(name); | ||
return secret; | ||
} | ||
|
||
private String getLocation(final ConfigValue configValue) { | ||
return configValue.getLineNumber() != -1 ? configValue.getConfigSourceName() + ":" + configValue.getLineNumber() | ||
: configValue.getConfigSourceName(); | ||
} | ||
} |
56 changes: 56 additions & 0 deletions
56
implementation/src/main/java/io/smallrye/config/SecretKeys.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package io.smallrye.config; | ||
|
||
import java.io.Serializable; | ||
import java.util.function.Supplier; | ||
|
||
public final class SecretKeys implements Serializable { | ||
private static final ThreadLocal<Boolean> LOCKED = ThreadLocal.withInitial(() -> Boolean.TRUE); | ||
|
||
private SecretKeys() { | ||
throw new UnsupportedOperationException(); | ||
} | ||
|
||
public static boolean isLocked() { | ||
return LOCKED.get(); | ||
} | ||
|
||
public static void doUnlocked(Runnable runnable) { | ||
doUnlocked(() -> { | ||
runnable.run(); | ||
return null; | ||
}); | ||
} | ||
|
||
public static <T> T doUnlocked(Supplier<T> supplier) { | ||
if (isLocked()) { | ||
LOCKED.set(false); | ||
try { | ||
return supplier.get(); | ||
} finally { | ||
LOCKED.set(true); | ||
} | ||
} else { | ||
return supplier.get(); | ||
} | ||
} | ||
|
||
public static void doLocked(Runnable runnable) { | ||
doLocked(() -> { | ||
runnable.run(); | ||
return null; | ||
}); | ||
} | ||
|
||
public static <T> T doLocked(Supplier<T> supplier) { | ||
if (!isLocked()) { | ||
LOCKED.set(true); | ||
try { | ||
return supplier.get(); | ||
} finally { | ||
LOCKED.set(false); | ||
} | ||
} else { | ||
return supplier.get(); | ||
} | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
implementation/src/main/java/io/smallrye/config/SecretKeysConfigSourceInterceptor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package io.smallrye.config; | ||
|
||
import java.util.Set; | ||
|
||
public class SecretKeysConfigSourceInterceptor implements ConfigSourceInterceptor { | ||
private final Set<String> secrets; | ||
|
||
public SecretKeysConfigSourceInterceptor(final Set<String> secrets) { | ||
this.secrets = secrets; | ||
} | ||
|
||
@Override | ||
public ConfigValue getValue(final ConfigSourceInterceptorContext context, final String name) { | ||
if (SecretKeys.isLocked() && isSecret(name)) { | ||
throw ConfigMessages.msg.notAllowed(name); | ||
} | ||
return context.proceed(name); | ||
} | ||
|
||
private boolean isSecret(final String name) { | ||
return secrets.contains(name); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 0 additions & 41 deletions
41
implementation/src/test/java/io/smallrye/config/ConfigSourceLoggingInterceptorTest.java
This file was deleted.
Oops, something went wrong.
34 changes: 34 additions & 0 deletions
34
implementation/src/test/java/io/smallrye/config/LoggingConfigSourceInterceptorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package io.smallrye.config; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertThrows; | ||
|
||
import java.util.NoSuchElementException; | ||
|
||
import org.eclipse.microprofile.config.Config; | ||
import org.junit.Test; | ||
|
||
public class LoggingConfigSourceInterceptorTest { | ||
@Test | ||
public void interceptor() throws Exception { | ||
Config config = buildConfig(); | ||
|
||
assertEquals("abc", config.getValue("my.prop", String.class)); | ||
assertThrows(SecurityException.class, () -> config.getValue("secret", String.class)); | ||
assertThrows(NoSuchElementException.class, () -> config.getValue("not.found", String.class)); | ||
|
||
// This should not log the secret value: | ||
assertEquals("12345678", SecretKeys.doUnlocked(() -> config.getValue("secret", String.class))); | ||
} | ||
|
||
private static Config buildConfig() throws Exception { | ||
return new SmallRyeConfigBuilder() | ||
.addDefaultSources() | ||
.addDefaultInterceptors() | ||
.withSources(new ConfigValuePropertiesConfigSource( | ||
LoggingConfigSourceInterceptorTest.class.getResource("/config-values.properties"))) | ||
.withInterceptors(new LoggingConfigSourceInterceptor()) | ||
.withSecretKeys("secret") | ||
.build(); | ||
} | ||
} |
Oops, something went wrong.