GitLab CI
Exchange your GitLab CI id token for a fifteen-minute credential from us and run one job step with the values.
Your job exchanges a GitLab-signed id token for a credential we mint, bound to one project and one environment. See machine identity and values in a CI build.
Trust a GitLab project
Open Machine Identities then Connect a Platform and pick GitLab CI. We build the subject
from your project path, branch, host and ref type, for example
project_path:acme/api:ref_type:branch:ref:main. The GitLab CI trust
reference lists every field and default.
| Constraint | Detail |
|---|---|
| Subject match | Exact, no wildcards. A tag job (ref_type:tag) or a second branch needs its own trust |
| Self-managed GitLab | Must be reachable from the internet; we read signing keys from the issuer's origin |
| Audience | Your workspace id, shown in the console |
Run penv in the job
deploy:
id_tokens:
ID_TOKEN:
aud: YOUR_WORKSPACE_ID
script:
- curl -fsSL https://penv.cloud/install | sh
- export PATH="$HOME/.penv/bin:$PATH"
- penv run -- npm run deployid_tokens is GitLab's
id token mechanism.
penv run exchanges the token itself and passes values to the child process only.
penv looks for a credential in this order:
| Order | Source |
|---|---|
| 1 | PENV_TOKEN |
| 2 | A login in the OS keychain (absent on a runner) |
| 3 | An enrolled keypair |
| 4 | A platform token: GitHub Actions' ACTIONS_ID_TOKEN_REQUEST_URL, then ID_TOKEN, then PENV_OIDC_TOKEN |
| 5 | AWS credentials; see AWS workload |
A runner has no keychain, so every run is online and nothing is cached on disk.
Exchange explicitly
Name the id token PENV_OIDC_TOKEN and penv run reads it too. For any other name, exchange it
yourself:
deploy:
id_tokens:
PENV_ID_TOKEN:
aud: YOUR_WORKSPACE_ID
script:
- |
C=$(T="$PENV_ID_TOKEN" jq -n '{token:env.T}' | curl -sS "https://penv.cloud/api/v1/auth/oidc" \
-H 'content-type: application/json' --data-binary @- | jq -r .credential)
PENV_TOKEN="$C" penv run -- npm run deployThe console prints a pull-secrets job of this shape that ends in PENV_TOKEN="$C" penv pull,
writing a .env for your later jobs. penv pull is for a host that needs a file;
penv run keeps values off disk. Copy the audience from the Connect page either way.
Credential scope
- Your trust holds no secret.
- The credential is bound to one project and one environment.
- Fifteen minutes is a ceiling: a credential never outlives the trust's expiry.
Troubleshooting
| Answer | Meaning |
|---|---|
401 unauthorized | The token's subject is not your trust's. Check the branch and project path |
401 expired | The trust's expiry has passed. Reissue it in the console |
403 forbidden | The credential is bound to another environment |
503 unavailable | We could not read the GitLab signing keys. Retry once |
All codes: our API answers.