Skip to content

Commit

Permalink
Add configuration to credentials to enable using limited policies
Browse files Browse the repository at this point in the history
  • Loading branch information
saville committed Jun 21, 2022
1 parent 67a16c5 commit be7448a
Show file tree
Hide file tree
Showing 13 changed files with 76 additions and 10 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ This is just a short introduction, please refer to [Hashicorp itself](https://ww

### Isolating policies for different jobs
It may be desirable to have jobs or folders with separate Vault policies allocated. This may be done
with the optional `policies` configuration option combined with AppRole authentication. The workflow
would look like this:
with the optional `policies` configuration option combined with authentication such as the AppRole
credential. The process is the following:
* The Jenkins job attempts to retrieve a secret from Vault
* The AppRole authentication is used to retrieve a new token (if the old one has not expired yet)
* The Vault plugin then uses the `policies` configuration value with job info to come up with a list of policies
Expand All @@ -30,8 +30,9 @@ would look like this:

The policies list may be templatized with values that can come from each job in order to customize
policies per job or folder. See the `policies` configuration help for more information on available
tokens to use in the configuration. Please note that the AppRole should have all policies configured
as `token_policies` and not `identity_policies`, as job-specific tokens inherit all
tokens to use in the configuration. The `Limit Token Policies` option must also be enabled on the
auth credential. Please note that the AppRole (or other authentication method) should have all policies
configured as `token_policies` and not `identity_policies`, as job-specific tokens inherit all
`identity_policies` automatically.

### What about other backends?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,43 @@
import com.bettercloud.vault.api.Auth.TokenRequest;
import com.cloudbees.plugins.credentials.CredentialsScope;
import com.datapipe.jenkins.vault.exception.VaultPluginException;
import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.annotations.NonNull;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.kohsuke.stapler.DataBoundSetter;

public abstract class AbstractVaultTokenCredentialWithExpiration
extends AbstractVaultTokenCredential {

protected final static Logger LOGGER = Logger
.getLogger(AbstractVaultTokenCredentialWithExpiration.class.getName());

@CheckForNull
private Boolean usePolicies;

/**
* Get if the configured policies should be used or not.
* @return true if the policies should be used, false or null otherwise
*/
@CheckForNull
public Boolean getUsePolicies() {
return usePolicies;
}

/**
* Set if the configured policies are used or not.
* @param usePolicies true if policies should be used, false otherwise
*/
@DataBoundSetter
public void setUsePolicies(Boolean usePolicies) {
this.usePolicies = usePolicies;
}

private Map<String, Calendar> tokenExpiry;
private Map<String, String> tokenCache;

Expand All @@ -43,13 +66,14 @@ protected Auth getVaultAuth(@NonNull Vault vault) {
}

/**
* Retrieves a new token with specific policies if a list of requested policies is provided.
* Retrieves a new child token with specific policies if this credential is configured to use
* policies and a list of requested policies is provided.
* @param vault the vault instance
* @param policies the policies list
* @return the new token or null if no policies are defined
* @return the new token or null if it cannot be provisioned
*/
protected String getTokenWithPolicies(Vault vault, List<String> policies) {
if (policies == null || policies.isEmpty()) {
protected String getChildToken(Vault vault, List<String> policies) {
if (usePolicies == null || !usePolicies || policies == null || policies.isEmpty()) {
return null;
}
Auth auth = getVaultAuth(vault);
Expand All @@ -59,7 +83,7 @@ protected String getTokenWithPolicies(Vault vault, List<String> policies) {
new Object[] {policies});
return auth.createToken(tokenRequest).getAuthClientToken();
} catch (VaultException e) {
throw new VaultPluginException("Could not retrieve token with policies from vault", e);
throw new VaultPluginException("Could not retrieve token with policies from Vault", e);
}
}

Expand Down Expand Up @@ -90,7 +114,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 = getTokenWithPolicies(vault, policies);
String childToken = getChildToken(vault, policies);
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 @@ -13,5 +13,8 @@
<f:entry title="${%Namespace}" field="namespace">
<f:textbox/>
</f:entry>
<f:entry field="usePolicies" title="Limit Token Policies">
<f:checkbox/>
</f:entry>
<st:include page="id-and-description" class="${descriptor.clazz}"/>
</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div>
If checked and policies are defined in the Vault plugin configuration, a child token will be
provisioned after authenticating with Vault with only the configured policies. See the Vault
plugin configuration policies for more information.
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
<f:entry title="${%Namespace}" field="namespace">
<f:textbox/>
</f:entry>
<f:entry field="usePolicies" title="Limit Token Policies">
<f:checkbox/>
</f:entry>

<st:include page="id-and-description" class="${descriptor.clazz}"/>
</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div>
If checked and policies are defined in the Vault plugin configuration, a child token will be
provisioned after authenticating with Vault with only the configured policies. See the Vault
plugin configuration policies for more information.
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@
<f:entry title="${%Namespace}" field="namespace">
<f:textbox/>
</f:entry>
<f:entry field="usePolicies" title="Limit Token Policies">
<f:checkbox/>
</f:entry>
<st:include page="id-and-description" class="${descriptor.clazz}"/>
</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div>
If checked and policies are defined in the Vault plugin configuration, a child token will be
provisioned after authenticating with Vault with only the configured policies. See the Vault
plugin configuration policies for more information.
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@
<f:entry title="Mount Path">
<f:textbox field="mountPath" name="mountPath" default="${descriptor.defaultPath}"/>
</f:entry>
<f:entry field="usePolicies" title="Limit Token Policies">
<f:checkbox/>
</f:entry>
<st:include page="id-and-description" class="${descriptor.clazz}"/>
</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div>
If checked and policies are defined in the Vault plugin configuration, a child token will be
provisioned after authenticating with Vault with only the configured policies. See the Vault
plugin configuration policies for more information.
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
<f:entry title="${%Namespace}" field="namespace">
<f:textbox/>
</f:entry>
<f:entry field="usePolicies" title="Limit Token Policies">
<f:checkbox/>
</f:entry>

<st:include page="id-and-description" class="${descriptor.clazz}"/>
</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div>
If checked and policies are defined in the Vault plugin configuration, a child token will be
provisioned after authenticating with Vault with only the configured policies. See the Vault
plugin configuration policies for more information.
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ static class ExampleVaultTokenCredentialWithExpiration extends
protected ExampleVaultTokenCredentialWithExpiration(Vault vault) {
super(CredentialsScope.GLOBAL, "id", "description");
this.vault = vault;
this.setUsePolicies(true);
}

@Override
Expand Down

0 comments on commit be7448a

Please sign in to comment.