Skip to content
Latchkey

oras push: Store OCI Artifacts in a Registry

oras push stores arbitrary files as an OCI artifact in a container registry, using the registry as generic content-addressable storage.

Registries can hold more than images. oras push lets a pipeline store SBOMs, signed manifests, configs, or ML models as OCI artifacts alongside images.

What it does

oras push packages one or more files into an OCI artifact manifest and uploads it to a reference. Each file becomes a layer with a media type (file:mediaType), and the whole artifact carries an artifact type set with --artifact-type.

Common usage

Terminal
# push a single file as an artifact
oras push ghcr.io/acme/configs:v1 \
  --artifact-type application/vnd.acme.config \
  config.yaml:application/yaml

# push several files
oras push ghcr.io/acme/bundle:v1 \
  sbom.json:application/spdx+json \
  notes.md:text/markdown

# authenticate first
oras login ghcr.io -u "$GH_USER" -p "$GH_TOKEN"

Options

FlagWhat it does
REF FILE[:type]Destination reference and files with optional media types
--artifact-type <type>The artifact type recorded in the manifest
--annotation key=valueAdd an OCI annotation to the manifest
--config <file>[:type]Custom config blob for the artifact
--plain-httpUse HTTP instead of HTTPS

In CI

oras push turns your registry into shared storage for build outputs like SBOMs or signed metadata, so they live next to the image and travel with --referrers copies. Authenticate with oras login (or a mounted docker config) before pushing.

Common errors in CI

"Error: no valid credentials found" or "unexpected status: 401 Unauthorized" means run oras login first. "unexpected status: 400 Bad Request" often means the registry does not accept the OCI artifact manifest; some older registries need --image-spec v1.0 or a config workaround. "http: server gave HTTP response to HTTPS client" needs --plain-http for a local registry.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →