Important Announcement!

This deprecated version of TLS Protect for Kubernetes, originally known as Jetstack Secure, will be PERMANENTLY SHUTDOWN on May 19, 2025. If you're still using this version, please work with your CyberArk/Venafi account team to transition to the current version of TLS Protect for Kubernetes.

Configure venafi-oauth-helper

Create a Bootstrap Secret

venafi-oauth-helper can be bootstrapped using refresh-token, username-password, or client-certificate credentials.

For an Issuer the bootstrap Secret must be in the same namespace as the Issuer.

For a ClusterIssuer the bootstrap Secret must be in the --cluster-resource-namespace. By default this is the same namespace as the venafi-oauth-helper Pod (cert-manager) but it may be different if you have installed venafi-oauth-helper in a different namespace, of if you have changed the --cluster-resource-namespace command line option.

...using a refresh-token

This is the most secure bootstrap method because you will not have to store the username-password or client-certificate in a Secret in the Kubernetes cluster. These sensitive credentials can be stored outside the cluster and need only be accessed when deploying the venafi-oauth-helper.

The disadvantage of this configuration is that if the refresh-token reaches its time limit, or if a new refresh-token is not successfully saved after rotation, or if the refresh-token is revoked, then the venafi-oauth-helper will cease to function until a new refresh-token is generated and saved to the Kubernetes Secret by an administrator.

⚠️ The refresh-token has a fixed expiry time. The expiry time of each rotated refresh-token will be the same as the initial bootstrap refresh-token from which they are derived. So you will need to use your username-password or client-certificate to generate a new bootstrap refresh-token before the current refresh-token expires. You should automate this if possible.

⚠️ The access-token / refresh-token may be revoked at any time by the TPP administrator, which will cause venafi-oauth-helper to stop renewing access-tokens, if using the refresh-token bootstrap method. So you should setup an alert which fires when venafi-oauth-helper logs the error: {"level":"error", "msg":"Giving up",...}, and have a process for generating a new bootstrap refresh-token, which will fix the error.

Create the refresh-token

If you do not have credentials to the Venafi Platform, your Venafi administrator will need to run this command :

vcert getcred --username REPLACE_WITH_VENAFI_TPP_USER \
--password REPLACE_WITH_VENAFI_TPP_PASSWORD \
-u https://REPLACE_WITH_VENAFI_TPP_HOSTNAME/vedsdk \
--client-id cert-manager.io \
--scope "certificate:manage,revoke" \
--format json > /tmp/token
Copy to clipboard

⚠️ The client-id in the command above MUST match the client-id used by venafi-oauth-helper, and MUST match the Application ID created in the Common Configuration section above. The default client-id is cert-manager.io but you can change it using the command line option: --client-id.

🔰 To know more about the OAuth tokens in TPP, see Obtaining an Authorization Token in the VCert documentation.

Save the refresh-token to a Kubernetes Secret

In this step, we will create a bootstrap secret using the refresh-token that we retrieved in the previous step.

ℹ️ The refresh token is retrieved from the /tmp/token using jq. If jq doesn't work on your machine, no worries, just replace $(jq -r .refresh_token < /tmp/token) with the actual refresh-token retrieved in previous step.

kubectl apply -f- <<EOF
apiVersion: v1
kind: Secret
metadata:
name: issuer-1-credentials-voh-bootstrap
namespace: ISSUER_NAMESPACE # ⚠ or CLUSTER_RESOURCE_NAMESPACE when using a ClusterIssuer
stringData:
refresh-token: $(jq -r .refresh_token < /tmp/token)
refresh-token-expires: $(jq -r ".refresh_until|todate" < /tmp/token)
EOF
Copy to clipboard

...using a username-password

Alternatively you can create a bootstrap secret containing a username-password, and the advantage of this is that venafi-oauth-helper can always request a new refresh-token, even if the last live refresh-token becomes invalid.

This is less secure because your username-password, which has greater privileges than a refresh-token, are now stored in the Kubernetes Cluster and therefore more exposed to accidental leakage and malicious use.

Update the username-password and apply the YAML:

kubectl apply -f- <<EOF
apiVersion: v1
kind: Secret
metadata:
name: issuer-1-credentials-voh-bootstrap
namespace: ISSUER_NAMESPACE # ⚠ or CLUSTER_RESOURCE_NAMESPACE when using a ClusterIssuer
stringData:
username: REPLACE_WITH_VENAFI_TPP_USER
password: REPLACE_WITH_VENAFI_TPP_PASSWORD
EOF
Copy to clipboard

...using a client-certificate

In this configuration, you store a client-certificate in the bootstrap credentials Secret.

This is less secure, because your client-certificate, which may have greater privileges than a refresh-token, is now stored in the Kubernetes Cluster and therefore more exposed to accidental leakage and malicious use.

kubectl create secret generic \
issuer-1-credentials-voh-bootstrap \
--namespace=ISSUER_NAMESPACE \ # ⚠ or CLUSTER_RESOURCE_NAMESPACE when using a ClusterIssuer
--from-file=p12-archive='/path/to/pfx/file.pfx' \
--from-literal=p12-password='PFX_DECRYPTION_PASSWORD'
Copy to clipboard

Annotate the Bootstrap Secret

Annotate the Secret so that venafi-oauth-helper can match the bootstrap Secret to your Issuer:

kubectl annotate secret issuer-1-credentials-voh-bootstrap \
voh.jetstack.io/issuer=issuer-1 \
--namespace=<NAMESPACE OF YOUR ISSUER RESOURCE>
Copy to clipboard

⚠ For a ClusterIssuer use the annotation voh.jetstack.io/cluster-issuer.

venafi-oauth-helper will immediately use this bootstrap credential to get an access-token and a new live refresh-token and these will be stored to separate Secret resources. Thereafter, the live refresh-token will be used to renew the access-token. If the live refresh-token fails, then venafi-oauth-helper will automatically try using the bootstrap credential again to generate a new refresh-token, but this will only work if you use a username-password or a client-certificate for the bootstrap credential.

⚠ Remember that a refresh-token can only be used once, so if you used a refresh-token as the bootstrap credential, TPP will have invalidated after it was first used. If the live refresh-token stops working you will need to manually create a new refresh-token and save it to the bootstrap credential Secret.

Next Steps

On this page