| 1 | --- |
| 2 | title: Infisical |
| 3 | description: Load an Infisical environment into your Stack — a machine identity on your machine, the platform's own OIDC token in CI. |
| 4 | --- |
| 5 | |
| 6 | [Infisical](https://infisical.com) keeps secrets in projects, split |
| 7 | into environments with folders inside each. `Infisical.Secrets` |
| 8 | downloads one folder, with |
| 9 | [secret references](https://infisical.com/docs/documentation/platform/secret-reference) |
| 10 | expanded on the server, into the stack's |
| 11 | [secret providers](/environments/secret-providers). It works exactly |
| 12 | like [Doppler](/environments/doppler); this page covers only what |
| 13 | differs. |
| 14 | |
| 15 | ```typescript |
| 16 | import * as Infisical from "alchemy/Infisical"; |
| 17 | |
| 18 | secrets: [ |
| 19 | Infisical.Secrets(({ stage }) => ({ |
| 20 | project: "my-app", |
| 21 | environment: stage === "prod" ? "prod" : "dev", |
| 22 | path: "/api", |
| 23 | })), |
| 24 | ], |
| 25 | ``` |
| 26 | |
| 27 | `project` is the project's slug, or its id with a user token, since |
| 28 | Infisical only resolves slugs for machine identities. `environment` |
| 29 | is the environment slug. Optional `path`, `recursive`, and |
| 30 | `includeImports` narrow or widen what is read; imports are on by |
| 31 | default and a secret defined directly in the folder wins over an |
| 32 | imported one. |
| 33 | |
| 34 | ## Connect your account |
| 35 | |
| 36 | Alchemy authenticates with an Infisical machine identity or user token. Create a |
| 37 | [machine identity](https://infisical.com/docs/documentation/platform/identities/machine-identities) |
| 38 | for yourself with |
| 39 | [Universal Auth](https://infisical.com/docs/documentation/platform/identities/universal-auth), |
| 40 | read access to your dev project, and a client secret. |
| 41 | Then run `alchemy profile edit --add Infisical` and choose |
| 42 | **Machine identity**; every command afterwards exchanges it for a |
| 43 | fresh access token. The client secret remains subject to its configured |
| 44 | expiry and use limits. **User token** takes the ten-day token |
| 45 | from the dashboard's account menu instead. Both accept an API URL for |
| 46 | the [EU cloud](https://eu.infisical.com) or a self-hosted instance. |
| 47 | |
| 48 | ```sh |
| 49 | alchemy profile edit --add Infisical --method universal-auth \ |
| 50 | --set clientId=env:INFISICAL_CLIENT_ID \ |
| 51 | --set clientSecret=env:INFISICAL_CLIENT_SECRET |
| 52 | ``` |
| 53 | |
| 54 | ## In CI |
| 55 | |
| 56 | Set `INFISICAL_TOKEN` to a ready access token, or `INFISICAL_IDENTITY_ID` |
| 57 | to a machine identity whose |
| 58 | [OIDC auth](https://infisical.com/docs/documentation/platform/identities/oidc-auth/general) |
| 59 | trusts your platform: |
| 60 | |
| 61 | ```yaml |
| 62 | jobs: |
| 63 | deploy: |
| 64 | permissions: |
| 65 | id-token: write # lets the job request an OIDC token |
| 66 | contents: read |
| 67 | steps: |
| 68 | - run: bun alchemy deploy --stage prod --yes |
| 69 | env: |
| 70 | INFISICAL_IDENTITY_ID: ${{ vars.INFISICAL_IDENTITY_ID }} |
| 71 | ``` |
| 72 | |
| 73 | Platform detection, precedence, and the `INFISICAL_OIDC_TOKEN` and |
| 74 | `INFISICAL_OIDC_AUDIENCE` overrides match |
| 75 | [Doppler's](/environments/doppler#in-ci). `INFISICAL_API_URL` selects |
| 76 | the EU cloud or a self-hosted instance in either mode. |
| 77 | |
| 78 | ## Where next |
| 79 | |
| 80 | - [Secret providers](/environments/secret-providers) — ordering, mixing sources, and per-stage callbacks. |
| 81 | - [Profiles](/environments/profiles) — where the machine identity lives. |
| 82 | - [Infisical docs](https://infisical.com/docs) — projects, environments, and access policies. |