Pub from CircleCI
CircleCI jobs read and publish your private packages with no stored secret: each job exchanges its own identity token for a Pub token that lasts 15 minutes. How it works on every provider is on Pub from CI.
1. Trust the issuer
Each CircleCI organization has its own issuer, so an Owner adds it first: in CI access, under This organization's own CI issuers, choose CircleCI and enter the organization ID.
2. Bind the repository
In the Control Room, open Organization, then CI access, Bind a repository, and choose CircleCI. The form asks for:
- Project ID: in CircleCI, Project Settings, Overview.
- Organization ID, optional: Organization Settings, Overview. Left out, it is read from the issuer.
- Context ID, optional: a context the job must use (Organization Settings, Contexts). Its security groups then gate every exchange.
- Ref pattern, optional: a branch or a tag: refs/tags/v* or refs/heads/main.
Then grant the binding its packages with its Packages button: read, or read and publish.
3. Exchange in the job
Put your organization id, from the same Organization screen, in DARTASTIC_ORG_ID. This job publishes; for one that only reads, drop dart pub publish and grant the binding read only.
# .circleci/config.yml: publish on a version tag
version: 2.1
jobs:
publish:
docker:
- image: dart:stable
environment:
DARTASTIC_ORG_ID: <your organization id>
steps:
- checkout
- run: apt-get update -qq && apt-get install -y -qq jq
- run:
name: Exchange this job's identity for a 15-minute Pub token
command: |
OIDC=$(circleci run oidc get --aud https://dartastic.io)
RESP=$(curl -sS --fail-with-body -X POST https://api.dartastic.io/v1/ci/exchange \
-H "Authorization: Bearer $OIDC" -H "Content-Type: application/json" \
-d "{\"orgId\":\"$DARTASTIC_ORG_ID\"}") || { echo "$RESP" >&2; exit 1; }
export PUB_TOKEN=$(echo "$RESP" | jq -er .token)
dart pub token add https://pub.dartastic.io --env-var PUB_TOKEN
echo "export PUB_TOKEN=$PUB_TOKEN" >> "$BASH_ENV"
- run: dart pub get
- run: dart pub publish --force
workflows:
release:
jobs:
- publish:
filters:
tags: { only: /^v.*/ }
branches: { ignore: /.*/ }- circleci run oidc get --aud https://dartastic.io gives the job a token for this audience. The tokens CircleCI sets on its own carry your organization ID as their audience, so they are refused.
- A job rerun with SSH is refused: a person at the shell could hold its token. Run it again without SSH.
When it is refused
The job's log shows the reason first, such as TRUSTED PUBLISHER REF MISMATCH. Every reason and what to do is on Pub from CI. CircleCI's own guide to its tokens is in its documentation.