chainctl
chainctl Chainguard Control
For the complete documentation index, see llms.txt.
chainctl auth pull-token create returns two values:
chainctl just created. It takes the form ORGANIZATION_ID/TOKEN_ID, where both parts are hexadecimal strings.Every tool that consumes a pull token takes that pair as a username and a password for HTTP basic authentication: the identity ID is the username, and the token is the password. What changes between output formats is only the label.
| Value | Default output | --output=json | --output=env |
|---|---|---|---|
| Identity ID | Username | identity_id | CHAINGUARD_IDENTITY_ID or CHAINGUARD_<ECOSYSTEM>_IDENTITY_ID |
| Token | Password | token | CHAINGUARD_TOKEN or CHAINGUARD_<ECOSYSTEM>_TOKEN |
The Chainguard Console labels the same two values Username and Password when it displays a new access token.
chainctl auth pull-token without a subcommand is equivalent to chainctl auth pull-token create, so the formats described here apply to both.
chainctl auth pull-token create supports two output formats, env and json, plus the default output you get when you pass no --output flag at all.
With no --output flag, chainctl prints instructions for the repository type you asked for.
For --repository=oci, the default, it prints a ready-to-run docker login command:
chainctl auth pull-token createTo use this pull token in another environment, run this command:
docker login "cgr.dev" --username "45a.....764595/095.....68679" --password "eyJhbGciO..........WF0IjoxN"The --username value is the identity ID and the --password value is the token. Both work with any tool that logs in to an OCI registry, including Podman, Helm, and registry mirroring tools. Refer to Authenticate to Chainguard’s Registry for examples.
For every other repository type, chainctl prints the pair as a username and a password:
chainctl auth pull-token create --repository=javaTo use this pull token in another environment, supply the following for Basic authorization:
Username: 45a.....764595/095.....68679
Password: eyJhbGciO..........WF0IjoxN--output=json prints one compact object with an identity_id field and a token field:
chainctl auth pull-token create --repository=java --output=json{"identity_id":"45a.....764595/095.....68679","token":"eyJhbGciO..........WF0IjoxN"}The field names stay the same for every repository type. Pipe the object to jq or another JSON processor to extract either value:
TOKEN_JSON=$(chainctl auth pull-token create --repository=java --output=json)
USERNAME=$(echo "$TOKEN_JSON" | jq -r '.identity_id')
PASSWORD=$(echo "$TOKEN_JSON" | jq -r '.token')--output=env prints two export statements, one per value:
chainctl auth pull-token create --repository=java --output=envexport CHAINGUARD_JAVA_IDENTITY_ID=45a.....764595/095.....68679
export CHAINGUARD_JAVA_TOKEN=eyJhbGciO..........WF0IjoxNWrap the command in eval to run those export statements, which sets both variables in your current session:
eval $(chainctl auth pull-token create --repository=java --output=env)The variable names depend on the repository type. For a library ecosystem, chainctl uppercases the --repository value and inserts it into the name; for oci and apk it uses the unqualified names.
--repository | Identity ID variable | Token variable |
|---|---|---|
oci (default) | CHAINGUARD_IDENTITY_ID | CHAINGUARD_TOKEN |
apk | CHAINGUARD_IDENTITY_ID | CHAINGUARD_TOKEN |
java | CHAINGUARD_JAVA_IDENTITY_ID | CHAINGUARD_JAVA_TOKEN |
javascript | CHAINGUARD_JAVASCRIPT_IDENTITY_ID | CHAINGUARD_JAVASCRIPT_TOKEN |
python | CHAINGUARD_PYTHON_IDENTITY_ID | CHAINGUARD_PYTHON_TOKEN |
Because the ecosystem name is part of the variable, credentials for two ecosystems can coexist in one shell session or one secrets file:
eval $(chainctl auth pull-token create --repository=java --output=env)
eval $(chainctl auth pull-token create --repository=python --output=env)Each invocation creates a new pull token identity. Write the export statements to a file or a secrets manager rather than rerunning the command whenever you need the values again, because chainctl displays the token only once.
chainctl emits variables starting with CHAINGUARD_. However, build tools that read credentials from the environment typically use their own names, and don’t read the CHAINGUARD_* variables directly. In such cases, you must map one to the other explicitly.
For example, uv reads index-scoped credentials from UV_INDEX_<NAME>_USERNAME and UV_INDEX_<NAME>_PASSWORD, where <NAME> is the index name in uppercase, with underscores replacing hyphens. For an index named chainguard:
export UV_INDEX_CHAINGUARD_USERNAME="${CHAINGUARD_PYTHON_IDENTITY_ID}"
export UV_INDEX_CHAINGUARD_PASSWORD="${CHAINGUARD_PYTHON_TOKEN}"The same pattern applies wherever a tool defines its own variable, such as the HTTP_AUTH variable used for private APK repositories:
export HTTP_AUTH="basic::${CHAINGUARD_IDENTITY_ID}:${CHAINGUARD_TOKEN}"Names you choose yourself, such as GitHub Actions secrets, are also independent of the CHAINGUARD_* convention. Whatever you call them, the identity ID is the username and the token is the password.
--output help text lists more formats
If you pass any other value, chainctl prints a warning to standard error, then falls back to default output. Requesting csv, for example, produces a warning along these lines:
"csv" is not a supported output. Supported: [ env json]. Using print to command lineEven when a command returns this warning, it still creates the pull token. It refuses only the formatting request, so a script that expects machine-readable output on standard output receives prose instead. This matters most for eval: eval $(chainctl auth pull-token --output=csv) creates a token, sends the warning to your terminal, and then tries to run the human-readable text as shell commands.
The --output flag is global, so chainctl --help and every reference page describe it the same way:
-o, --output string Output format. One of: [csv, env, go-template, id, json, markdown, none, table, terse, tree, wide]That list is the union of every format any chainctl command supports, not a list of formats that all commands support. Each command declares its own subset. Table-shaped commands such as chainctl iam identities list accept csv and markdown; pull-token create returns a single credential pair and accepts only env and json.
Last updated: 2026-09-03 00:00