Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

type: oras

An oras Manifest is a Manifest type that pulls an artifact placed in an OCI registry and delegates its content to helmfile or kustomize to apply to the cluster.

The ORAS Manager handles the pull → extract → invoke delegate Manager chain. The artifact’s content itself is written in the same idiomatic style as helmfile / kustomize.

path

An ORAS Manifest’s manifests[].path is not used in practice. Since validation does not allow it to be empty, write some directory.

The path passed to the delegate Manager is the cache directory locally extracted after the pull (descended to a sub-path if target is specified).

Specific Fields

Written inside the manifests[].oras object.

FieldTypeRequiredDefaultDescription
referencestringYes-OCI artifact reference. Accepts both the tag form (ghcr.io/example/foo:v1.0.0) and the digest form (ghcr.io/example/foo@sha256:...).
targetstring-""Relative sub-path from the artifact root after extraction. Omitting it means the root. Values that escape the artifact root via .. and so on are rejected.
plainHTTPbool-falseWhen true, connect to the registry over HTTP (non-TLS).
insecureSkipVerifybool-falseWhen true, skip TLS certificate verification when connecting to the registry.
authORASAuth-nullOverrides the registry credentials. Defaults to using docker config.json. See Credential resolution for details.
delegateORASDelegateYes-Configuration of the delegate Manager invoked after the pull.

ORASAuth

FieldTypeRequiredDescription
usernamestring-Registry username.
passwordstring-Registry password.

If both fields are empty, this is not treated as an override (see Credential resolution).

ORASDelegate

FieldTypeRequiredDefaultDescription
typestringYes-Manifest type to delegate to. helmfile or kustomize.
helmfileManifestHelmfile-nullOptions passed to the delegate as-is when type: helmfile.
kustomizeManifestKustomize-nullOptions passed to the delegate as-is when type: kustomize.

Behavior

OperationInternal processing
BuildPull artifact → call the delegate’s Build.
ApplyPull artifact → call the delegate’s Apply.
DestroyPull artifact → call the delegate’s Destroy.

The delegate is invoked with a new Manifest assembled like this:

  • name / description / tags / tests are carried over from the original ORAS Manifest as-is.
  • type is delegate.type (helmfile / kustomize).
  • path is the local path after the pull (with sub-path appended if target is set).
  • Specific fields use delegate.helmfile / delegate.kustomize as-is.

Test plugin is also evaluated in the same Manifest context.

Pull and Cache

ORAS pulls are cached locally per digest. Subsequent pulls of an artifact with the same digest do not access the registry.

  • Cache directory:
    • If $XDG_CACHE_HOME is set: $XDG_CACHE_HOME/tazuna/oras
    • Otherwise: $HOME/.cache/tazuna/oras
  • Cache structure:
    • Artifact is extracted under blobs/<sanitized digest>/
    • Tag → digest mapping is recorded in refs/<sanitized reference>
  • Specifying --no-cache to apply / build / destroy bypasses the cache and always refetches from the registry.
  • Specifying --offline forbids registry access. If the cache misses, it is an error.
  • --no-cache and --offline cannot be specified together.
  • See the apply / build / destroy pages for CLI flags.

Constraints at Extraction Time

Tar extraction inside the artifact applies the upper bounds defined in ADR004.

LimitValue
Total size after extraction1 GiB
Number of tar entries10000

The following invalid entries are rejected.

  • Entries containing absolute paths
  • Entries that escape the extraction directory via .. (zip slip)
  • Symlinks / hardlinks that escape the extraction directory
  • Unsupported types (character device / block device / FIFO, etc.)

The artifact’s OCI manifest is required to have only one layer. Multi-layer artifacts are not accepted.

Credential Resolution

Credentials for the registry are resolved in the following priority.

  1. oras.auth override (at least one of username / password is non-empty)
  2. docker’s credential store ($DOCKER_CONFIG or ~/.docker/config.json)
  3. anonymous (no authentication)

Even if you write oras.auth, if both fields are empty it is not treated as an override and falls back to the docker side (to avoid unintended anonymization).

Within the same process, token caching is shared, so multiple pulls against the same registry do not pay the cost of re-acquiring tokens.

Examples

Tag-based + helmfile delegation:

manifests:
  - name: cert-manager
    type: oras
    path: ./oras/cert-manager   # not actually used but required
    oras:
      reference: ghcr.io/example/cert-manager-helmfile:v1.14.0
      delegate:
        type: helmfile
        helmfile:
          includeCRDs: true
          wait: true

Digest-based + kustomize delegation + sub-path:

manifests:
  - name: ingress-nginx
    type: oras
    path: ./oras/ingress-nginx
    oras:
      reference: registry.example.com/platform/ingress-bundle@sha256:abc123...
      target: kustomize/ingress-nginx
      auth:
        username: ci-bot
        password: ${REGISTRY_TOKEN}
      delegate:
        type: kustomize
        kustomize:
          defaultNamespace: ingress-nginx