Beyondtrustworkloadcredentials
BeyondTrust Workload Credentials
External Secrets Operator integrates with BeyondTrust Workload Credentials for secret management.
The provider supports static key-value secrets stored in folders. For dynamic secret generation (e.g., temporary AWS credentials), refer to the BeyondTrust Workload Credentials Generator.
For complete BeyondTrust Workload Credentials API documentation, see: https://docs.beyondtrust.com/bt-docs/docs/secrets-api
Example
First, create a SecretStore with a BeyondTrust Workload Credentials backend. You'll need an API token and the server configuration:
apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
name: beyondtrustworkloadcredentials-ss
namespace: external-secrets
spec:
provider:
beyondtrustworkloadcredentials:
auth:
apikey:
token:
name: bts-api-token
key: token
server:
apiUrl: "https://api.beyondtrust.io/site"
siteId: <SITE_ID>
folderPath: <FOLDER_PATH>
Create the API token secret:
kubectl create secret generic api-token \
--from-literal=token=<YOUR_API_TOKEN> \
-n external-secrets
If using self-signed certificates, create a CA bundle secret:
kubectl create secret generic my-ca-bundle \
--from-file=ca.crt="/path/to/root.crt" \
-n external-secrets
Now create an ExternalSecret that uses the above SecretStore:
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: beyondtrustsecret
namespace: external-secrets
spec:
refreshInterval: 1m
refreshPolicy: Periodic
secretStoreRef:
name: beyondtrustworkloadcredentials-ss
kind: SecretStore
target:
name: my-beyondtrust-secret
dataFrom:
- find:
name:
regexp: ".*"
This will automatically create a Kubernetes Secret with the synced data.
Fetching Secret Properties
Single Property Retrieval
You can fetch a specific property from a secret by specifying the property field:
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: postgres-credentials
namespace: external-secrets
spec:
refreshInterval: 1m
secretStoreRef:
name: beyondtrustworkloadcredentials-ss
kind: SecretStore
target:
name: postgres-creds
data:
- secretKey: username
remoteRef:
key: postgresCreds
property: username
- secretKey: password
remoteRef:
key: postgresCreds
property: password
username and password.
Fetching All Properties as JSON
If you omit the property field, you'll get all key-value pairs as a single JSON string:
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: postgres-credentials-json
namespace: external-secrets
spec:
refreshInterval: 1m
secretStoreRef:
name: beyondtrustworkloadcredentials-ss
kind: SecretStore
target:
name: postgres-creds-json
data:
- secretKey: credentials
remoteRef:
key: postgresCreds
This returns: {"username":"user","password":"pass"} as the value of credentials.
Extracting All Properties as Separate Keys
To sync all properties of a secret as individual keys in the target Kubernetes secret, use dataFrom with extract:
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: postgres-credentials-extracted
namespace: external-secrets
spec:
refreshInterval: 1m
secretStoreRef:
name: beyondtrustworkloadcredentials-ss
kind: SecretStore
target:
name: postgres-creds-extracted
dataFrom:
- extract:
key: postgresCreds
This creates a secret with:
data:
username: dXNlcg== # base64("user")
password: cGFzcw== # base64("pass")
Getting Multiple Secrets
You can extract multiple secrets from a folder by using dataFrom.find.
Given a folder eso/static with these secrets:
- anotherSecret: {"someKey": "value1"}
- mySecret: {"myKey": "value2", "someKey": "value3"}
- postgresCreds: {"username": "user", "password": "pass"}
Fetch All Secrets in Folder
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: all-secrets
namespace: external-secrets
spec:
refreshInterval: 1m
secretStoreRef:
name: beyondtrustworkloadcredentials-ss
kind: SecretStore
target:
name: all-folder-secrets
dataFrom:
- find:
name:
regexp: ".*"
This merges all key-value pairs from all secrets in the folder into a single Kubernetes secret.
Regex Pattern Filtering
To sync only secrets matching a specific pattern:
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: filtered-secrets
namespace: external-secrets
spec:
refreshInterval: 1m
secretStoreRef:
name: beyondtrustworkloadcredentials-ss
kind: SecretStore
target:
name: filtered-folder-secrets
dataFrom:
- find:
name:
regexp: "Secret$"
This will only sync secrets whose names end with "Secret" (e.g., anotherSecret, mySecret).
Specifying a Different Folder
By default, find uses the folderPath from the SecretStore. To search a different folder, use the path field:
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: subfolder-secrets
namespace: external-secrets
spec:
refreshInterval: 1m
secretStoreRef:
name: beyondtrustworkloadcredentials-ss
kind: SecretStore
target:
name: subfolder-data
dataFrom:
- find:
path: "eso/production" # Override folder path
name:
regexp: ".*" # Get all secrets in this folder
This will list all secrets in the eso/production folder, regardless of the folderPath configured in the SecretStore.
Note: The path field specifies a folder path, not a path to a specific secret. To fetch a single secret, use data with extract or individual remoteRef entries.
Handling Source Secret Deletion
By default, when a source secret is deleted from BeyondTrust Workload Credentials, the managed Kubernetes secret is retained. You can change this behavior using deletionPolicy:
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: secret-with-deletion
namespace: external-secrets
spec:
refreshInterval: 1m
secretStoreRef:
name: beyondtrustworkloadcredentials-ss
kind: SecretStore
target:
name: managed-secret
deletionPolicy: Delete # Delete the Kubernetes secret when source is removed
data:
- secretKey: myKey
remoteRef:
key: mySecret
Valid values:
- Retain (default): Keep the Kubernetes secret even if the source is deleted
- Delete: Remove the Kubernetes secret when the source is deleted
Authentication
BeyondTrust Workload Credentials uses API key authentication. The API key is stored in a Kubernetes Secret and referenced in the SecretStore:
apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
name: beyondtrustworkloadcredentials-ss
namespace: external-secrets
spec:
provider:
beyondtrustworkloadcredentials:
auth:
apikey:
token:
name: api-token # Name of the Kubernetes Secret
key: token # Key within the Secret
server:
apiUrl: "https://api.beyondtrust.io/site"
siteId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
folderPath: "eso/static"
auth:
apikey:
token:
name: api-token
key: token
Server Configuration
The server configuration consists of:
- apiUrl: The base URL of your BeyondTrust Workload Credentials API
- siteId: Your BeyondTrust site identifier (UUID format)
The provider automatically constructs the full API endpoint as: {apiUrl}/{siteId}/secrets
Certificate Trust
BeyondTrust Workload Credentials typically uses certificates signed by public CAs, requiring no additional configuration.
If using self-signed certificates, configure trust using either caBundle or caProvider:
Using caProvider (Recommended)
spec:
provider:
beyondtrustworkloadcredentials:
# ... other config ...
caProvider:
type: Secret
name: my-ca-bundle
key: ca.crt
namespace: external-secrets # Required for ClusterSecretStore
First create the CA bundle secret:
kubectl create secret generic my-ca-bundle \
--from-file=ca.crt="/path/to/ca.crt" \
-n external-secrets
Using caBundle
Alternatively, embed the base64-encoded PEM certificate directly:
spec:
provider:
beyondtrustworkloadcredentials:
# ... other config ...
server:
apiUrl: "https://api.beyondtrust.io/site"
siteId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
caBundle: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0t..." # base64-encoded PEM
To generate the base64 string:
cat /path/to/ca.crt | base64 -w 0
Folder Path
The folderPath specifies the default folder containing your secrets. This should be a folder path, not the full path to a specific secret.
For example, if your secrets are stored at:
- eso/static/secret1
- eso/static/secret2
- eso/static/secret3
Set folderPath: "eso/static" in your SecretStore.
When using data or dataFrom.extract, secret names are relative to this folder. When using dataFrom.find, this folder is searched by default (unless overridden with the path field).
Refresh Interval
The refreshInterval controls how often the ExternalSecret checks for updates:
spec:
refreshInterval: 5m # Check every 5 minutes
Supported units: s (seconds), m (minutes), h (hours).
Best Practice: Balance between keeping secrets up-to-date and minimizing API calls. For most use cases, 1m to 15m is appropriate.
ClusterSecretStore
To use a ClusterSecretStore (accessible across all namespaces):
apiVersion: external-secrets.io/v1
kind: ClusterSecretStore
metadata:
name: beyondtrustworkloadcredentials-css
spec:
provider:
beyondtrustworkloadcredentials:
auth:
apikey:
token:
name: api-token
key: token
namespace: external-secrets # Required: specify where the token secret lives
server:
apiUrl: "https://api.beyondtrust.io/site"
siteId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
folderPath: "eso/static"
Reference it in an ExternalSecret:
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: my-secret
namespace: my-app
spec:
secretStoreRef:
name: beyondtrustworkloadcredentials-css
kind: ClusterSecretStore # Specify ClusterSecretStore
# ... rest of spec