Regstair: One Endpoint for Every Container Registry

Inspiration

Container registries are treated as infrastructure details, but their locations leak into almost everything: Dockerfiles, CI pipelines, Kubernetes manifests, deployment scripts, documentation, and developer workflows.

An organization may use several registries at once:

  • Harbor for internal applications
  • Docker Hub for public base images
  • GitHub Container Registry for open-source projects
  • cloud registries such as ECR, GCR, or ACR
  • vendor-specific registries
  • departmental or regional registry infrastructure

Every client is expected to know where each image lives.

That creates brittle dependencies. Moving an image between registries can require changes across hundreds of repositories. Public-registry outages or rate limits can interrupt builds. Repeated image pulls waste bandwidth. Internal namespaces can also become vulnerable to unsafe fallback or dependency-confusion behavior when registry resolution is not explicitly governed.

We wanted to separate the logical identity of a container image from its physical registry location.

Regstair was created as an OCI abstraction layer: one endpoint through which clients can pull and publish images while policy determines where those operations actually go.

The simplest way to describe the idea is:

Pull without knowing where the image lives. Push without knowing where the image belongs.


What Regstair Does

Regstair presents a single OCI-compatible endpoint to Docker, Podman, CI systems, Kubernetes, and other container tooling.

Behind that endpoint, it applies deterministic routing policy to:

  • search approved registries in a defined order;
  • prefer authoritative internal sources;
  • allow or deny external fallback by namespace;
  • retrieve images from public or private upstream registries;
  • cache manifests and layers locally by digest;
  • reuse cached content for later pulls;
  • route image pushes to the correct internal registry;
  • rewrite logical namespaces to physical registry paths;
  • record image provenance and routing decisions;
  • explain why each pull or push resolved as it did.

For example, a client may pull:

registry.example.org/library/postgres:17

Regstair may resolve that request by:

  1. checking an internal curated registry;
  2. falling back to Docker Hub if policy permits;
  3. verifying the returned manifest and layer digests;
  4. caching the content locally;
  5. serving later requests without contacting Docker Hub again.

A different namespace might be protected:

registry.example.org/company/payroll-api:4.2

If the authoritative internal registry does not contain that image, Regstair refuses to search public registries. This prevents an internal image name from unexpectedly resolving to unrelated external content.

Pushes use the same abstraction. A developer can publish to the Regstair endpoint, and routing policy determines which internal Harbor, Quay, cloud registry, or other OCI destination should receive the image.


Why This Is More Than a Pull-Through Cache

Pull-through caches already exist, but caching is only one part of the problem.

Regstair is designed around a broader abstraction:

  • Pull routing: Where should an image be found?
  • Push routing: Where should a new image be published?
  • Namespace authority: Which registry owns a particular image namespace?
  • Fallback control: When may Regstair search another source?
  • Logical naming: Can clients use stable names while storage locations change?
  • Digest caching: Can identical layers be stored once and reused safely?
  • Provenance: Where did an image come from?
  • Policy explanation: Why did this request resolve the way it did?
  • Hierarchy: Can one Regstair node route through another?

The objective is not to replace Harbor, Quay, Zot, Distribution, or cloud registries. Regstair sits in front of them and provides a unified policy and routing layer.


How We Built It

Regstair was built as a collection of deliberately separated components.

OCI Gateway

The gateway exposes the registry interface used by container clients. It handles authentication, request normalization, manifest requests, blob transfers, and push operations.

Route Engine

The route engine matches logical repository names against configured policy.

Each route can define:

  • namespace patterns;
  • ordered pull sources;
  • authoritative registries;
  • whether external fallback is permitted;
  • push destinations;
  • namespace rewrites;
  • tag freshness behavior;
  • cache-retention policy.

Routing is deterministic. An AI model may help generate or explain a policy, but it does not decide live production requests.

Registry Connectors

Registry connectors isolate upstream-specific behavior. Internal registries, external registries, and other Regstair nodes are represented through the same source abstraction.

Content-Addressed Cache

OCI objects are stored by digest rather than as independent image archives.

Regstair tracks:

  • indexes;
  • manifests;
  • image configurations;
  • layers and blobs;
  • tag-to-digest mappings;
  • access timestamps;
  • leases;
  • pins;
  • provenance records.

If several image tags share a layer, the underlying blob is retained once and referenced by digest.

Metadata and Provenance

Regstair records:

  • the logical image requested;
  • the source registry consulted;
  • the physical upstream repository;
  • the resolved digest;
  • whether fallback was used;
  • whether the response came from cache;
  • when the image was last validated;
  • where a pushed image was published.

Administrative Interface

The web interface exposes:

  • configured sources;
  • routing policy;
  • registry health;
  • recent pulls and pushes;
  • cache hits and misses;
  • stored artifacts;
  • resolved digests;
  • image provenance;
  • routing explanations.

How We Used Codex and GPT-5.6

Codex was used as the primary implementation agent during development.

It helped with:

  • scaffolding the Go service;
  • implementing OCI request paths;
  • building the routing engine;
  • creating upstream registry connectors;
  • implementing digest verification;
  • building the content-addressed cache;
  • adding push-routing behavior;
  • creating automated integration tests;
  • assembling the Docker Compose test environment;
  • building the administrative API and interface;
  • refining setup and test documentation.

