Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/main/java/com/datapipe/jenkins/vault/VaultAccessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public class VaultAccessor implements Serializable {
private VaultConfig config;
private VaultCredential credential;
private List<String> policies;
private String role;
private int maxRetries = 0;
private int retryIntervalMilliseconds = 1000;

Expand All @@ -68,7 +69,7 @@ public VaultAccessor init() {
if (credential == null) {
vault = Vault.create(config);
} else {
vault = credential.authorizeWithVault(config, policies);
vault = credential.authorizeWithVault(config, policies, role);
}

vault.withRetries(maxRetries, retryIntervalMilliseconds);
Expand Down Expand Up @@ -102,6 +103,14 @@ public void setPolicies(List<String> policies) {
this.policies = policies;
}

public String getRole() {
return role;
}

public void setRole(String role) {
this.role = role;
}

public int getMaxRetries() {
return maxRetries;
}
Expand Down Expand Up @@ -200,6 +209,7 @@ public static Map<String, String> retrieveVaultSecrets(Run<?,?> run, PrintStream
vaultAccessor.setConfig(vaultConfig);
vaultAccessor.setCredential(credential);
vaultAccessor.setPolicies(generatePolicies(config.getPolicies(), envVars));
vaultAccessor.setRole(config.getRole());
vaultAccessor.setMaxRetries(config.getMaxRetries());
vaultAccessor.setRetryIntervalMilliseconds(config.getRetryIntervalMilliseconds());
vaultAccessor.init();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public class VaultConfiguration extends AbstractDescribableImpl<VaultConfigurati

private String policies;

private String role;

private Boolean disableChildPoliciesOverride;

private Integer timeout = DEFAULT_TIMEOUT;
Expand All @@ -78,6 +80,7 @@ public VaultConfiguration(VaultConfiguration toCopy) {
this.vaultNamespace = toCopy.vaultNamespace;
this.prefixPath = toCopy.prefixPath;
this.policies = toCopy.policies;
this.role = toCopy.role;
this.disableChildPoliciesOverride = toCopy.disableChildPoliciesOverride;
this.timeout = toCopy.timeout;
}
Expand Down Expand Up @@ -109,6 +112,9 @@ public VaultConfiguration mergeWithParent(VaultConfiguration parent) {
(parent.getDisableChildPoliciesOverride() != null && parent.getDisableChildPoliciesOverride())) {
result.setPolicies(parent.getPolicies());
}
if (result.role == null) {
result.setRole(parent.getRole());
}
if (result.timeout == null) {
result.setTimeout(parent.getTimeout());
}
Expand Down Expand Up @@ -197,11 +203,20 @@ public String getPolicies() {
return policies;
}

public String getRole() {
return role;
}

@DataBoundSetter
public void setPolicies(String policies) {
this.policies = fixEmptyAndTrim(policies);
}

@DataBoundSetter
public void setRole(String role) {
this.role = fixEmptyAndTrim(role);
}

public Boolean getDisableChildPoliciesOverride() {
return disableChildPoliciesOverride;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ protected AbstractVaultTokenCredential(CredentialsScope scope, String id, String
protected abstract String getToken(Vault vault);

@Override
public Vault authorizeWithVault(VaultConfig config, List<String> policies) {
public Vault authorizeWithVault(VaultConfig config, List<String> policies, String role) {
Vault vault = Vault.create(config);
return Vault.create(config.token(getToken(vault)));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,10 @@ protected Auth getVaultAuth(@NonNull Vault vault) {
* policies and a list of requested policies is provided.
* @param vault the vault instance
* @param policies the policies list
* @param role a possible token role to use
* @return the new token or null if it cannot be provisioned
*/
protected String getChildToken(Vault vault, List<String> policies) {
protected String getChildToken(Vault vault, List<String> policies, String role) {
if (usePolicies == null || !usePolicies || policies == null || policies.isEmpty()) {
return null;
}
Expand All @@ -84,6 +85,11 @@ protected String getChildToken(Vault vault, List<String> policies) {
.polices(policies)
// Set the TTL to the parent token TTL
.ttl(ttl);
if (role != null) {
tokenRequest.role(role);
LOGGER.log(Level.FINE, "Requesting child token with policies {0}, TTL {1} and role {2}",
new Object[] {policies, ttl, role});
}
LOGGER.log(Level.FINE, "Requesting child token with policies {0} and TTL {1}",
new Object[] {policies, ttl});
return auth.createToken(tokenRequest).getAuthClientToken();
Expand All @@ -105,7 +111,7 @@ private String getCacheKey(List<String> policies) {
}

@Override
public Vault authorizeWithVault(VaultConfig config, List<String> policies) {
public Vault authorizeWithVault(VaultConfig config, List<String> policies, String role) {
// Upgraded instances can have these not initialized in the constructor (serialized jobs possibly)
if (tokenCache == null || tokenExpiryCache == null) {
tokenCache = new HashMap<>();
Expand All @@ -119,7 +125,7 @@ public Vault authorizeWithVault(VaultConfig config, List<String> policies) {
config.token(tokenCache.get(cacheKey));

// After current token is configured, try to retrieve a new child token with limited policies
String childToken = getChildToken(vault, policies);
String childToken = getChildToken(vault, policies, role);
if (childToken != null) {
// A new token was generated, put it in the cache and configure vault
tokenCache.put(cacheKey, childToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
@NameWith(VaultCredential.NameProvider.class)
public interface VaultCredential extends StandardCredentials, Serializable {

Vault authorizeWithVault(VaultConfig config, List<String> policies);
Vault authorizeWithVault(VaultConfig config, List<String> policies, String role);

class NameProvider extends CredentialsNameProvider<VaultCredential> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
<f:entry field="engineVersion" title="K/V Engine Version">
<f:select/>
</f:entry>
<f:entry title="(Optional) Token Role" field="role">
<f:textbox/>
</f:entry>
<f:entry title="(Optional) Job Policies" field="policies">
<f:textarea/>
</f:entry>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<div>
Specify token <strong>role</strong> name to use when creating new tokens (see <a href="https://developer.hashicorp.com/vault/api-docs/auth/token#create-update-token-role">Create / update token role</a>).
Roles enforce specific behavior when creating tokens that allow token functionality
that is otherwise not available or would require <strong>sudo/root</strong> privileges to access.
Role parameters, when set, override any provided options to the create endpoints.
The role name is also included in the token path, allowing all tokens created against a role
to be revoked using the <strong>/sys/leases/revoke-prefix</strong> endpoint.
Token roles are different from AppRole roles and also need to exist in order to use them.
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public void shouldBeAbleToFetchTokenOnInit() throws VaultException {
when(auth.lookupSelf()).thenReturn(lookupResponse);
when(lookupResponse.getTTL()).thenReturn(5L);

vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, null);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, null, null);

verify(vaultConfig).token("fakeToken");
}
Expand All @@ -68,9 +68,9 @@ public void shouldFetchNewTokenForDifferentPolicies() throws VaultException {
when(authResponse.getAuthClientToken()).thenReturn("fakeToken1", "fakeToken2");
when(childAuthResponse.getAuthClientToken()).thenReturn("childToken1", "childToken2");

vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, null);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, null, null);
verify(vaultConfig).token("fakeToken1");
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, policies);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, policies, null);
verify(vaultConfig).token("childToken1");
}

Expand All @@ -79,7 +79,7 @@ public void shouldNotFetchChildTokenIfEmptyPoliciesSpecified() throws VaultExcep
when(authResponse.getAuthClientToken()).thenReturn("fakeToken");
when(auth.lookupSelf()).thenReturn(lookupResponse);
when(lookupResponse.getTTL()).thenReturn(0L);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, new ArrayList<>());
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, new ArrayList<>(), null);

verify(vaultConfig, times(1)).token(anyString());
verify(vaultConfig).token("fakeToken");
Expand All @@ -94,7 +94,7 @@ public void shouldFetchChildTokenIfPoliciesSpecified() throws VaultException {
// First response is for parent, second is for child
when(lookupResponse.getTTL()).thenReturn(30L, 0L);

vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, policies);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, policies, null);

verify(vaultConfig, times(2)).token(anyString());
verify(vaultConfig).token("fakeToken");
Expand All @@ -108,13 +108,13 @@ public void shouldReuseTheExistingTokenIfNotExpired() throws VaultException {
when(auth.lookupSelf()).thenReturn(lookupResponse);
when(lookupResponse.getTTL()).thenReturn(30L);

vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, null);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, null);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, null, null);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, null, null);
verify(vaultConfig, times(2)).token("fakeToken1");

// Different policies results in a new token
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, policies);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, policies);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, policies, null);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, policies, null);
verify(vaultConfig, times(2)).token("childToken1");
}

Expand All @@ -125,15 +125,15 @@ public void shouldFetchNewTokenIfExpired() throws VaultException {
when(auth.lookupSelf()).thenReturn(lookupResponse);
when(lookupResponse.getTTL()).thenReturn(0L);

vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, null);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, null);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, null, null);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, null, null);
verify(vaultConfig, times(2)).token(anyString());
verify(vaultConfig).token("fakeToken1");
verify(vaultConfig).token("fakeToken2");

// Different policies results in a new token
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, policies);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, policies);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, policies, null);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, policies, null);
verify(vaultConfig).token("childToken1");
verify(vaultConfig).token("childToken2");
}
Expand All @@ -143,8 +143,8 @@ public void shouldExpireTokenImmediatelyIfExceptionFetchingTTL() throws VaultExc
when(authResponse.getAuthClientToken()).thenReturn("fakeToken1", "fakeToken2");
when(auth.lookupSelf()).thenThrow(new VaultException("Fail for testing"));

vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, null);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, null);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, null, null);
vaultTokenCredentialWithExpiration.authorizeWithVault(vaultConfig, null, null);

verify(vaultConfig, times(2)).token(anyString());
verify(vaultConfig).token("fakeToken1");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ public static VaultAppRoleCredential createTokenCredential(final String credenti
when(cred.getDescription()).thenReturn("description");
when(cred.getRoleId()).thenReturn("role-id-" + credentialId);
when(cred.getSecretId()).thenReturn(Secret.fromString("secret-id-" + credentialId));
when(cred.authorizeWithVault(any(), eq(null))).thenReturn(vault);
when(cred.authorizeWithVault(any(), eq(null), eq(null))).thenReturn(vault);
return cred;

}
Expand Down