Runbook — Onboard a GitLab Container Registry as a Stella publish target
SPRINT_20260605_010 (SRD-INT-004). Companion to SPRINT_20260605_009 (Scanner-side referrers fallback-tag + external-image attach) and ADR-024 (internal OCI metadata registry / opt-in upstream attachment / attachment-state).
This runbook explains how to register a GitLab Container Registry (e.g. registry.<gitlab-host>) as a Stella registry integration so Stella can attach SBOM + reachability OCI referrers to images and, when opted in, mirror those referrers to the GitLab registry.
Why GitLab CR needs special handling
- Token-realm auth. GitLab’s registry does not accept Basic auth on
/v2/directly; it answers401withWWW-Authenticate: Bearer realm="https://<gitlab-host>/jwt/auth",service="container_registry". Stella performs the bearer-token dance (challenge → token GET with the credential as Basic → authenticated request). The write-probe (POST /v2/<repo>/blobs/uploads/→DELETE) runs through the same dance (SRD-INT-001). - No Referrers API on GitLab CE. GitLab CE returns
404on/v2/<repo>/referrers/<digest>(the registry metadata DB that powers the Referrers API is off). Stella therefore makes referrers discoverable via the OCI fallback-tag scheme (sha256-<subjectDigest>index) — handled Scanner-side inOciArtifactPusher(SPRINT_20260605_009 / SRD-ATT-001). No registry-side configuration is required.
Prerequisites
- A GitLab access token with registry push scope. A Personal Access Token (or Project/Group token) with
read_registryandwrite_registryscopes. (Withoutwrite_registrythe integration is pull-only; Stella will reportwriteAccess=falseand an opt-in publish target will be markedFailed.) - A writable probe namespace. GitLab maps each registry repository to a project. The write-probe needs a repository path the token can push to (the integration’s configured publish namespace). A token with
write_registrybut no project mapping will (correctly) fail the probe. - The token stored in Vault. Do not paste the token inline. Store it in Vault and reference it (see below) so the integration row holds a reference, never the secret (SRD-INT-002).
Steps
- Store the token in Vault. e.g.
vault kv put secret/<path> token=<PAT>. - Create the registry integration (
POST /integrationsor the Console):type = Registry,endpoint = https://registry.<gitlab-host>.- Credential = a secret reference, not an inline secret:
authref://vault/<path>#<field>(existing authref scheme), orvault://<path>#<field>(SPRINT_20260605_010 / SRD-INT-002).
publishOciMetadata = trueinExtendedConfigto opt in to external attachment (defaultfalse= internal-only, the ADR-024 system-of-record path).
- Test the connection. Stella resolves the credential, runs the read + write probes through the GitLab token realm, and records the capability snapshot. Expected outcomes:
- read+write OK →
Active;SupportsArtifactPublish = true. - read OK, write denied +
publishOciMetadata=true→Failedwith a blocking reason mentioningpublishOciMetadata(INT-003: opt-in must fail loud, never silentActive). - credential reference resolves to nothing + opt-in →
Failedwith “credential reference could not be resolved … will not fall back to anonymous access” (SRD-INT-002 — an anonymous-read registry must never look “Healthy (pull only)” while the configured PAT is dead).
- read+write OK →
Token rotation / expiry drift
GitLab tokens expire. The periodic registry write-drift monitor re-runs the read + write probe on its interval. On a writable→read-only transition (e.g. the token expired or lost write_registry) it emits registry.write-access-lost(and registry.write-access-restoredon recovery), after a bounded number of consecutive confirming probes to avoid flapping (SRD-INT-003). Treat registry.write-access-lost as: external attachment will fail until the token is rotated — rotate the Vault secret; the next probe drains back to Active/restored. Internal attachment (the ADR-024 system of record) is unaffected by token loss.
Air-gap note
External attachment + drift notifications are opt-in and disable-able. With publishOciMetadata=false the integration never pushes upstream; Stella’s internal OCI metadata registry remains the system of record and all referrers are served by digest locally.
