Workbenches is an open standard. Read why
Docs Images

API reference

Images

workbenches.dev runs an OCI image registry at images.workbenches.dev for Workbench runtime images. Repository names are <organization>/<image>. Push with wb image push or any OCI client; see Publishing.

Who can pull#

An image is private until a public Workbench references it. A repository is pullable anonymously only while at least one public, approved version in that organization names an image in it. Otherwise a pull needs:

  • an API key of the owning organization with catalog:read or packages:write, sent as the Basic password, or
  • a pull token from POST /v1/pulls, sent as the Basic password with any username.

Otherwise the registry answers 401 with a Basic challenge. Cloud runs pull internal images of their own organization with a short-lived pull token; another organization's internal image fails the run.

Who can push#

The registry issues its own token. A key needs packages:write and an owning user to receive push scope, and push also needs a signed-in account. Tokens carry the key's organization.

List images#

GET /v1/images

Open. With organization_id, a key with catalog:read or a signed-in member.

Query Type Meaning
organization_id UUID This organization's images.
publisher_slug slug A publisher's images.

Response 200:

{
    "images": [
        {
            "id": "uuid",
            "name": "project-core",
            "status": "active",
            "reference": "images.workbenches.dev/acme/project-core",
            "storage_bytes": 734003200,
            "publisher": {
                "id": "uuid",
                "slug": "acme",
                "name": "Acme",
                "accent": null,
                "logo_url": null
            },
            "tags": [
                {
                    "name": "0.4.0",
                    "digest": "sha256:...",
                    "media_type": "application/vnd.oci.image.manifest.v1+json",
                    "manifest_size": 1234,
                    "updated_at": "..."
                }
            ],
            "created_at": "...",
            "updated_at": "..."
        }
    ]
}

status is active, unlisted, or deprecated.

Mint a pull credential#

POST /v1/pulls with { "repository": "acme/project-core" }

Key catalog:read of the organization that owns the repository. The image must exist.

Response 200:

{ "username": "...", "password": "...", "expires_at": "..." }

The password is a signed token, valid for 10 minutes, that grants pull on that one repository and nothing else.

printf "%s" "$PASSWORD" | docker login images.workbenches.dev -u "$USERNAME" --password-stdin
docker pull images.workbenches.dev/acme/project-core:0.4.0

OCI Distribution#

The registry implements the OCI Distribution routes under images.workbenches.dev/v2. Errors use the OCI error format.

Method Path Auth Purpose
GET /v2/ Open Ping. Answers 401 with a WWW-Authenticate challenge.
GET /v2/auth Open; send Basic or Bearer credentials for push Token endpoint. A 5 minute signed token.
POST /v2/:publisher/:image/blobs/uploads Push Start a blob upload, or mount with ?mount=.
GET, PATCH, PUT, DELETE /v2/:publisher/:image/blobs/uploads/:id Push Status, append, complete (?digest=), or cancel an upload.
GET, HEAD /v2/:publisher/:image/blobs/:digest Pull Fetch a blob.
GET, HEAD /v2/:publisher/:image/manifests/:reference Pull Fetch a manifest by tag or digest.
PUT /v2/:publisher/:image/manifests/:reference Push Push a manifest.
GET /v2/:publisher/:image/tags/list Pull List tags.

Upload limits#

A blob sent in one request may be any size the request limit allows. A chunked upload follows these rules: every chunk after the first must match the first chunk's size, which must be at least 5 MiB, and only the last chunk may be smaller. Upload responses send OCI-Chunk-Min-Length: 5242880. A chunk that breaks the rule answers 400 BLOB_UPLOAD_INVALID before anything is stored. A blob is at most 5 GiB.

Direct client pushes are subject to the registry edge's per-request body limit. Use wb image push for images with large layers, because it controls the chunk size.