Skip to main content

!secret

The !secret YAML function resolves a declared secret from its configured backend (a secret: true store such as AWS SSM, AWS Secrets Manager, HashiCorp Vault, Azure Key Vault, or GCP Secret Manager, or a SOPS-encrypted file) and substitutes its value into an Atmos stack manifest. Resolved values are automatically registered with the I/O masker, so they are redacted in all output.

Usage

  !secret <NAME> | path <yq-expression> | default <default-value>

The secret <NAME> must be declared under the component's secrets.vars before it can be referenced — this keeps the registry of secrets GitOps-friendly and explicit.

Usage examples:

  # Resolve a declared secret
vars:
api_key: !secret DATADOG_API_KEY

# Provide a default when the secret is missing
vars:
api_key: !secret DATADOG_API_KEY | default "dev-key"

# Extract a nested value from a structured (JSON) secret
vars:
db_host: !secret DATABASE_CONFIG | path ".host"
db_password: !secret DATABASE_CONFIG | path ".credentials.password"

# Combine path and default
vars:
db_host: !secret DATABASE_CONFIG | path ".host" | default "localhost"

Declaration

A secret must be declared before use. Declarations live in stack/component config and reference a backend by name:

stacks/prod/api.yaml
components:
terraform:
api:
secrets:
vars:
DATADOG_API_KEY:
description: "Datadog API key for monitoring"
store: app-secrets # a `secret: true` store (track 1)
required: true
GITHUB_APP_KEY:
sops: dev-sops # a SOPS provider (track 2)
vars:
datadog_api_key: !secret DATADOG_API_KEY

The backend (store: or sops:) carries the provider, region, prefix, and optional auth identity, so the declaration stays terse. See Secrets configuration for backend setup.

Masking and Inspection

!secret is automatically masked everywhere its value appears. In inspection commands — atmos describe and the atmos list family — !secret resolves to <MASKED> without contacting the backend when masking is enabled (the default). This means you can inspect a stack's shape with no cloud credentials:

# No credentials needed — the secret renders as <MASKED>
atmos describe component api --stack=prod

# Reveal the real value (requires access to the secret backend)
atmos describe component api --stack=prod --mask=false

In value-producing commands (terraform plan/apply, atmos secret get), the value is always retrieved because it is needed to function; --mask only controls whether it is redacted in display output.

Access Rule

!secret is the only accessor for a secret: true store. Using !store against a secret: true store is an error — this makes declarations mandatory-by-construction for secrets and removes any ambiguity about whether a value is sensitive.

See Also