oci

package
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 13, 2026 License: Apache-2.0 Imports: 27 Imported by: 0

Documentation

Overview

Package oci stores and retrieves DevProof subjects as OCI objects.

The local image layout implemented here is the Phase 1 transport: it is a real, spec-shaped OCI layout that other tooling can read, which makes the hardest guarantees — canonical bytes and safe expansion — testable without a registry in the picture.

Index

Constants

View Source
const (

	// MediaTypeImageIndex is the OCI index media type.
	MediaTypeImageIndex = "application/vnd.oci.image.index.v1+json"

	// AnnotationRefName is the conventional annotation carrying a tag.
	// It lives on the index, never on the subject manifest: an annotation on
	// the subject would change its digest (DP-002).
	AnnotationRefName = "org.opencontainers.image.ref.name"
)

OCI image layout file names and values, from the image-spec.

Variables

This section is empty.

Functions

This section is empty.

Types

type Index

type Index struct {
	SchemaVersion int         `json:"schemaVersion"`
	MediaType     string      `json:"mediaType"`
	Manifests     []IndexItem `json:"manifests"`
}

Index is the layout's index.json.

type IndexItem

type IndexItem struct {
	MediaType    string            `json:"mediaType"`
	Digest       string            `json:"digest"`
	Size         int64             `json:"size"`
	ArtifactType string            `json:"artifactType,omitempty"`
	Annotations  map[string]string `json:"annotations,omitempty"`
	// Subject names the manifest this one is a referrer for. A layout has no
	// referrers API, so the index is where that relationship is recorded.
	Subject string `json:"subject,omitempty"`
}

IndexItem references a manifest in the layout.

Unlike a subject manifest, an index entry may carry annotations: the index is a local directory listing, not content anybody addresses by digest, so a tag recorded here cannot change what the subject is.

func (IndexItem) Descriptor

func (i IndexItem) Descriptor() artifact.Descriptor

Descriptor returns the item as a plain descriptor.

func (IndexItem) Ref

func (i IndexItem) Ref() string

Ref returns the item's tag, if it has one.

type Layout

type Layout struct {
	// contains filtered or unexported fields
}

Layout is an OCI image layout directory.

Every operation goes through an os.Root held on the layout directory, so a blob path derived from a digest cannot escape it even if the digest string were somehow attacker-controlled.

func Create

func Create(dir string) (_ *Layout, retErr error)

Create makes a new OCI image layout at dir.

The directory must not already be a layout. Writing into an existing one would mean inheriting blobs and an index that this process never verified.

func Open

func Open(dir string) (_ *Layout, retErr error)

Open opens an existing OCI image layout.

func (*Layout) AddManifest

func (l *Layout) AddManifest(descriptor artifact.Descriptor, artifactType, tag string) error

AddManifest records a subject in the index, optionally under a tag.

A tag is written only after the manifest it names is already present, which is the local equivalent of the publication barrier a registry push observes (DP-007): a name never points at content that has not landed.

func (*Layout) AddReferrer

func (l *Layout) AddReferrer(descriptor artifact.Descriptor, artifactType, subjectDigest string) error

AddReferrer records an evidence manifest against its subject.

Unlike AddManifest this never carries a tag and never replaces an existing entry with a different digest: a subject may have several pieces of evidence, and attaching one must not remove another (DP-003).

func (*Layout) Close

func (l *Layout) Close() error

Close releases the layout's directory handle.

func (*Layout) FindManifest

func (l *Layout) FindManifest(reference string) (IndexItem, error)

FindManifest resolves a reference, which may be a digest or a tag.

A tag is resolved to a digest here and the digest is what every later step uses, so a tag that moves mid-operation cannot change what was verified (DP-007).

func (*Layout) GetBlob

func (l *Layout) GetBlob(digest canonical.Digest, limit int64) ([]byte, error)

GetBlob reads a blob, verifying it against its digest.

limit bounds the read so that a layout directory someone else can write cannot force an unbounded allocation.

func (*Layout) Index

func (l *Layout) Index() (*Index, error)

Index reads index.json.

func (*Layout) OpenBlob

func (l *Layout) OpenBlob(digest canonical.Digest) (io.ReadCloser, int64, error)

OpenBlob returns a streaming reader over a blob.

The caller is responsible for verifying the digest as it reads; this exists for the layer, which is too large to hold in memory just to check it once.

func (*Layout) Path

func (l *Layout) Path() string

Path returns the layout's absolute path.

func (*Layout) PutBlob

func (l *Layout) PutBlob(content []byte) (canonical.Digest, error)

PutBlob stores content under its digest.

The digest is recomputed from the bytes rather than trusted from the caller, because a blob filed under the wrong name is a blob that will later verify against a descriptor it does not match. Writing is atomic: content lands at a temporary name, is synced, and is renamed into place, so a crash never leaves a truncated blob at a digest-shaped path where a reader would take its name as proof of its content.