The major product and architectural decisions remained human-driven, including:

  • treating Regstair as an abstraction layer rather than a registry replacement;
  • supporting both pull and push routing;
  • making namespace authority explicit;
  • prohibiting unsafe implicit fallback;
  • keeping request-time routing deterministic;
  • using digest-addressed storage;
  • separating logical names from physical locations;
  • limiting the Build Week version to a demonstrable vertical slice.

GPT-5.6 was also used to assist with policy-oriented functionality. It can translate administrator intent into a proposed routing configuration, explain route decisions, and identify potentially dangerous policy such as ambiguous namespaces or unsafe external fallback.

Generated policy is never accepted blindly. It must pass schema validation and deterministic safety checks before an administrator can approve it.


Challenges We Faced

OCI Distribution Is a Protocol, Not Just File Transfer

A container image is not a single file. It may contain an index, one or more platform-specific manifests, configurations, and many shared blobs.

Supporting standard clients required correctly handling:

  • tag and digest references;
  • manifest media types;
  • multi-platform image indexes;
  • blob existence checks;
  • resumable uploads;
  • digest validation;
  • registry-compatible errors;
  • authentication challenges.

The implementation had to preserve OCI semantics rather than simply downloading and rehosting tar archives.

Tags Are Mutable

A digest identifies immutable content. A tag does not.

For a pull such as:

ubuntu:latest

Regstair must decide when to consult the upstream registry again. Returning a cached digest forever would be fast but potentially stale. Rechecking on every pull would reduce much of the cache benefit.

We introduced configurable tag-freshness rules, including:

  • always revalidate;
  • revalidate after a time-to-live;
  • serve stale content when an upstream is unavailable;
  • require digest references for protected namespaces.

Registry Search Can Become a Security Problem

The phrase “try internal first, then external” sounds simple, but it is unsafe without namespace ownership.

If an internal registry is unavailable, Regstair must not silently resolve an internal application name from Docker Hub merely because a matching public name exists.

The route model therefore distinguishes:

  • authoritative registries;
  • fallback registries;
  • protected namespaces;
  • externally resolvable namespaces.

Push Routing Is Harder Than Pull Routing

Pulling can often stream existing content from an upstream source. Pushes require handling uploads, validating blobs, selecting the destination, and preserving the client’s expected registry workflow.

We deliberately limited the first version to a clear, policy-selected primary destination rather than prematurely implementing complex multi-registry transactions.

Safe Cache Eviction Requires Graph Awareness

Deleting an “old image” is not as simple as deleting a directory. Several manifests may share the same layers.

Regstair therefore treats cache cleanup as a reference-aware process:

  1. mark retained and pinned manifests;
  2. trace referenced configurations and blobs;
  3. protect active leases;
  4. remove only unreferenced content.

Scope Control

The product naturally expands into:

  • replication;
  • signature verification;
  • SBOMs;
  • vulnerability scanning;
  • multi-region storage;
  • Kubernetes admission policy;
  • high availability;
  • peer-to-peer distribution.

The largest challenge was resisting the temptation to build the entire future platform at once.

For Build Week, we focused on proving the central abstraction:

  1. pull through one endpoint;
  2. route across internal and external sources;
  3. cache by digest;
  4. operate from cache during an upstream outage;
  5. block unsafe namespace fallback;
  6. push through the same endpoint to a policy-selected destination;
  7. show exactly why each operation resolved as it did.

What We Learned

We learned that a registry abstraction layer must treat routing policy as part of the software supply chain, not merely as network configuration.

Several conclusions became central to the design:

  • image names require explicit namespace authority;
  • tags and digests must be handled differently;
  • caching and mirroring are not the same thing;
  • pull routing and push routing belong in the same abstraction;
  • provenance should be captured during resolution, not reconstructed later;
  • cached layers must be managed as a reference graph;
  • AI is most useful for policy creation and explanation, while enforcement should remain deterministic;
  • existing registries are valuable infrastructure and should be composed rather than replaced.

We also learned that the most important part of Regstair is not the cache.

The cache improves performance and reliability, but the real product is the stable boundary it creates between clients and registry infrastructure.


Accomplishments We Are Proud Of

  • Created a single logical endpoint for OCI pull and push operations.
  • Implemented deterministic multi-registry routing.
  • Added namespace authority and safe fallback control.
  • Cached OCI content by digest.
  • Preserved shared-layer deduplication.
  • Demonstrated repeated pulls without the original external source.
  • Routed pushes to a policy-selected destination.
  • Recorded artifact provenance.
  • Produced human-readable request explanations.
  • Built a reproducible containerized test environment.
  • Kept AI-generated policy advisory and human-approved.

What Is Next

Regstair’s next stages include:

  • hierarchical Regstair-to-Regstair routing;
  • regional and site-local caching;
  • asynchronous replication;
  • S3-compatible storage;
  • OIDC and enterprise authentication;
  • Cosign and attestation verification;
  • SBOM indexing;
  • vulnerability and license policy;
  • cache prewarming;
  • high availability;
  • GitOps-managed routing policy;
  • support for additional OCI artifacts such as Helm charts, WASM modules, model packages, and build caches.

The long-term objective is for an organization to treat Regstair as its permanent OCI address, while the underlying registry products, locations, and storage technologies can evolve independently.


Final Thought

Container infrastructure has traditionally required every client to know too much.

Regstair changes that relationship.

One endpoint. Every registry. Deterministic policy.

Built With

Share this project:

Updates

posted an update

Scrambled to get this done after work, after working through the weekend, and totally missed the <3 minute requirement on the video. I blew it on the last item. It was fun anyway, and I got to learn more about Codex.

Log in or sign up for Devpost to join the conversation.