Skip to main content

Web UI Reference

Reference for the Angos web interface.


Configuration​

[ui]
enabled = true
name = "My Registry"
OptionTypeDefaultDescription
enabledboolfalseEnable the web interface
namestring"Angos"Registry name displayed in the top bar

Sign-in​

[ui.oidc]
provider = "dex"
client_id = "angos-ui"
OptionTypeDefaultDescription
providerstringrequiredThe auth.oidc provider to sign in against
client_idstringrequiredThe provider's public client, holding no secret
scopesstring"openid profile email"The OAuth scope parameter, verbatim

provider names a configured [auth.oidc.<name>] section and the registry refuses to start when no such provider exists. The issuer is read from it, so the browser can only be sent to an issuer the registry validates tokens from.

Without this section the UI offers no sign-in and sends no credentials, which is what a registry readable anonymously or fronted by an authenticating proxy wants.


URL Structure​

URLs follow Docker reference format:

URLViewDescription
/Repository listAll configured repositories
/{repository}Namespace listImages within a repository
/{repository}/{namespace}Manifest listAll manifests for an image
/{repository}/{namespace}:{tag}Manifest detailsManifest by tag
/{repository}/{namespace}@{digest}Manifest detailsManifest by digest
...#history, ...#vulnerabilities, ...#filesystemManifest detailsA manifest's Pull History, Vulnerabilities or Filesystem tab; no anchor opens the OCI tab, and ...#vulnerabilities/linux/arm64 one platform's report of an index
/jobs/{queue}JobsPending and failed jobs of the cache, replication or scan queue; /jobs opens the cache queue

Examples:

  • / - List all repositories
  • /library - List namespaces in the "library" repository
  • /library/nginx - List all nginx manifests
  • /library/nginx:latest - Details for the latest tag
  • /library/nginx@sha256:abc123... - Details for a specific digest

API Endpoints​

UI Configuration​

GET /v2/_angos/ui/config

Returns the UI configuration.

Response:

{
"name": "My Registry",
"oidc": {
"issuer": "https://dex.example.com",
"client_id": "angos-ui",
"scopes": "openid profile email"
}
}

The oidc object is present only when [ui.oidc] is configured. Every field in it is public by nature: the client holds no secret. The endpoint itself needs no credentials, since the UI reads it before anyone has signed in.

Static Assets​

Static assets have no dedicated URL prefix. Every GET or HEAD request outside the API routes (/v2/..., /healthz, /readyz, /metrics) serves the embedded single-page app, falling back to index.html for paths that match no bundled asset.


Access Control Actions​

UI-specific actions for access policies:

ActionDescription
ui-assetStatic files (JS, CSS, images)
ui-configUI configuration endpoint (/v2/_angos/ui/config)
list-repositoriesRepository list view
list-namespacesNamespace list view
list-revisionsManifest list view
list-uploadsActive uploads view

Allowing list-repositories and list-namespaces does not expose every repository: both listings serve a repository only while it holds a namespace the caller could list tags under. A repository whose access_policy denies them stays out of the UI and answers as an absent one when opened directly, and so does a repository that is simply empty, which is what keeps the two apart from being told apart.

Minimal Policy for UI Access​

[global.access_policy]
default = "deny"
rules = [
# Allow UI to load
"request.action == 'ui-asset' || request.action == 'ui-config'",

# Allow authenticated users to browse
"identity.username != null && request.action.startsWith('list-')",

# Allow reading manifests
"identity.username != null && request.action == 'get-manifest'"
]

Read-Only Policy​

rules = [
"request.action == 'ui-asset' || request.action == 'ui-config'",
"identity.username != null && request.action.startsWith('list-')",
"identity.username != null && request.action == 'get-manifest'",
"identity.username != null && request.action == 'get-referrers'",
"identity.username != null && request.action == 'get-blob'"
]

Full Access Policy​

rules = [
"request.action == 'ui-asset' || request.action == 'ui-config'",
"identity.username != null"
]

