Imported from vince-winkintel/gitlab-cli-skills (
glab-artifact-registry/SKILL.md). Install upstream withnpx skills add vince-winkintel/gitlab-cli-skills --skill glab-artifact-registry. Copyright stays with the author.
glab artifact-registry
Exchange the active GitLab credential for a short-lived Artifact Registry access token. The command group also accepts the glab ar alias. This command group is experimental; verify live help and the target GitLab instance before using it in durable automation.
Maven and sbt destination files
login --config-file <path> applies only to --maven or --sbt; other package-manager modes reject it, as does an explicitly empty path. It writes only that file, leaving the default destinations alone. Approve the token exchange and exact destination before running login; these files contain a live credential and must stay outside repositories and logs. A project-specific Maven settings file must also be selected by the consuming build, for example with Maven's --settings option. For sbt with -Dsbt.global.base, select the credentials.sbt file inside that actual base.
Without --config-file, sbt writes ~/.sbt/1.0/credentials.sbt plus <base>/2/credentials.sbt. For sbt 2.x, <base> uses the first valid absolute override: SBT_CONFIG_HOME, then XDG_CONFIG_HOME/sbt on macOS/Linux or %LOCALAPPDATA%\sbt on Windows, then ~/.config/sbt as the fallback. On Windows, glab uses LOCALAPPDATA instead of XDG_CONFIG_HOME; it does not consult XDG_CONFIG_HOME for this base. Blank or relative overrides are skipped with a warning because sbt can resolve them differently. On Windows, absolute LOCALAPPDATA also gets sbt/credentials.sbt for the sbt 2.x batch launcher. Inspect every reported destination: a later write can fail after an earlier file already received the token.
Credentials use realm artifact-registry, username __token__, and the lowercased hostname without its port. Existing matching active entries are refreshed. An already-running sbt shell/server keeps its old credentials until reload or sbt shutdown; refresh the token and reload before retrying an expired-token build.
# After approving the exchange and the destination outside version control
glab artifact-registry login --maven --registry https://ar.example.com \
--registry-alias gitlab-ar --config-file /secure/build-settings.xml
glab artifact-registry login --sbt --registry https://ar.example.com \
--config-file /secure/sbt-global/credentials.sbt
Prerequisites
- GitLab Enterprise Edition 19.4 or later.
glabis authenticated to the intended hostname.
The token is ephemeral but still a credential. Never print it in logs, store it in a repository, include it in command arguments, or paste it into issue/MR content.
Check access first
status performs the token exchange and prints non-secret identity metadata: issuer, subject, audience, and expiry. Each check mints and immediately discards a server-side token; prefer JSON for automation and do not call it in a tight loop.
glab artifact-registry status --hostname gitlab.example.com --output json
# Extract only non-secret expiry metadata
glab artifact-registry status \
--hostname gitlab.example.com \
--output json \
--jq '.expires_at'
Confirm that the issuer, subject, and audience identify the intended instance, actor, and registry before requesting a token for another process.
Request a short-lived token
Text output is the bare token on stdout so a shell can capture or pipe it. Default duration is 15 minutes; accepted durations range from 1 second through 12 hours. Use the shortest duration that covers the operation.
# Avoid command tracing and keep the token only in a process-local variable
set +x
artifact_token="$(glab artifact-registry get-token \
--hostname gitlab.example.com \
--duration 15m)"
# Feed via stdin, not as a command-line argument. Obtain the registry host and
# required username from the target registry's documentation or administrator.
printf '%s' "$artifact_token" | \
docker login <artifact-registry-host> \
--username '<registry-username>' \
--password-stdin
unset artifact_token
Use --output json only when a consumer also needs the expiry. Treat the JSON document as secret because it contains the token. Do not pass --jq expressions that print the token into logs.
Configure package-manager authentication
glab artifact-registry login configures exactly one package manager per run:
--dockerinstalls thedocker-credential-glabshim and registersglabunder Docker's per-registrycredHelpers.--mavenwrites a<server>block to~/.m2/settings.xml, keyed by--registry-alias; the consuming<repository>must use the same<id>.--gradlewrites{alias}Url,{alias}Username, and{alias}Passwordto~/.gradle/gradle.properties, where{alias}is--registry-alias.--npmwrites a//{host}{path}/:_authTokenentry to~/.npmrc; you must still configureregistry=or@scope:registry=to point npm at the registry.--yarnconfigures Yarn 2 or later in~/.yarnrc.yml: annpmRegistriesentry holdsnpmAuthTokenandnpmAlwaysAuth. Set a matchingnpmRegistryServerseparately. For Yarn 1 use--npm. ExistingnpmScopescredentials can override the registry token; inspect the warning and review the scope before changing it. Rewriting YAML can change formatting.--sbtwrites credentials for both sbt 1.x and 2.x; see destination and reload rules above.--config-fileselects one file instead.
# Show only the destination path, then check the stored GitLab identity
printf 'Docker config: %s\n' "${DOCKER_CONFIG:-$HOME/.docker}/config.json"
glab auth status --hostname gitlab.example.com
# Configure only the verified Artifact Registry hostname
glab artifact-registry login \
--hostname gitlab.example.com \
--docker \
--registry registry.example.com
# Configure Maven for a two-hour token
glab artifact-registry login \
--hostname gitlab.example.com \
--maven \
--registry https://ar.example.com \
--registry-alias gitlab-ar \
--duration 2h
Safety and compatibility rules:
- For
--docker,--registrymust be a bare hostname, optionally with a port. For Maven, Gradle, npm, Yarn, and sbt,--registryis typically a URL. - Docker exchanges a fresh token for every pull or push, so
--durationdoes not apply. Maven, Gradle, npm, Yarn, and sbt receive one static token; rerun the command before--durationelapses. - The Docker helper subprocess intentionally ignores
GITLAB_TOKEN. It normally reads a token stored byglab auth login; inside a GitLab CI job, it also honorsCI_JOB_TOKENwhen CI auto-login is enabled withGLAB_ENABLE_CI_AUTOLOGIN=true. Maven, Gradle, npm, Yarn, and sbt login paths can readGITLAB_TOKENbecauseglabwrites the exchanged token into each tool's config file. - Use this only for a registry actually backed by GitLab Artifact Registry. Misclassifying a normal container registry can make every pull fail because an exchanged Artifact Registry token takes precedence.
- Review the destination config path before writing:
${DOCKER_CONFIG:-$HOME/.docker}/config.json,~/.m2/settings.xml,~/.gradle/gradle.properties,~/.npmrc,~/.yarnrc.yml, or the sbt destination files listed above (or the explicit--config-file). --registry-aliasapplies only to Maven and Gradle. For Gradle, choose an alias that is a valid identifier in the build script; the derived default can contain hyphens.- Re-running the command for the same registry refreshes or replaces the matching entry. After configuration, test a non-destructive package-manager operation against the intended host without printing credentials.
Troubleshooting
- Unsupported or not found: verify GitLab EE 19.4+ with the instance administrator.
- Wrong issuer/subject/audience: stop; re-check
--hostname, environment-token precedence, andglab auth status --hostname <host>. - Duration rejected: use a Go-style duration between
1sand12h. - Expired token: request a new short-lived token; do not persist or attempt to refresh the old one.
- Stored-token error during Docker setup: run
glab auth login --hostname <host>; an environment-only token is not used by the Docker helper. - Credential-helper conflict: use the status-only Docker diagnostic in glab-auth for the exact registry key. The config path is
${DOCKER_CONFIG:-$HOME/.docker}/config.json. Do not display the file or raw helper values in agent output, logs, or chat. Keep the current helper unless the operator explicitly approves a migration. If this standalone install lacks glab-auth, Python 3, or a Bash-compatible shell, stop the optional diagnostic; do not fall back to displaying configuration or credential-helper output. Ask the operator to inspect the selected registry privately and report onlyglab,glab-cli,not configured, ordifferent helper configured. Keep any backup private and outside the repository. - Build tool still unauthenticated: verify the tool reads the file that
glab artifact-registry loginwrote, and that its registry URL or repository ID matches the written key.
See references/commands.md for captured command help.
