> ## Documentation Index
> Fetch the complete documentation index at: https://biznetgio.creations.ren/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage secrets the right way

> Keep API tokens and credentials out of git and safe in CI

The [Authentication](/authentication) page already covers what these providers do for you: `api_key`/`apiToken` are marked sensitive, and every `raw` output is redacted. This tutorial is about the layer above that, keeping the token itself out of git and getting it safely into CI, since that layer is entirely on you.

## Rule one: never commit a real token

* Export it as an environment variable (`BIZNETGIO_API_KEY`) instead of writing it into a committed file.
* Never pass it with `-var` on the Terraform CLI; command-line arguments end up in your shell history.
* Gitignore any `tfvars` file that ever holds a real value, per the [project structure](/tutorials/project-structure) tutorial.

## Terraform Cloud variables

If you followed the [state and collaboration](/tutorials/state-and-collaboration) tutorial's recommended path, set the token as a workspace variable: category "environment variable", key `BIZNETGIO_API_KEY`, and tick the sensitive checkbox. It's injected into every plan and apply run and never appears in logs.

## Pulumi config and ESC

`pulumi config set --secret` encrypts the value before writing it to `Pulumi.<stack>.yaml`:

```bash theme={null}
pulumi config set --secret biznetgio:apiToken <your-token>
```

By default the value is encrypted with a key managed by Pulumi Cloud; anyone with access to that stack in your Pulumi Cloud organization can decrypt it through the CLI. If you're self-hosting state with a passphrase instead (see the previous tutorial), you distribute that passphrase yourself, and losing it means losing the ability to read secrets back out, though the stack still updates fine without it.

For one token shared across multiple stacks or projects, **Pulumi ESC** (Environments, Secrets, and Configuration) centralizes it:

```bash theme={null}
esc env set biznetgio/production biznetgio:apiToken <your-token> --secret
```

Then reference it from `Pulumi.yaml` instead of repeating `config set` per stack:

```yaml theme={null}
environment:
  - biznetgio/production
```

## GitHub Actions secrets

Store the token as a repository secret, or better, an **environment secret** scoped to a named environment (for example `production`) with required reviewers turned on. That's what gates the [CI/CD tutorial](/tutorials/cicd)'s apply/up job behind a human approval, since the secret itself is only available once the environment's protection rules pass.

```yaml theme={null}
env:
  BIZNETGIO_API_KEY: ${{ secrets.BIZNETGIO_API_KEY }}
```

## Rotating a leaked token

1. Generate a new one in the [portal](https://portal.biznetgio.com) (see [Authentication](/authentication)); the old one stops working immediately.
2. Update every place the old value was stored: the CI secret, the Pulumi ESC environment, the Terraform Cloud variable.
3. Re-run a plan/preview to confirm the new token authenticates before merging anything.

## There's no scoped token

The [Authentication](/authentication) page's warning applies directly here: the API token grants full control of the account, and there's no read-only or scoped variant. That means giving a CI pipeline access to it is equivalent to giving that pipeline full account access. Gate who can trigger the pipeline that has it (branch protection, required reviewers on the production environment) as carefully as you'd gate who has the token itself.

## Next steps

* [CI/CD with GitHub Actions](/tutorials/cicd) - put this token to work in an actual pipeline
