Skip to content

Credentials

imglife uses two sets of credentials:

  1. Package Registry — for storing/reading build metadata (GitLab, Gitea, or S3).
  2. OCI registries — for pulling/pushing Docker images.
Provider Variable Required scopes
GitLab GITLAB_TOKEN api, read_packages, write_packages, read_registry, write_registry
Gitea GITEA_TOKEN package scope, write:repository (for git push in CI)
S3 / Garage AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY s3:GetObject, s3:PutObject, s3:DeleteObject, s3:ListBucket
Terminal window
# GitLab
export GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx
# Gitea
export GITEA_TOKEN=giteatoken...
# S3
export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=secret...

OCI registry credentials use a naming convention based on the normalised hostname:

Normalisation rule: hostname → uppercase → replace all non-alphanumeric characters with _.

Hostname Normalised Variable prefix
docker.io DOCKER_IO IMGLIFE_DOCKER_IO_
quay.io QUAY_IO IMGLIFE_QUAY_IO_
ghcr.io GHCR_IO IMGLIFE_GHCR_IO_
registry.example.com REGISTRY_EXAMPLE_COM IMGLIFE_REGISTRY_EXAMPLE_COM_
registry:5000 REGISTRY_5000 IMGLIFE_REGISTRY_5000_

Three authentication methods:

Terminal window
export IMGLIFE_DOCKER_IO_USERNAME=myuser
export IMGLIFE_DOCKER_IO_PASSWORD=mypassword
Terminal window
export IMGLIFE_QUAY_IO_TOKEN=mytoken
export IMGLIFE_GHCR_IO_TOKEN=ghp_...

If no IMGLIFE_* variable is set for a host, imglife falls back to ~/.docker/config.json. This means a prior docker login works automatically.

Docker Hub enforces pull rate limits for anonymous and free accounts. Always provide Docker Hub credentials:

Terminal window
export IMGLIFE_DOCKER_IO_USERNAME=myuser
export IMGLIFE_DOCKER_IO_PASSWORD=dckr_pat_...

In CI, store these as masked CI variables:

  • GitLab: Settings > CI/CD > Variables
  • Gitea: Repository Settings > Secrets

In GitLab CI, the built-in CI_JOB_TOKEN is automatically used for your project’s own registry ($CI_REGISTRY). You don’t need to set IMGLIFE_* variables for it.

For cross-project registry access, use a dedicated service account token.

For sync entries pulling from private registries:

sync:
entries:
- source: quay.io/prometheus/prometheus
# ...
Terminal window
export IMGLIFE_QUAY_IO_TOKEN=mytoken

For local development with plain-HTTP registries:

registry:
url: http://registry.local:5000
insecure_registries:
- registry.local:5000
Terminal window
# Credentials for the insecure registry
export IMGLIFE_REGISTRY_LOCAL_5000_USERNAME=admin
export IMGLIFE_REGISTRY_LOCAL_5000_PASSWORD=password

Follow the principle of least privilege:

Operation Required scope
sync Read from source, write to target OCI registry; no Package Registry access
build Write to target OCI registry; no Package Registry access
cleanup Delete from OCI registry; no Package Registry access
register Write to Package Registry; no OCI registry access
status Read from Package Registry; no OCI registry access
check Read from Package Registry; no OCI registry access
eol update Write to Package Registry (if eol_target: pkgregistry); no OCI registry access

For a typical base-images pipeline, you need one token with all scopes. For applicative projects (check + register only), a read-only token plus package write is sufficient.