Configuration
Secrets
Argus can resolve its secrets (registry credentials and the GitLab token) from a secret manager instead of plain environment variables. AWS Secrets Manager is supported today, through a provider model built to take more clouds.
Overview
Anywhere Argus reads a secret (a registry username/password in config.yml, or the GITLAB_PRIVATE_TOKEN), the value may be a $${{...}} reference. A reference is resolved at startup to its plaintext value; a plain value is used as-is. The same three reference forms work in both config.yml and environment variables, and secret values are never logged.
Reference syntax
$${{ENV_VAR}}reads from the environment (the original behaviour, unchanged).$${{secret:<key>}}reads<key>from the configured secret bundle. Provider-neutral: the reference looks identical whichever cloud backs it.$${{aws-secretsmanager:<secret-id>#<json-key>}}reads a specific key from a specific secret.
Secret-manager secrets are JSON documents, so the #<json-key> (and the bundle key) selects a field from the JSON. An unknown scheme is a hard error that lists the schemes Argus knows, so a typo never silently falls through to a literal.
AWS Secrets Manager
On EKS, Argus uses the pod’s IAM identity (IRSA / Pod Identity) via the standard AWS credential chain: no keys in the environment. If ARGUS_AWS_ROLE_ARN is set, Argus assumes that role (via STS) on top of the ambient identity, which covers cross-account setups. Region comes from AWS_REGION/AWS_DEFAULT_REGION. The AWS client is built lazily, so projects that use no AWS references never initialise it.
version: 3
registries:
internal-artifactory:
url: https://artifactory.example.internal/artifactory/all-repos
username: ${{secret:artifactory-username}}
password: ${{secret:artifactory-password}}
replaces-base: true# The role to assume (optional; omit to use the pod's IRSA identity directly)
ARGUS_AWS_ROLE_ARN=arn:aws:iam::123456789012:role/argus-secrets-reader
# The one JSON secret that holds Argus' secrets, backing ${{secret:KEY}}
ARGUS_AWS_SECRET_ARN=arn:aws:secretsmanager:eu-west-1:123456789012:secret:argus/secrets
# Standard AWS settings are honoured
AWS_REGION=eu-west-1
# The GitLab token can itself come from the bundle:
GITLAB_PRIVATE_TOKEN=${{secret:gitlab-token}}AWS setup walkthrough
A complete EKS setup is three steps: store the secret, grant read access, and let the Argus pod assume an identity that holds it. The example uses one JSON bundle secret and IRSA; adapt the names to your account.
1. Create the secret
Store Argus’ secrets as a single JSON document in AWS Secrets Manager:
aws secretsmanager create-secret \
--name argus/secrets \
--description "Secrets read by Argus" \
--secret-string '{
"gitlab-token": "glpat-xxxxxxxxxxxxxxxxxxxx",
"artifactory-username": "svc-argus",
"artifactory-password": "ory-xxxxxxxx"
}'
# Note the returned ARN and set it as ARGUS_AWS_SECRET_ARN.
# Rotate later with: aws secretsmanager put-secret-value --secret-id argus/secrets --secret-string '{...}'2. Grant read access
Create a least-privilege IAM policy that allows reading only Argus’ secrets. Scope the resource to your secret’s ARN prefix:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ArgusReadSecrets",
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "arn:aws:secretsmanager:eu-west-1:123456789012:secret:argus/*"
}
]
}3. Wire the pod identity
Give the Argus job’s pod an identity that carries the policy, using IAM Roles for Service Accounts (IRSA) or EKS Pod Identity. No access keys ever enter the environment.
# IRSA: bind a Kubernetes service account to the IAM role, then run Argus under it.
eksctl create iamserviceaccount \
--cluster my-cluster --namespace ci --name argus \
--attach-policy-arn arn:aws:iam::123456789012:policy/argus-secrets-read \
--approve
# The service account is annotated with the role; the SDK picks it up automatically:
# eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/argus-secrets-reader
# Run the Argus job's pod with serviceAccountName: argus (no keys in the environment).The secret bundle
Rather than naming a secret in every reference, point Argus at one JSON secret that holds all of its secrets and reference the keys by name. Set ARGUS_AWS_SECRET_ARN to that secret’s ARN, store a JSON object like {"gitlab-token": "…", "artifactory-password": "…"}, and reference each value as $${{secret:<key>}}. The bundle is fetched once per run. This is the recommended setup: a single role and a single secret ARN, then short references everywhere.
The GitLab token
GITLAB_PRIVATE_TOKEN is resolved through the same mechanism, so it can be a reference: GITLAB_PRIVATE_TOKEN=$${{secret:gitlab-token}} pulls it from the bundle, or $${{aws-secretsmanager:argus/gitlab#token}} from a specific secret. A plain token value still works unchanged, and the CI_JOB_TOKEN upload fallback is preserved.
Providers
Secret resolution is built on a small provider interface, so support for more clouds can be added without changing the reference syntax or your configuration.
| Provider | Scheme | Status |
|---|---|---|
| Environment | $${{ENV_VAR}} | Built in |
| AWS Secrets Manager | aws-secretsmanager | Supported |
| GCP Secret Manager | gcp-secretmanager | Planned |
| Azure Key Vault | azure-keyvault | Planned |
| HashiCorp Vault | vault | Planned |
The design rationale and the extension contract are recorded in ADR-021. When a new provider lands, the $${{secret:<key>}} references in your config stay exactly the same.
Further reading
- AWS Secrets Manager User Guide
- Create and manage a secret · Rotate secrets
- EKS: IAM Roles for Service Accounts (IRSA)
- EKS: Pod Identity
- Secrets Manager IAM policy examples
- STS AssumeRole (for
ARGUS_AWS_ROLE_ARN/ cross-account) - AWS SDKs: service-specific endpoints (
AWS_ENDPOINT_URL, used for local testing)