Chapter 23Lesson 03~180 minutes

Container Registry, Package Registry, Generic Packages, Dependency Proxy, and Artifact Promotion: Configuration, Design Choices, and Tradeoffs

Choose deliberately among job tokens, deploy tokens, tags, digests, same-bytes promotion, built-in registries, external repository managers, protection, and retention controls.

DesignCI_JOB_TOKENDeploy tokensRetentionTradeoffs

Learning objectives

  • Choose job tokens or deploy tokens based on lifetime, execution context, and least privilege.
  • Choose tags for readability while retaining digest/checksum as the machine-verifiable identity.
  • Design same-bytes promotion instead of per-environment rebuilding.
  • Compare built-in GitLab registries with an external repository manager without collapsing trust boundaries.
  • Apply protection, duplicate, and cleanup policies without confusing governance with content identity.

1. Design problem: distribution policy is part of delivery architecture

Once multiple teams consume artifacts, registry choices affect blast radius, rollback speed, auditability, storage cost, and developer experience. The right question is not “which registry feature is richest?” It is “which identity, authentication, lifecycle, and evidence model keeps the verified bytes reproducible across teams?”

Before comparing designs, preserve the producer identity: CI_PIPELINE_SOURCE, exact CI_COMMIT_SHA, pipeline/job IDs, and the published package checksum or image digest. Design decisions are valid only if they keep that evidence chain intact.

2. Job token versus deploy token

Choice Strength Risk / cost Good fit
CI_JOB_TOKEN Ephemeral, automatically issued, tied to running job and triggering user permissions. Cross-project use needs allowlist and user permission; runner security matters. CI-to-GitLab package/container automation.
Deploy token Purpose-built registry/package scopes; useful outside CI. Longer-lived secret requires rotation/storage; protected packages can restrict deploy-token publishing. External deployment system or read-only consumer.
PAT/project access token Broad API flexibility. Often wider than distribution needs and longer lived. Only when narrower mechanisms cannot perform an authorized requirement.

For CI, start with the job token. For a non-CI consumer, a narrowly scoped deploy token may be appropriate. Never choose a credential merely because it “makes 403 go away.”

3. Tag versus digest/version

Reference Human readability Mutability Rollback/provenance value
Container tag v1.4.0 High Can move unless policy prevents overwrite Record resolved digest alongside it.
Container @sha256:… Lower Content-addressed Strong machine identity for deploy/rollback.
Generic package version High Named version; duplicate assets may be configurable/allowed Pair with file checksum and duplicate policy.
Package checksum Low Content identity of file Strong verification of exact bytes.

4. Rebuild per environment versus promote the same bytes

Rebuilding in test, staging, and production produces three artifact identities even if the source SHA is the same. Toolchain timing, dependency resolution, base image drift, timestamps, or nondeterministic compilation can change the bytes. Promotion should preserve the object identity and only change eligibility or a human-facing pointer.

flowchart LR
  A[Build once from source SHA] --> B[Digest/checksum]
  B --> C[Test consumes exact identity]
  C --> D[Approval / policy]
  D --> E[Staging points to same identity]
  E --> F[Approval / policy]
  F --> G[Production points to same identity]
  G --> H[Independent health check]

5. GitLab registry versus external repository manager

Dimension GitLab built-in registry External repository manager
Pipeline integration Native project metadata, job-token flow, release/deployment proximity. Usually requires external auth/config and separate audit correlation.
Formats/features Strong built-in coverage; Generic Packages for arbitrary files. May offer broader federation, replication, promotion, scanning, or enterprise policy depending on product.
Identity GitLab project/package/image coordinates. External repository path/digest/version.
Evidence Producer pipeline and commit can be close to package metadata. Must explicitly record GitLab pipeline → external object relationship.
Operations Fewer systems for smaller teams. Separate service lifecycle, HA, backup, credentials, cost.

6. Protection and immutability are different controls

Protected packages and protected container tags restrict who can push/delete matching identities. Current protected container tags are Free and can define up to five rules per project; protected tags are excluded from cleanup policies. Container tag immutability goes further: once a matching tag exists, it cannot be updated or deleted. Current GitLab documents container tag immutability as Ultimate, so the mandatory course path never depends on it.

