Guided Problem
MiniDock Build 10: Authenticate One Protected Release
- Time
- 25m
- Level
- intermediate
- Artifacts
- not specified
Registry Architecture
Design claim: A registry is a content service whose authentication, metadata, and blob paths have different responsibilities.
Starting model
- You can recover local engine state without confusing mutable names, immutable image content, and instance state.
- The useful vocabulary at this point is deliberately small: registry, manifest endpoint, blob endpoint, token.
Distribution is not remote execution
Clients must discover, authorize, fetch, and publish image objects without turning a registry into a remote Docker daemon. Distribution adds concurrency and remote failure to an immutable object graph. The useful question is when another client may safely observe a release.
The tempting shortcut is straightforward: expose one authenticated file server for names and bytes. The happy path makes the shortcut appear atomic even though metadata and large byte transfers complete at different times. Mutable references, immutable manifests, large blobs, and scoped authorization have different caching and consistency needs. Once a reader or retry can interleave with publication, visibility and durability need an explicit order.
Separate authority, metadata, and bytes
The entire distribution protocol fits on an index card. Manifests: GET /v2/{repo}/manifests/{tag-or-digest} — the only endpoint that understands names. Blobs: GET /v2/{repo}/blobs/{digest} — dumb byte service. Existence checks use HEAD on the same paths, and uploads use POST/PUT (Lesson 16). Internally the registry mirrors this split: a metadata service for manifests and tags, and a blob store — usually delegating actual bytes to object storage (S3-style), often behind a CDN, because verified-by-digest bytes can be served from anywhere.
A distribution API separates token issuance, repository-scoped metadata operations, and digest-addressed blob transfer. The protocol separates authorization, object identity, transfer, and publication so each response has a precise meaning.
Read the architecture as a trust boundary around metadata and bytes, then identify the one operation that makes a graph visible.
flowchart LR
C["client (engine)"]
AUTH["auth service
issues scoped tokens"]
API["HTTP API frontend
/v2/…"]
MS["manifest + tag service
(understands names)"]
BS["blob service
(digests → bytes)"]
OS[("object storage / CDN")]
C -- "1· get token (repo:pull)" --> AUTH
C -- "2· requests + token" --> API
API --> MS
API --> BS
BS --> OS
MS -. "manifests reference blobs" .-> BS
It separates client, token service, registry metadata, and blob storage. Its central claim is that every registry operation is authorized for its repository action, and immutable objects remain addressed by verified digest; the labels therefore describe authority rather than decorative grouping.
A protected pull begins with a challenge
Registries decouple auth from serving. An unauthenticated request gets 401 plus a header saying where to get a token and for what scope; the client fetches a short-lived token scoped to one repository and one action (pull or push), then retries. The registry only ever validates tokens — it never sees your password:
A client receives an authorization challenge, obtains a scoped token, resolves a manifest, then transfers only the referenced objects it lacks. At each message, ask what the client and registry can now prove about the object graph.
The second figure tests the same model in motion: it traces challenge, scoped token, manifest resolution, and blob transfer.
sequenceDiagram
participant E as Engine
participant R as Registry API
participant A as Auth service
E->>R: GET /v2/acme/api/manifests/2.1
R-->>E: 401 + "get token at A, scope: repository:acme/api:pull"
E->>A: credentials + requested scope
A-->>E: signed token (expires in minutes)
E->>R: same GET + Authorization: Bearer token
R-->>E: 200 manifest JSON
It traces challenge, scoped token, manifest resolution, and blob transfer. The ordering is valid only when it continues to preserve the stated invariant under retries and interruption.
Scope is part of the token's meaning
A token grants pull access to one repository but is replayed against another, so the registry must refuse the request before disclosing metadata. Interruption may leave resumable work, but it must not leave a visible release whose referenced content cannot be served.
Every registry operation is authorized for its repository action, and immutable objects remain addressed by verified digest. The rule binds remote visibility to verified reachability rather than to connection success.
Give MiniDock a narrow distribution seam
MiniDock can distribute releases through a narrow content protocol instead of exposing engine internals. MiniDock gains a distribution contract while placement remains a design decision.
What carries forward
- Every registry operation is authorized for its repository action, and immutable objects remain addressed by verified digest.
- Authorize protected image reads and writes without exposing long-lived client credentials to content storage.
- The rejected shortcut remains a diagnostic: if the design starts depending on it again, the original constraint has probably been lost.
See what actually stuck.
Take the practice scenarios now.