| 1 | --- |
| 2 | title: Doppler |
| 3 | description: Load a Doppler config into your Stack — log in with the browser on your machine, use a service token in CI. |
| 4 | --- |
| 5 | |
| 6 | [Doppler](https://www.doppler.com) organises secrets into projects, |
| 7 | each with configs such as `dev`, `stg`, and `prd`. `Doppler.Secrets` |
| 8 | downloads one config into the stack's |
| 9 | [secret providers](/environments/secret-providers), without writing |
| 10 | anything to `process.env` or to disk. |
| 11 | |
| 12 | ```typescript |
| 13 | import * as Doppler from "alchemy/Doppler"; |
| 14 | |
| 15 | secrets: [ |
| 16 | Doppler.Secrets(({ stage }) => ({ |
| 17 | project: "my-app", |
| 18 | config: stage === "prod" ? "prd" : "dev", |
| 19 | })), |
| 20 | ], |
| 21 | ``` |
| 22 | |
| 23 | Browser login and personal tokens are not scoped to a single config, |
| 24 | so `project` and `config` are required with those. A |
| 25 | [service token](https://docs.doppler.com/docs/service-tokens) is |
| 26 | scoped to one config, so both may be omitted. Doppler's |
| 27 | [branch configs](https://docs.doppler.com/docs/branch-configs) map |
| 28 | neatly onto preview stages if `pr-42` should inherit from `dev`. |
| 29 | |
| 30 | ## Connect your account |
| 31 | |
| 32 | Run `alchemy profile edit --add Doppler`. **Login** opens the Doppler |
| 33 | dashboard; approve the request and the token is stored in your |
| 34 | [profile](/environments/profiles). It shows up in Doppler as |
| 35 | `Alchemy (<your hostname>)`, and |
| 36 | `alchemy profile edit --remove Doppler` revokes it. **API token** |
| 37 | takes a service or |
| 38 | [personal token](https://docs.doppler.com/docs/personal-tokens) you |
| 39 | already have. Non-interactively: |
| 40 | |
| 41 | ```sh |
| 42 | alchemy profile edit --add Doppler --method api-token --set token=env:DOPPLER_TOKEN |
| 43 | ``` |
| 44 | |
| 45 | ## In CI |
| 46 | |
| 47 | Profiles are never consulted in CI; the environment decides. The |
| 48 | simplest is a service token in `DOPPLER_TOKEN`: |
| 49 | |
| 50 | ```yaml |
| 51 | - run: bun alchemy deploy --stage prod --yes |
| 52 | env: |
| 53 | DOPPLER_TOKEN: ${{ secrets.DOPPLER_TOKEN }} |
| 54 | ``` |
| 55 | |
| 56 | On Doppler's Team and Enterprise plans, use OIDC to avoid storing a |
| 57 | long-lived Doppler token. Create a |
| 58 | [service account identity](https://docs.doppler.com/docs/service-account-identities) |
| 59 | that trusts your platform's OIDC issuer and set `DOPPLER_IDENTITY_ID`; |
| 60 | Alchemy exchanges the platform's own identity token for a short-lived |
| 61 | Doppler token on every run: |
| 62 | |
| 63 | ```yaml |
| 64 | jobs: |
| 65 | deploy: |
| 66 | permissions: |
| 67 | id-token: write # lets the job request an OIDC token |
| 68 | contents: read |
| 69 | steps: |
| 70 | - run: bun alchemy deploy --stage prod --yes |
| 71 | env: |
| 72 | DOPPLER_IDENTITY_ID: ${{ vars.DOPPLER_IDENTITY_ID }} |
| 73 | ``` |
| 74 | |
| 75 | Alchemy detects GitHub Actions, Vercel, and supported |
| 76 | Google Cloud runtimes. Each platform must be configured to issue a token |
| 77 | whose issuer, subject, and audience match the Doppler identity's trust policy. |
| 78 | Use your job's actual subject claim when configuring that policy; it can |
| 79 | vary with the repository, branch, environment, and organization settings. |
| 80 | |
| 81 | For GitLab, name the token in the job's |
| 82 | [`id_tokens`](https://docs.gitlab.com/ci/secrets/id_token_authentication/) |
| 83 | block `DOPPLER_OIDC_TOKEN` and set its `aud` to the audience trusted by |
| 84 | Doppler. `SIGSTORE_ID_TOKEN` is also detected when `GITLAB_CI` is set. |
| 85 | On other platforms, `DOPPLER_OIDC_TOKEN` accepts an explicitly supplied token. |
| 86 | |
| 87 | `DOPPLER_OIDC_AUDIENCE` sets the requested audience on GitHub Actions |
| 88 | and Google Cloud. It is required for Google's |
| 89 | [metadata identity endpoint](https://docs.cloud.google.com/docs/authentication/get-id-token). |
| 90 | It does not change the audience of tokens already supplied by Vercel, |
| 91 | GitLab, or `DOPPLER_OIDC_TOKEN`. |
| 92 | |
| 93 | `DOPPLER_TOKEN` wins over `DOPPLER_IDENTITY_ID`, and either wins over |
| 94 | a profile, so a teammate can deploy with a token they were handed. |
| 95 | `alchemy provider check-env` lists these variables. |
| 96 | |
| 97 | ## Where next |
| 98 | |
| 99 | - [Secret providers](/environments/secret-providers) — ordering, mixing sources, and per-stage callbacks. |
| 100 | - [Profiles](/environments/profiles) — where the login lives. |
| 101 | - [Doppler docs](https://docs.doppler.com) — projects, configs, and access control. |