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.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
reference | string | Yes | - | OCI artifact reference. Accepts both the tag form (ghcr.io/example/foo:v1.0.0) and the digest form (ghcr.io/example/foo@sha256:...). |
target | string | - | "" | 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. |
plainHTTP | bool | - | false | When true, connect to the registry over HTTP (non-TLS). |
insecureSkipVerify | bool | - | false | When true, skip TLS certificate verification when connecting to the registry. |
auth | ORASAuth | - | null | Overrides the registry credentials. Defaults to using docker config.json. See Credential resolution for details. |
delegate | ORASDelegate | Yes | - | Configuration of the delegate Manager invoked after the pull. |
ORASAuth
| Field | Type | Required | Description |
|---|---|---|---|
username | string | - | Registry username. |
password | string | - | Registry password. |
If both fields are empty, this is not treated as an override (see Credential resolution).
ORASDelegate
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
type | string | Yes | - | Manifest type to delegate to. helmfile or kustomize. |
helmfile | ManifestHelmfile | - | null | Options passed to the delegate as-is when type: helmfile. |
kustomize | ManifestKustomize | - | null | Options passed to the delegate as-is when type: kustomize. |
Behavior
| Operation | Internal processing |
|---|---|
Build | Pull artifact → call the delegate’s Build. |
Apply | Pull artifact → call the delegate’s Apply. |
Destroy | Pull artifact → call the delegate’s Destroy. |
The delegate is invoked with a new Manifest assembled like this:
name/description/tags/testsare carried over from the original ORAS Manifest as-is.typeisdelegate.type(helmfile/kustomize).pathis the local path after the pull (with sub-path appended iftargetis set).- Specific fields use
delegate.helmfile/delegate.kustomizeas-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_HOMEis set:$XDG_CACHE_HOME/tazuna/oras - Otherwise:
$HOME/.cache/tazuna/oras
- If
- Cache structure:
- Artifact is extracted under
blobs/<sanitized digest>/ - Tag → digest mapping is recorded in
refs/<sanitized reference>
- Artifact is extracted under
- Specifying
--no-cachetoapply/build/destroybypasses the cache and always refetches from the registry. - Specifying
--offlineforbids registry access. If the cache misses, it is an error. --no-cacheand--offlinecannot be specified together.- See the
apply/build/destroypages for CLI flags.
Constraints at Extraction Time
Tar extraction inside the artifact applies the upper bounds defined in ADR004.
| Limit | Value |
|---|---|
| Total size after extraction | 1 GiB |
| Number of tar entries | 10000 |
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.
oras.authoverride (at least one ofusername/passwordis non-empty)- docker’s credential store (
$DOCKER_CONFIGor~/.docker/config.json) - 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
Related
- Delegate targets:
type: helmfile/type: kustomize - CLI:
tazuna apply/tazuna build/tazuna destroy - Term: ORAS / OCI artifact