Beyondtrustworkloadcredentials
The BeyondtrustWorkloadCredentialsDynamicSecret Generator provides an interface to BeyondTrust Workload Credentials's
dynamic secret generation capabilities. This enables obtaining temporary, short-lived credentials.
Dynamic secret definitions must be created in BeyondTrust Workload Credentials before they can be referenced by the generator. The generator calls the generation endpoint to produce fresh credentials each time it is invoked.
For complete BeyondTrust Workload Credentials API documentation, see: https://docs.beyondtrust.com/bt-docs/docs/secrets-api
Any authentication method supported by the BeyondTrust Workload Credentials provider can be used here
(provider block of the spec).
Example manifest
apiVersion: generators.external-secrets.io/v1alpha1
kind: BeyondtrustWorkloadCredentialsDynamicSecret
metadata:
name: aws-dynamic-generator
namespace: external-secrets
spec:
provider:
auth:
apikey:
token:
name: bts-api-token
key: token
server:
apiUrl: "https://api.beyondtrust.io/site"
siteId: <SITE_ID>
folderPath: <FOLDER_PATH>
Example ExternalSecret that references the BeyondTrust Workload Credentials generator:
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: app-aws-credentials
namespace: external-secrets
spec:
refreshInterval: 5m
refreshPolicy: Periodic
target:
name: app-aws-credentials
dataFrom:
- sourceRef:
generatorRef:
apiVersion: generators.external-secrets.io/v1alpha1
kind: BeyondtrustWorkloadCredentialsDynamicSecret
name: aws-dynamic-generator
Configuration
Folder Path
The folderPath in the generator spec uses the format {folder}/{secretName}:
- folder: The folder containing the dynamic secret definition (e.g., eso)
- secretName: The name of the dynamic secret definition (e.g., dynamic)
For example, if your dynamic secret is stored at path my/dynamic in BeyondTrust Workload Credentials:
spec:
provider:
folderPath: "my/dynamic"
Generated Secret Fields
The generator returns different fields depending on the type of dynamic secret:
AWS Dynamic Secrets
stringData:
accessKeyId: ASIAIOSFODNN7EXAMPLE
secretAccessKey: wJal...YEKY
sessionToken: IQoJ...Ek8=
leaseId: 84038398-ec0f-417d-9a0f-02494fd7d22c
expiration: 2025-12-29T22:35:29Z
Credential Refresh and Expiration
Important: External Secrets Operator does NOT automatically handle credential expiration/TTL from BeyondTrust Workload Credentials. The refresh is controlled solely by the refreshInterval specified in the ExternalSecret spec.
Setting Refresh Interval
You should set refreshInterval to less than the credential lifetime to ensure credentials are refreshed before expiration:
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: aws-credentials
spec:
refreshInterval: 45m # If credentials expire in 1 hour
target:
name: aws-temp-creds
dataFrom:
- sourceRef:
generatorRef:
apiVersion: generators.external-secrets.io/v1alpha1
kind: BeyondtrustWorkloadCredentialsDynamicSecret
name: beyondtrustworkloadcredentials-ds
What happens if refreshInterval > credential expiration?
Credentials will expire before being refreshed. Users will see:
- ExternalSecret status: SecretSyncError
- Logs/events: Authorization errors when the application tries to use expired credentials
- The application will fail to authenticate with the target service
What happens if refreshInterval << credential expiration?
For example, if credentials expire in 1 hour but refreshInterval: 1m:
- New credentials are generated every minute
- Old credentials remain valid until their expiration time
- Multiple valid credential sets may exist simultaneously
- These credentials expire automatically at their TTL in AWS (for AssumeRole credentials).
Recommendation: Set refreshInterval to 75-80% of the credential lifetime. For example:
- 1-hour credentials → refreshInterval: 45m
- 12-hour credentials → refreshInterval: 9h
- 24-hour credentials → refreshInterval: 18h
Generator Reusability
Generators are reusable Custom Resources. You can reference the same generator from multiple ExternalSecrets:
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: app-1-aws-creds
spec:
refreshInterval: 45m
target:
name: app-1-aws-credentials
dataFrom:
- sourceRef:
generatorRef:
kind: BeyondtrustWorkloadCredentialsDynamicSecret
name: beyondtrustworkloadcredentials-ds
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: app-2-aws-creds
spec:
refreshInterval: 45m
target:
name: app-2-aws-credentials
dataFrom:
- sourceRef:
generatorRef:
kind: BeyondtrustWorkloadCredentialsDynamicSecret
name: beyondtrustworkloadcredentials-ds
Important: Each reference triggers a new credential generation. In the example above, app-1 and app-2 will receive different, independent sets of credentials.
Authentication
The generator uses the same authentication mechanism as the BeyondTrust Workload Credentials provider (API key authentication):
apiVersion: generators.external-secrets.io/v1alpha1
kind: BeyondtrustWorkloadCredentialsDynamicSecret
metadata:
name: beyondtrustworkloadcredentials-ds
namespace: external-secrets
spec:
provider:
auth:
apikey:
token:
name: api-token
key: token
Create the API token secret:
kubectl create secret generic api-token \
--from-literal=token=<YOUR_API_TOKEN> \
-n external-secrets
Certificate Trust
If using self-signed certificates, configure trust using caProvider:
spec:
provider:
# ... other config ...
caProvider:
type: Secret
name: my-ca-bundle
key: ca.crt
Create the CA bundle secret:
kubectl create secret generic my-ca-bundle \
--from-file=ca.crt="/path/to/ca.crt" \
-n external-secrets
Server Configuration
Configure the BeyondTrust Workload Credentials API endpoint:
spec:
provider:
server:
apiUrl: "https://api.beyondtrust.io/site"
siteId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
apiUrl: The base URL of your BeyondTrust Workload Credentials APIsiteId: Your BeyondTrust site identifier (UUID format)
Complete Example
Here's a complete example for AWS dynamic credentials:
-
Create the API token and CA bundle secrets:
kubectl create secret generic api-token \ --from-literal=token=<YOUR_API_TOKEN> \ -n external-secrets kubectl create secret generic my-ca-bundle \ --from-file=ca.crt="/path/to/ca.crt" \ -n external-secrets -
Create the generator:
apiVersion: generators.external-secrets.io/v1alpha1 kind: BeyondtrustWorkloadCredentialsDynamicSecret metadata: name: aws-dynamic-generator namespace: external-secrets spec: provider: auth: apikey: token: name: api-token key: token server: apiUrl: "https://api.beyondtrust.io/site" siteId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890" folderPath: "production/aws-temp" -
Create an ExternalSecret that uses the generator:
apiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: app-aws-credentials namespace: external-secrets spec: refreshInterval: 45m # Refresh before 1-hour expiration target: name: aws-temp-credentials creationPolicy: Owner dataFrom: - sourceRef: generatorRef: apiVersion: generators.external-secrets.io/v1alpha1 kind: BeyondtrustWorkloadCredentialsDynamicSecret name: aws-dynamic-generator -
The resulting Kubernetes secret will contain:
apiVersion: v1 kind: Secret metadata: name: aws-temp-credentials namespace: external-secrets data: accessKeyId: QVNJ...R04= secretAccessKey: Z3dk...WFk= sessionToken: SVFv...Ek8= leaseId: NTdk...Nm1j expiration: MjAy...OVo=
Troubleshooting
Empty Credential Fields
If the generated secret has empty values:
1. Verify the dynamic secret exists in BeyondTrust Workload Credentials at the specified path
2. Check the API token has permissions to generate credentials
3. Verify the folderPath format is correct (folder/secretName)
4. Check controller logs: kubectl logs -l app.kubernetes.io/name=external-secrets -n external-secrets
Authentication Errors
If you see 403/401 errors:
1. Verify the API token is valid and not expired
2. Check the token has generate permissions for the dynamic secret
3. Ensure the caProvider or caBundle is configured correctly if using self-signed certificates
Timeout Errors
If credential generation times out: 1. Check network connectivity from the cluster to BeyondTrust Workload Credentials API 2. Verify the API endpoint is responsive 3. Check if there are firewall rules blocking the connection
Credential Expiration Issues
If applications report authentication failures:
1. Check if refreshInterval is greater than credential lifetime
2. Review the expiration field in the secret to see when credentials expire
3. Adjust refreshInterval to be 75-80% of the credential lifetime
4. Check ExternalSecret status: kubectl describe externalsecret <name> -n <namespace>