# Manage Secrets

The `app-config` component needs two secrets: a third-party `API_KEY` and a structured `DB_CONFIG` (JSON) containing database credentials. Atmos manages
these with a dedicated secrets workflow that keeps them out of your stack YAML and — importantly — **out of the `.tfvars` files written to disk**.

In this tutorial the secret backends are the same emulated SSM Parameter Store and Secrets Manager running in your [local sandbox](/quick-start/advanced/start-sandbox),
so you can practice the full secrets workflow with no cloud account.

## Declare the secret stores

Secrets are stored in [stores](/cli/configuration/stores) marked `secret: true`. The example declares two of them in `atmos.yaml`, both authenticating
to the sandbox via the `local-aws` identity:

**File:** `atmos.yaml`

```yaml
stores:
  secrets/ssm:
    kind: aws/ssm           # AWS SSM Parameter Store (SecureString)
    identity: local-aws
    secret: true
    options:
      region: us-east-1
      prefix: /atmos/quickstart/secrets
  secrets/asm:
    kind: aws/asm           # AWS Secrets Manager
    identity: local-aws
    secret: true
    options:
      region: us-east-1
      prefix: /atmos/quickstart/secrets
```

## Declare the secrets on the component

A component declares which secrets it consumes in its `secrets.vars` section. Each entry names the backing store and whether it's required. The
`app-config` catalog declares both secrets:

**File:** `stacks/catalog/app-config/defaults.yaml`

```yaml
components:
  terraform:
    app-config:
      secrets:
        vars:
          API_KEY:
            description: "Third-party API key for the application."
            store: secrets/ssm
            required: true
          DB_CONFIG:
            description: "Structured database credentials (JSON) stored in Secrets Manager."
            store: secrets/asm
            required: true
```

- **`store`**
  Which declared store holds this secret. 
  `API_KEY`
   lives in the emulated SSM Parameter Store (
  `secrets/ssm`
  ); 
  `DB_CONFIG`
   lives in the emulated Secrets Manager (
  `secrets/asm`
  ).
- **`required`**
  When 
  `true`
  , Atmos fails fast if the secret has no value before the component is provisioned, rather than passing an empty value to Terraform.
- **`scope`**
  Optional. When set to 
  `scope: global`
  , a secret is shared across every stack that uses the same store and declaration, instead of being scoped to a single stack+component. The two secrets in this tutorial use the default (per-stack) scope, but 
  `scope: global`
   is useful for credentials that are identical everywhere (for example, a shared read-only token).

## Set secret values

In an interactive terminal, run [`atmos secret`](/cli/commands/secret/usage) and let Atmos guide you through the required secrets for `app-config`:

```shell
atmos secret -s plat-ue2-dev -c app-config
```

You can also set each secret explicitly with [`atmos secret set`](/cli/commands/secret/set). The simplest invocation supplies the value inline as `NAME=VALUE`:

```shell
atmos secret set API_KEY=sk-quickstart-example -s plat-ue2-dev -c app-config
atmos secret set 'DB_CONFIG={"username":"app","password":"s3cr3t"}' -s plat-ue2-dev -c app-config
```

- **`--stack` / `-s`**
  The stack the secret belongs to (e.g. 
  `plat-ue2-dev`
  ).
- **`--component` / `-c`**
  The component whose declaration the secret belongs to (e.g. 
  `app-config`
  ).

:::tip
`atmos secret set` can also read the value from standard input with `--stdin`, or prompt for the value interactively (masked) when you run it without
supplying `NAME=VALUE`. See [atmos secret set](/cli/commands/secret/set).
:::

## Import secrets from a file

To seed many secrets at once — for example from a local `.env` file — use [`atmos secret import`](/cli/commands/secret/import). Each key is routed to
the backend declared for it:

```shell
atmos secret import .env -s plat-ue2-dev -c app-config
```

Add `--dry-run` to preview what would be written without changing any backend.

## List secrets

[`atmos secret list`](/cli/commands/secret/list) shows the declared secrets and whether each has a value, **without decrypting or printing the
values**:

```shell
atmos secret list -s plat-ue2-dev -c app-config
```

## Consume secrets in the stack

Components consume secrets with the [`!secret`](/functions/yaml/secret) YAML function. For the structured secret, you can extract a single field with a
path expression:

**File:** `stacks/catalog/app-config/defaults.yaml`

```yaml
components:
  terraform:
    app-config:
      vars:
        api_key: !secret API_KEY
        db_password: !secret DB_CONFIG | path ".password"
```

## Secrets never touch disk

This is the key property of the workflow: secret values are **delivered to Terraform as `TF_VAR_*` environment variables**, not written into the
generated `.tfvars` file. So `api_key` arrives as `TF_VAR_api_key` and `db_password` as `TF_VAR_db_password`. The Terraform variables that receive them
are declared `sensitive = true`. This means a secret never lands in a plaintext file in the component directory, even though the rest of the component's
variables do.

:::tip
For the full command reference, see the [`atmos secret`](/cli/commands/secret/usage) command group.
:::

---

**Next:** catch mistakes before they reach Terraform → **[Validate Configurations →](/quick-start/advanced/configure-validation)**
