Use secrets in a pipeline
Store credentials as encrypted, write-only secrets and reference them from commands and env values.
Store tokens, API keys and store credentials as secrets instead of pipeline
env values. Oore encrypts each value with the instance encryption key, never
returns it from the API, and masks it as *** in build logs.
What you need
- Project developer, maintainer, instance admin, or instance owner access for project and pipeline secrets.
- Instance admin or owner access for instance secrets.
Scopes
A secret belongs to one scope. A build sees the secrets of its pipeline, its project and the instance. When two scopes define the same name, the narrower scope wins: pipeline over project, project over instance.
| Scope | API base | Who can write |
|---|---|---|
| Instance | /v1/secrets | Instance admin or owner |
| Project | /v1/projects/{project_id}/secrets | Project developer or above |
| Pipeline | /v1/pipelines/{pipeline_id}/secrets | Project developer or above |
Listing returns names and timestamps only. Anyone who can read the project can see which names exist; nobody can read a value back, including the person who wrote it.
1. Create a secret
Add the secret in the scope that matches who should use it:
- For every pipeline on the instance, open Settings > Secrets.
- For every pipeline in one project, open the project’s Settings tab.
- For one pipeline, open the pipeline’s Secrets tab.
Select Add secret, enter the Name and Value, and save. To change a value later, use Replace value. The next build uses the new value. Builds already running keep the old one.
Names follow environment variable rules ([A-Za-z_][A-Za-z0-9_]*, at most 128
characters). Values can be up to 64 KiB, which fits a Google Play service
account JSON file.
From the API, send the secret to the scope’s base path:
curl -X POST "$OORE_URL/v1/projects/$PROJECT_ID/secrets" \
-H "Authorization: Bearer $OORE_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"name": "SENTRY_AUTH_TOKEN", "value": "sntrys_..."}'To rotate, send PUT .../secrets/{name} with {"value": "..."}. To remove,
send DELETE .../secrets/{name}. Each change is written to the audit log.
Deleting a secret that a pipeline uses as its Google Play service account
returns 409 secret_in_use and names those pipelines. Point them at another
secret first, or add ?force=true to delete it anyway. A pipeline that would
fall back to a secret of the same name in a wider scope, such as an instance
PLAY_SERVICE_ACCOUNT, does not block the delete.
2. Reference it
Use ${{ secrets.NAME }} in an env value or in any command:
env:
- key: SENTRY_AUTH_TOKEN
value: ${{ secrets.SENTRY_AUTH_TOKEN }}
commands:
post_build:
- ./scripts/upload-symbols.sh --token "${{ secrets.SENTRY_AUTH_TOKEN }}"- In an
envvalue, the reference is replaced with the secret value before the step starts. - In a command, the reference becomes the shell variable
${OORE_SECRET_NAME}, which the runner sets for that build. Quote it as you would any shell variable. The value is never pasted into the command text. - Env values that come from a secret are left out of the
--dart-define-from-filefile, so they are not compiled into the app. Pass one explicitly with--dart-defineif the app really needs it. - Only
${{ secrets.NAME }}is supported inside${{ }}. Any other expression, or a reference to a secret that does not exist in any visible scope, fails the build before a step runs.
Verify the result
Any line a step prints that contains a secret value shows *** in its place.
For multi-line values such as JSON keys, each longer line of the value is
masked as well. Masking matches exact text, so a value that a step transforms
(for example, base64-encodes) is not recognised; avoid printing derived forms.
Run a build that uses the secret. The step that reads it succeeds, and the
log shows *** wherever the value would appear.
Troubleshooting
The build fails before its first step with an unknown secret
No visible scope defines that name. Check the spelling, and add the secret to the pipeline, its project, or the instance.
The value appears in the log
The step printed a transformed form of the value, such as base64. Masking matches exact text only. Stop printing the value, then rotate it.
Next step
Set triggers, timeouts, and approvals for the pipeline.