Access tokens and CI
An access token lets a CI pipeline or a tool outside Kupe use the registry. Choose pull, or push and pull, and an expiry between 1 and 365 days (90 by default). The token’s secret is shown once, when you create it. Kupe keeps no copy, so if you lose it, revoke the token and create another.
Pods in your clusters do not need a token: connect the cluster instead.
Create a token
Section titled “Create a token”Creating an access token needs a tenant admin. readonly members can list
tokens but not create them.
kupe registry token create --name github-actions --access push --expires-in-days 30 -o json-o json prints the token’s ID, username, access, expiry and secret. Without
it, standard output holds only the secret, so
TOKEN=$(kupe registry token create --name deploy --access pull) works in a
script. The command waits until the token is issued, which takes seconds; a
token that is not issued within a minute is revoked. See
kupe registry token create.
On the registry’s Access tab, select Create access token.
Give it a name, such as github-actions, choose Pull or Push and pull,
and an expiry. The dialog that follows shows the username, the token and a
docker login command, each with a copy button. It is the only time the
token is shown.
curl -X POST \ -H "Authorization: Bearer $KUPE_API_KEY" \ -H "Content-Type: application/json" \ "https://api.kupe.cloud/api/v1/tenants/$KUPE_TENANT/registries/registry/tokens" \ -d '{"displayName": "github-actions", "access": "push", "expiresInDays": 30}'The response carries username and secret; see
Manage the registry with the API.
resource "kupe_registry_token" "ci" { registry = kupe_registry.this.name display_name = "github-actions" access = "push" expires_in_days = 30}The secret is stored in Terraform state in plain text. See Manage the registry with Terraform.
A registry holds up to 50 access tokens. Login sessions from
kupe registry login do not count towards that.
The username and the secret
Section titled “The username and the secret”Sign in with the username shown with the token, which looks like
kupe+acme+tok-1a2b3c4d5e6f7a8b, and the secret as the password. The username
has no characters a shell treats specially, so it needs no quoting.
The secret starts with kupecr_ and is 49 characters long, so secret scanners
can recognise one that leaks. Store it in your CI system’s secret store, masked
in logs.
printf '%s' "$KUPE_REGISTRY_TOKEN" | docker login registry.kupe.cloud \ --username "$KUPE_REGISTRY_USERNAME" --password-stdinPull or push and pull
Section titled “Pull or push and pull”| Access | Can do |
|---|---|
pull |
Pull every repository in your registry. |
push |
Pull, push to every repository, and replace existing tags. Shown as Push and pull in the console. |
Neither can delete images. Deleting is done through the console, the CLI, the API or Terraform; see Managing images.
Expiry
Section titled “Expiry”A token stops working at its expiry time. The console shows how many days are
left, and the RegistryAccessTokenExpiring alert fires when a token is due to
expire within 7 days (see Alerts). A token cannot be
extended: create a new one, give it to whatever used the old one, then revoke
the old one.
Last used
Section titled “Last used”Last used shows the most recent pull or push made with the token. It is checked about once an hour. The registry keeps its record of pulls and pushes for 30 days, so a token with no use in that time shows Not in the last 30 days in the console.
Revoke
Section titled “Revoke”Revoking a token stops it signing in. Admins can revoke any token; a readonly
member can revoke only their own login sessions.
kupe registry token listkupe registry token revoke rt-1a2b3c4d5e6f7a8bIn the console, select Revoke on the token’s row. The API is
DELETE .../registries/registry/tokens/{id}.
When a member leaves or becomes read-only
Section titled “When a member leaves or becomes read-only”A token belongs to the member who created it, or to the member who created the API key that created it.
- When that member leaves the tenant, every access token and login session they created is revoked.
- When an admin becomes a
readonlymember, the access tokens and login sessions they created that can push are revoked. Their pull-only ones keep working.
For a pipeline that must outlive one person’s membership, plan who creates its token and replace it when that person leaves.
GitHub Actions
Section titled “GitHub Actions”This workflow builds the image in the repository and pushes it on every push to
main. Create a push token, then set the repository variables KUPE_TENANT
and KUPE_REGISTRY_USERNAME and the secret KUPE_REGISTRY_TOKEN. The
hello-kupe sample
holds the same file as ci/github-actions.yaml.
# Builds the image in this repository and pushes it to your Kupe registry# on every push to main.## Set in the repository's settings (Settings > Secrets and variables > Actions):# variable KUPE_TENANT your tenant name# variable KUPE_REGISTRY_USERNAME the access token's username (kupe+<tenant>+tok-...)# secret KUPE_REGISTRY_TOKEN the access token's secret (kupecr_...)# Create a push token with:# kupe registry token create --name github-actions --access push -o jsonname: Push to the Kupe registry
on: push: branches: - main
permissions: contents: read
jobs: push: name: Build and push runs-on: ubuntu-latest env: # Change hello-kupe to the repository name you push to. IMAGE: registry.kupe.cloud/${{ vars.KUPE_TENANT }}/hello-kupe steps: - name: Checkout code uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false
- name: Set up Docker Buildx uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- name: Sign in to the Kupe registry uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 with: registry: registry.kupe.cloud username: ${{ vars.KUPE_REGISTRY_USERNAME }} password: ${{ secrets.KUPE_REGISTRY_TOKEN }}
- name: Build and push uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 with: context: . platforms: linux/amd64 push: true tags: ${{ env.IMAGE }}:${{ github.sha }}GitLab CI
Section titled “GitLab CI”This job builds the image and pushes it on every push to the default branch,
using Docker in Docker. Set the CI/CD variables KUPE_TENANT,
KUPE_REGISTRY_USERNAME and KUPE_REGISTRY_TOKEN, each protected, and mask
the token. The hello-kupe sample holds the same file as ci/gitlab-ci.yml.
# Builds the image in this repository and pushes it to your Kupe registry# on every push to the default branch.## Set in the project's settings (Settings > CI/CD > Variables), each protected:# KUPE_TENANT your tenant name# KUPE_REGISTRY_USERNAME the access token's username (kupe+<tenant>+tok-...)# KUPE_REGISTRY_TOKEN the access token's secret (kupecr_...), also masked# Create a push token with:# kupe registry token create --name gitlab-ci --access push -o jsonpush-to-kupe: image: docker:29.9.2 services: - docker:29.9.2-dind variables: DOCKER_TLS_CERTDIR: "/certs" # Change hello-kupe to the repository name you push to. IMAGE: registry.kupe.cloud/$KUPE_TENANT/hello-kupe:$CI_COMMIT_SHORT_SHA rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH script: - printf '%s' "$KUPE_REGISTRY_TOKEN" | docker login registry.kupe.cloud --username "$KUPE_REGISTRY_USERNAME" --password-stdin - docker build --platform linux/amd64 -t "$IMAGE" . - docker push "$IMAGE"