Share secrets and configuration across CI pipelines by giving each value one stable name, storing it once in Depot CI, and adding scoped variants only where the value needs to differ.
For example, every workflow can use the same expression:
env:
API_BASE_URL: ${{ vars.API_BASE_URL }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}Depot selects the matching value for the repository, branch, workflow file, and job environment before the workflow starts. The YAML doesn't need a copy of every environment-specific credential.
Use secrets for credentials and variables for configuration
Depot CI secrets are encrypted, decrypted on demand, sent to the isolated job sandbox, and masked in logs. Their values can't be read back after creation.
Variables are plain text. Their values are visible in the dashboard and CLI output. Use them for configuration that's not sensitive, such as service names, regions, feature modes, and public endpoints.
Don't put a credential in a variable because it's convenient to inspect. Don't put ordinary configuration in a secret if engineers need to audit or compare it.
Organization owners can manage secrets and variables in the Depot dashboard. Existing GitHub Actions values can be imported with:
depot ci migrate secrets-and-varsThat command creates a one-shot GitHub Actions workflow to import the values. It's a migration mechanism, not a continuous synchronization path.
Start with a fallback, then add variants
Create an unscoped fallback only when the value is safe and correct for every matching job. Add variants for narrower contexts.
A common DATABASE_URL setup is:
- Default variant for development or test jobs
- Repository variant for a service with its own database
- Branch variant for a release branch
- Environment variant for staging or production
Every workflow still reads ${{ secrets.DATABASE_URL }}. Depot resolves the value from least to most specific.
When more than one variant matches, attribute priority is:
- Environment
- Repository
- Branch
- Workflow
- No attributes
Combining different attribute types makes a variant more specific. A variant scoped to both repository=api and
environment=production beats a variant scoped only to environment=production.
Within branch or workflow patterns, a narrow match beats a broad match. release/v2 is more specific than
release/*.
Select environment values explicitly
An environment-scoped variant matches the job's environment field:
jobs:
deploy:
runs-on: depot-ubuntu-24.04
environment: production
steps:
- uses: actions/checkout@v4
- run: ./scripts/deploy.sh
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
API_BASE_URL: ${{ vars.API_BASE_URL }}A job without environment: production can't receive a variant limited to that environment, even if it runs on the
default branch or lives in the deployment workflow.
The environment field selects the matching Depot secret and variable variants. It doesn't, by itself, create a
human approval gate. Keep deployment approval in the system that owns the release policy, or use a separately
dispatched deployment workflow.
Limit credentials to the job that needs them
Scope a production credential across more than one dimension when possible:
- Repository: only the service that deploys
- Branch: only
mainorrelease/* - Workflow: only
deploy.yml - Environment: only
production
This prevents a pull request workflow from receiving the credential simply because it uses the same secret name.
Also keep workflow token permissions narrow:
permissions:
contents: readAdd write scopes only to the job that needs them. Don't give validation jobs release, package, or infrastructure credentials.
Know the built-in token exceptions
Depot CI injects a short-lived DEPOT_TOKEN into every job. It has access to the organization's Depot projects and
registry for that job. You don't need to store another Depot token for ordinary container builds or Depot Registry
pushes.
If you create your own DEPOT_TOKEN secret, it overrides the injected token. A migrated project token may be scoped to
one container-build project and fail when the workflow tries to access another registry repository. Remove the custom
secret when the built-in token is the correct identity.
The built-in job token can't dispatch another Depot CI workflow. Store an organization or user token under a
different name, such as DEPOT_ORG_TOKEN, when a workflow must call depot ci dispatch.
Depot CI also exposes secrets.GITHUB_TOKEN as a GitHub App token. GitHub Packages doesn't accept GitHub App tokens
for package authentication. Use Depot Registry, another package registry, or a separately managed GitHub personal
access token if a job must push to or pull from GitHub Packages.
Verify resolution before running production
Use the filters in Depot CI settings to select a repository, branch, workflow, and environment. The dashboard shows which variant wins and greys out the other matches.
Check that resolution whenever you add a broad glob or a more specific variant. The safest secret system is still
dangerous if production resolves to the test credential or a pull request job unexpectedly matches a release branch.
Keep the names stable, keep the values out of YAML, and make the scope narrow enough that the wrong job can't receive them.