Skip to content

Docker Registry Standards ​

The RepoForge.io Docker registry complies with the following Open Container Initiative (OCI) and Docker specifications, so docker, buildx, containerd, podman, skopeo, crane, oras and cosign work against it without extra configuration.

Registry API ​

StandardSpecification
OCI Distribution Spec v1.1Distribution Specification
Docker Registry HTTP API V2HTTP API V2
Docker Token AuthenticationToken Authentication Specification
Docker Token ScopesToken Scope Documentation

Every response carries the Docker-Distribution-API-Version: registry/2.0 header, and errors use the spec's {"errors": [{"code": ..., "message": ..., "detail": ...}]} format with codes such as BLOB_UNKNOWN, MANIFEST_UNKNOWN, DIGEST_INVALID and UNAUTHORIZED.

Images ​

StandardSpecification
OCI Image ManifestImage Manifest Specification
OCI Image IndexImage Index Specification
OCI Content DescriptorsDescriptors and digests
Docker Image Manifest V2, Schema 2Image Manifest V2, Schema 2

This covers single-platform images, multi-platform images built with docker buildx, Docker manifest lists, and artifacts such as signatures, SBOMs and attestations that use subject, artifactType and annotations. Manifests are stored and served byte for byte as they were pushed, so the body always hashes to its Docker-Content-Digest. Blob digests can use sha256 or sha512; manifest digests use sha256.

Supported Endpoints ​

All paths are relative to https://docker.repoforge.io/v2/, where <name> is your hash ID followed by the registry name, for example repoforge-hash-id/name-of-registry. Registry names can contain / to group images, for example repoforge-hash-id/team/app.

EndpointPurpose
GET /v2/Check the registry is available and the token is valid
GET /v2/_catalogList the registries in your account
GET /v2/<name>/tags/listList tags, paged with n and last and a Link header
HEAD, GET /v2/<name>/manifests/<reference>Check or pull a manifest by tag or digest
PUT /v2/<name>/manifests/<reference>Push a manifest or image index
DELETE /v2/<name>/manifests/<reference>Delete a tag, or a manifest by digest
HEAD, GET /v2/<name>/blobs/<digest>Check or pull a blob, including byte ranges with Range
DELETE /v2/<name>/blobs/<digest>Delete a blob that no manifest references
POST /v2/<name>/blobs/uploads/Start a chunked upload, upload a blob in one request with ?digest=, or mount a blob from another registry with ?mount=<digest>&from=<name>
PATCH, PUT /v2/<name>/blobs/uploads/<uuid>Upload a chunk, then complete the upload
GET, DELETE /v2/<name>/blobs/uploads/<uuid>Check the progress of an upload, or cancel it
GET /v2/<name>/referrers/<digest>List the signatures, SBOMs and attestations that refer to a manifest, optionally filtered by artifactType

Push Checks ​

When you push an image, RepoForge.io also:

  • hashes every uploaded blob and rejects the upload with 400 DIGEST_INVALID if it doesn't match the digest your client sends
  • checks that a manifest pushed by digest hashes to that digest, and that its Content-Type matches its mediaType
  • rejects a manifest with 400 MANIFEST_BLOB_UNKNOWN if it references a blob or child manifest that hasn't been pushed
  • rejects a tag that isn't a valid tag name with 400 TAG_INVALID
  • rejects manifests larger than 256 KiB with 413 SIZE_INVALID

When a tag is moved to a new image, the old image is only removed once no other tag, image index or artifact refers to it, so layers shared between tags are never lost.

Tokens and Scopes ​

Clients request a token for the registries and actions they need, using scopes such as repository:repoforge-hash-id/name-of-registry:pull,push. RepoForge.io only grants the actions your user or access token is allowed:

ActionAllowsRole
pullPulling manifests, tags and blobsDocker - Read only or Docker - Full access
pushUploading blobs and pushing manifestsDocker - Full access
deleteDeleting tags, manifests and blobsDocker - Full access

If registry-level permissions are on, the registry's own roles are used instead. Anyone can get a pull token for a public registry without logging in, but never a push or delete token.

A request without a valid token, or with a token that doesn't cover it, returns 401 Unauthorized with a WWW-Authenticate header naming the scope it needs, so clients can fetch the right token and retry.

Delete an Image ​

docker can't delete images from a registry, but tools that use the registry API can. For example, with crane:

bash
crane auth login docker.repoforge.io -u __token__ -p "$REPOFORGE_TOKEN"
crane delete docker.repoforge.io/repoforge-hash-id/name-of-registry:old-tag

Deleting a tag removes only that tag. Deleting by digest, for example crane delete docker.repoforge.io/repoforge-hash-id/name-of-registry@sha256:..., removes the image and every tag pointing at it. Either way, layers are removed only once no other image uses them.

Built with care by the RepoForge.io team.