Views​

Repository List​

Repository ListRepository List

Displays the configured repositories in two tables, the hosted ones first and the pull-through caches, when any are configured, after them, each with:

  • Repository name
  • Upstream registry, for a cache
  • Immutable badge, when immutable tags are enabled
  • Namespace count

Namespace List​

Namespace ListNamespace List

Displays images within a repository:

  • Image name (namespace)
  • Manifest count
  • Upload count (if any in progress)
  • Repository configuration summary

Manifest List​

Manifest ListManifest List

Tree view of all manifests:

  • Multi-platform indexes with expandable children
  • Platform badges (e.g., linux/amd64, linux/arm64)
  • Attestations badges: SBOM, SLSA, signature, vulnerability report, etc.
  • Tags as clickable badges
  • Digest (shortened, click to copy full)
  • Push time
  • Last pull time (if tracked): the newest pull by digest or through any of its tags

Manifest Details​

The page opens with a title, the full name it was addressed by (namespace:tag or namespace@digest) with a copy button, and splits the detail into tabs. Each tab has its own URL, the anchor naming it (#history, #vulnerabilities, #filesystem) and none for OCI, so a tab can be linked to; an anchor naming a tab the manifest lacks opens OCI. On a multi-platform index the platform shown follows, as in #vulnerabilities/linux/arm64.

OCI​

Manifest Details, OCI tabManifest Details, OCI tab

The manifest (digest, tags with delete buttons, media type, artifact type, subject, expandable annotations, a delete action), the config, the layers (or, for an ORAS artifact, its files with download links), an index's platform manifests, the referrers (signatures, SBOMs, reports), and what references the manifest. Referrers load the first 100 with the view; a "Load more referrers" control fetches the next page, which needs the get-referrers action.

For a multi-platform index, the platform manifests are listed with their referrers nested beneath, each attestation carrying its SBOM, SLSA or vuln badge:

Manifest details for a multi-platform indexManifest details for a multi-platform index

Pull History​

Pull History tabPull History tab

The newest 100 recorded pulls of the reference the view was addressed by, a tag and a digest recorded separately, each naming the client that pulled. The heading states the configured retention, since superseded entries are collected past it; recording happens only when update_pull_time is enabled.

Vulnerabilities​

Vulnerabilities tabVulnerabilities tab

Shown only when a report is attached, with the total finding count in a grey square on the tab: the report inline, its findings filterable by severity, each with the package, installed and fixed versions and a link to the advisory, and the scanner named. A multi-platform index gets a sub-tab per platform manifest that has a report. The counts also appear next to the vuln badge in the manifest tree and in referrer lists, as count pills coloured by severity with the severity named on hover.

Filesystem​

Filesystem tab, list viewFilesystem tab, list view

Shown only for an image with tar layers: the layers merged into one tree, the way a runtime applies them, whiteouts removing what lower layers put there, and every entry carrying the layer that last set it. Opening a file shows it beside the list, in view while the list scrolls: its metadata and digests over its text with numbered lines, syntax colored for common languages, markdown rendered, images shown, an ELF binary's type, architecture, loader, hardening and the libraries it needs, a PEM file's certificates listed with their expiry, a diff against another layer's version, the first 512 KiB of a larger one, a chip per layer holding a version of it, and a Download button; a symlink is followed to its target. Both go through the registry's layer endpoints, which need the get-blob action. The open file is in the URL (#filesystem/<path>, @L<n> for another layer's version), Esc closes it, and the arrow keys and Enter walk each view. The first visit to an image nobody indexed shows "Indexing" until the registry's index jobs have walked its layers, and a listing an older version indexed shows with a notice until its layer is indexed again. Beside the Tree and Icons views, a Secrets view lists the files of any layer holding a private key, a service token or a credential anywhere in their text, removed ones included, with the lines they are on, marked when the file opens, a Permissions view lists the setuid, setgid and world-writable files and folders and the files granted Linux capabilities, and a Waste view measures the bytes later layers overwrote or removed and the bytes spent on identical files, each file of either opening on click, the overwritten ones as their layer holds them.

The icon view walks the tree folder by folder as tiles:

Filesystem tab, icon viewFilesystem tab, icon view

The layers menu narrows the tree to what the checked layers added, changed or removed, and a path filter narrows it to matching names:

Filesystem tab, layers menuFilesystem tab, layers menu

Uploads​

UploadsUploads

Shows in-progress blob uploads:

  • Upload UUID
  • Current size
  • Start time
  • Cancel button

Jobs​

JobsJobs

Lists the durable background work of each queue, one URL per queue (/jobs/cache, /jobs/replication, /jobs/scan, /jobs/index), selected by the tabs at the top; /jobs opens the cache queue. Two tables:

  • Pending & In-flight: the kind, lock key, attempt count and queued time of each job, with a backoff badge on one waiting out a retry delay, and a delete action.
  • Failed: the jobs that exhausted their attempts and dead-lettered, with the last error, a retry that re-queues one and a delete that discards it.

Interactive Features​

Delete Operations​

Delete buttons require double-click confirmation:

  1. First click: Arms the button (changes to red)
  2. Second click: Executes the deletion
  3. Click elsewhere: Disarms

Deletable items:

  • Tags (removes tag, keeps the manifest unless a retention policy allows its deletion)
  • Manifests (by digest), with what their going would orphan
  • Uploads (cancels in-progress uploads)

Deleting a manifest takes its orphans with it. Deleting an index also deletes the platform manifests no other index names and that carry no tag of their own, and the referrers (signatures, SBOMs, scan reports) of everything removed, since a referrer without its subject has nothing left to describe. A platform manifest another index still names, and anything tagged, stays. The armed confirm button names what goes, as confirm (+2 platform, +1 attestation). The registry's own DELETE is per manifest and unchanged: this is the web UI deleting what a retention policy would otherwise reclaim later, which matters most when no retention policy is configured, since untagged manifests are then kept indefinitely.

Deleting several manifests: the Select button above the manifest table puts a checkbox on every row, with one in the header that covers the rows at the top level. delete selected (N) then arms and confirms like any other delete and sends one delete per manifest; the rows that went disappear at once and the refresh reconciles the rest. Done leaves select mode, and so does opening another page; the whole checkbox cell is the target, not only the box.

Copy to Clipboard​

The manifest page's title carries a copy button; it copies the full name, namespace:tag or namespace@sha256:..., so what is copied can be pulled as is.

Theme Toggle​

Toggle between light, dark and system themes with the switcher at the right of the top bar. Preference is saved in browser local storage.

Dark and Light Theme

Annotations Expansion​

Click [+] to expand annotation values. Well-known annotation keys are displayed with friendly names:

  • org.opencontainers.image.title → Title
  • org.opencontainers.image.description → Description
  • org.opencontainers.image.version → Version
  • org.opencontainers.image.created → Created
  • org.opencontainers.image.source → Source

ORAS Artifacts​

ORAS FilesORAS Files

For OCI artifacts (non-container content), the UI displays:

  • Filename (from annotations or media type)
  • Media type
  • Size
  • Download button

Download URL format:

/v2/{namespace}/blobs/{digest}

Platform Display​

Multi-platform images show platform information:

BadgeMeaning
linux/amd64Linux on x86_64
linux/arm64Linux on ARM64
linux/arm/v7Linux on ARMv7
windows/amd64Windows on x86_64
unknownPlatform not specified

Error States​

StateDisplay
LoadingSpinner animation
Not found404 message with navigation
UnauthorizedSign-in starts, or a 401 message when already signed in
Forbidden403 message explaining access denied
Server error500 message with retry option

Browser Requirements​

  • Modern browser with JavaScript enabled
  • ES2020+ support (Chrome 80+, Firefox 74+, Safari 14+, Edge 80+)
  • CSS Grid and Flexbox support