Generic Packages have their own duplicate behavior: duplicate files are allowed by default and can be restricted at group settings. Therefore, your immutable contract should still include exact version + checksum even when governance rules exist.

7. Retention: storage control must preserve rollback evidence

Container cleanup policies select tags by name/age while always preserving latest and excluding protected/immutable tags. Deleting tags does not necessarily reclaim underlying layers immediately; registry garbage collection/online GC behavior is a separate storage layer. Package cleanup likewise has package/asset rules. Start with narrow policies and inspect what will remain before relying on cleanup for cost control.

Retention question Evidence-first answer
Can we delete this tag? Is it a rollback/provenance target? Is it protected/immutable? Which digest does it reference?
Can we delete this package version? Who consumes the exact version? Is request forwarding enabled? Is the version referenced by releases/deployments?
Did cleanup save storage? Inspect registry/package usage after policy execution; tag deletion alone is not storage proof.

8. Worked scenario: choose a design

A team builds a CLI once, tests it in CI, deploys it to staging and production, and also publishes a container wrapper. Production must be reproducible; a legacy external host needs read-only download access.

Decision Choice Why Observable evidence
CI publisher CI_JOB_TOKEN Ephemeral and native to producer pipeline. Producer pipeline/job IDs + successful package/container publication.
Legacy consumer Read-only deploy token Non-CI system needs durable read identity only. Token class/scope documented; download audit; checksum match.
Package identity Version + SHA-256 Readable version plus byte identity. Package coordinate + stored/local checksum.
Container identity Tag + manifest digest Readable label plus content-addressed deploy reference. Registry digest + deployment reference.
Promotion Same bytes Avoids rebuild drift. Stage/prod manifests reference same checksum/digest.
Retention Protect release identities; clean ephemeral tags narrowly Preserves rollback while controlling cost. Policy config + post-cleanup object inventory.

9. Tier/offering assumptions

  • Generic Packages, Package Registry, Container Registry, Dependency Proxy, protected packages, and protected container tags are available across Free/Premium/Ultimate in current docs.
  • Container tag immutability is currently documented as Ultimate.
  • Self-Managed registry capabilities can depend on using the newer container registry/metadata database.
  • Cross-project job-token access remains authorization-sensitive even when the feature itself is Free.

Knowledge check

Why is a deploy token not automatically “more secure” than a job token?

If a protected tag cannot be overwritten by a Developer, is its digest unnecessary?

What is the main reproducibility problem with rebuilding in each environment?

When should an external repository manager be considered?

Why start cleanup rules narrowly?

Next lesson

Diagnostics, failure modes, security, and performance

Preserve evidence and diagnose mutable-tag drift, duplicate-version ambiguity, job-token denials, proxy/provenance confusion, credential exposure, and cleanup mistakes at the correct layer.

Version and compatibility note

GitLab and GitLab Runner evolve continuously. Treat version-sensitive YAML, runner/executor behavior, APIs, security features, policy controls, tiers, and deprecations as assumptions to verify against the current official GitLab documentation before production use. Preserve the exact project/ref/SHA, compiled configuration, pipeline/job IDs, runner/tool versions, and external target evidence used for any reproducible lab or incident record.

Official references and version notes

Documentation verification date: 2026-09-12. Generic Packages, Package Registry, Container Registry, Dependency Proxy, protected packages, and protected container tags are documented for Free/Premium/Ultimate unless noted otherwise. Current immutable container-tag rules are Ultimate-only. Dependency Proxy is group-level and supports Docker Hub images. The design lesson treats GitLab feature availability as a runtime assumption to record, because Self-Managed registry backend/version configuration can affect which protection and cleanup capabilities are actually usable.

Current assumptions used in this chapter: Version-sensitive YAML, Runner/executor behavior, APIs, security features, policy controls, tiers, and deprecations must be verified against the exact GitLab, GitLab Runner, tool, and external-system versions used in production. Preserve the exact project/ref/SHA, compiled configuration, pipeline/job IDs, runner/tool versions, and external target evidence used for reproducible work.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.