func (*Layout) PutBlobStream

func (l *Layout) PutBlobStream(content io.Reader, want canonical.Digest, size int64) (retErr error)

PutBlobStream stores a blob by streaming it, verifying as it goes.

The layer can be far larger than memory, and reading it into a slice just to hash it once would make peak memory track payload size. Instead the content is hashed while it is written to a temporary file, and the file is published under its digest only once the digest is known to be the expected one.

want is the digest the caller expects. A blob is never filed under a digest it does not have, so a source that served different bytes is caught here rather than becoming a corrupt layout.

func (*Layout) SetIndex

func (l *Layout) SetIndex(items []IndexItem) error

SetIndex replaces index.json.

type LayoutTransport

type LayoutTransport struct {
	// contains filtered or unexported fields
}

LayoutTransport exposes local OCI image layouts through the same contract as a registry.

Having one contract is what keeps the publication rules — blobs before the manifest, read back before tagging, tag last — in one place. A local destination that had its own code path would be the one where those rules quietly diverged, and it is the path most people develop against.

func NewLayoutTransport

func NewLayoutTransport() *LayoutTransport

NewLayoutTransport returns a transport for local layouts.

func (*LayoutTransport) Attach

Attach stores an evidence blob and the referrer manifest naming it.

func (*LayoutTransport) Close

func (t *LayoutTransport) Close() error

Close releases every layout this transport opened.

func (*LayoutTransport) Fetch

Fetch returns the content a descriptor names.

func (*LayoutTransport) Push

Push stores content under its descriptor.

func (*LayoutTransport) Record

func (t *LayoutTransport) Record(ref artifact.Reference, target artifact.Descriptor) error

Record registers a manifest in the index without assigning a tag.

A layout has no way to enumerate manifests other than its index, so an untagged subject still has to be recorded or it would be unreachable. This is layout-specific: a registry keeps a manifest addressable by digest with no index entry at all.

func (*LayoutTransport) Referrers

Referrers lists evidence attached to a subject in a layout.

A layout has no referrers API, so the index is scanned for manifests whose subject is the one asked about. That is a real set, unlike the registry fallback tag, so the storage mode reported is the referrers one.

func (*LayoutTransport) Resolve

Resolve freezes a reference to one descriptor.

func (*LayoutTransport) Scheme

func (t *LayoutTransport) Scheme() string

Scheme is the reference scheme this transport handles.

func (*LayoutTransport) Tag

Tag assigns a mutable name to an already-stored manifest.

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry is an OCI Distribution transport.

func NewRegistry

func NewRegistry(opts RegistryOptions) *Registry

NewRegistry returns a registry transport.

func (*Registry) Attach

func (r *Registry) Attach(
	ctx context.Context,
	ref artifact.Reference,
	subject artifact.Descriptor,
	blob artifact.Descriptor,
	content io.Reader,
	artifactType string,
) (artifact.Descriptor, artifact.EvidenceStorage, error)

Attach stores an evidence blob and the referrer manifest naming it.

func (*Registry) Close

func (r *Registry) Close() error

Close releases idle connections.

func (*Registry) Fetch

Fetch returns the content a descriptor names.

func (*Registry) Push

func (r *Registry) Push(ctx context.Context, ref artifact.Reference, target artifact.Descriptor, content io.Reader) error

Push stores content under its descriptor. Content that is already present is not an error.

func (*Registry) Referrers

func (r *Registry) Referrers(
	ctx context.Context,
	ref artifact.Reference,
	subject artifact.Descriptor,
	artifactType string,
) ([]artifact.Descriptor, artifact.EvidenceStorage, error)

Referrers lists evidence attached to a subject.

Where the registry has no referrers API, the fallback tag is consulted instead and the storage mode says so. A caller that cannot accept the fallback's replace-rather-than-accumulate semantics can refuse it by policy, but only if it is told which mode answered (DP-028).

func (*Registry) Resolve

Resolve freezes a reference to one descriptor.

func (*Registry) Scheme

func (r *Registry) Scheme() string

Scheme is the reference scheme this transport handles.

func (*Registry) Tag

func (r *Registry) Tag(ctx context.Context, ref artifact.Reference, target artifact.Descriptor, tag string) error

Tag assigns a mutable name to an already-stored manifest.

type RegistryOptions

type RegistryOptions struct {
	// Credentials supplies per-host credentials. Nil means anonymous.
	Credentials artifact.CredentialProvider
	// PlainHTTP disables TLS.
	PlainHTTP bool
	// Timeout bounds a single request attempt.
	Timeout time.Duration
}

RegistryOptions configures a registry transport.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL