attest

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 5, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package attest builds and verifies in-toto attestations wrapped in DSSE envelopes, re-implemented on internal/sig (no in-toto or sigstore libraries). An attestation is a signed statement *about* an artifact: "this digest has this SBOM", "this digest was built by this pipeline" (SLSA provenance), "this digest is not affected by CVE-X" (VEX), or — for the agentic era — "agent X, running prompt hash Y, produced this digest" (an agent-action attestation).

The unit that ties everything together is the in-toto Statement: a subject (name + digest) plus a typed predicate. Signing wraps the Statement JSON in a DSSE envelope with the in-toto payload type; verifying unwraps it, checks the signature against a trust root and policy, and then — critically — checks that the statement's subject digest matches the artifact actually under test. Skipping that last check is how a valid attestation for image A gets replayed onto image B, so the verify path treats a subject mismatch as a hard failure.

Index

Constants

View Source
const (
	PredicateSLSAProvenance = "https://slsa.dev/provenance/v1"
	PredicateVSA            = "https://slsa.dev/verification_summary/v1"
	PredicateOpenVEX        = "https://openvex.dev/ns/v0.2.0"
	PredicateCycloneDX      = "https://cyclonedx.org/bom"
	PredicateSPDX           = "https://spdx.dev/Document"
	// PredicateAgentAction is this project's own predicate for attesting an
	// automated (AI-agent) infrastructure change. It is intentionally namespaced
	// under docker-security.dev to signal it is a local extension, not a standard.
	PredicateAgentAction = "https://docker-security.dev/attestations/agent-action/v0.1"
)

Predicate type URIs for the predicates this package understands.

View Source
const InTotoPayloadType = "application/vnd.in-toto+json"

InTotoPayloadType is the DSSE payload type for in-toto attestations.

View Source
const InTotoStatementType = "https://in-toto.io/Statement/v1"

InTotoStatementType is the type URI for an in-toto v1 Statement.

Variables

This section is empty.

Functions

func HashPrompt

func HashPrompt(prompt []byte) string

HashPrompt returns the hex SHA-256 of a prompt's bytes, the value to store in PromptRef.SHA256. Callers hash the prompt themselves rather than passing it here-then-elsewhere, so the raw prompt never lingers in the attestation.

func SBOMPredicateType

func SBOMPredicateType(format string) string

SBOMPredicateType returns the in-toto predicate type URI for an SBOM format name ("cyclonedx" or "spdx"). Unknown formats map to CycloneDX, which is the project's default SBOM encoding.

func Sign

func Sign(st *Statement, signers ...sig.Signer) (*sig.Envelope, error)

Sign wraps a statement in a DSSE envelope signed by the given signers.

Types

type ActionInfo

type ActionInfo struct {
	// Type is the action class (e.g. "build", "deploy", "patch", "config-change").
	Type string `json:"type"`
	// Tool is the tool or API the agent invoked.
	Tool string `json:"tool,omitempty"`
	// Target is what the action affected (e.g. an image ref or resource name).
	Target string `json:"target,omitempty"`
}

ActionInfo describes what the agent did.

type Agent

type Agent struct {
	// ID is a stable identifier for the agent/automation (e.g.
	// "ci-bot@corp.example" or a service account).
	ID string `json:"id"`
	// Model names the model that drove the agent, if any (e.g. "claude-opus-4").
	Model string `json:"model,omitempty"`
	// Version is the agent software version.
	Version string `json:"version,omitempty"`
}

Agent identifies the automated actor.

type AgentAction

type AgentAction struct {
	Agent     Agent      `json:"agent"`
	Prompt    PromptRef  `json:"prompt"`
	Action    ActionInfo `json:"action"`
	Timestamp time.Time  `json:"timestamp"`
}

AgentAction is the predicate for an attested automated action.

type BuildDefinition

type BuildDefinition struct {
	// BuildType is a URI naming the build process convention.
	BuildType string `json:"buildType"`
	// ExternalParameters are the top-level, externally supplied inputs (e.g. the
	// source repo and ref).
	ExternalParameters map[string]string `json:"externalParameters,omitempty"`
	// ResolvedDependencies pins the materials the build consumed.
	ResolvedDependencies []ResourceDescriptor `json:"resolvedDependencies,omitempty"`
}

BuildDefinition describes the build's inputs.

type BuildMeta

type BuildMeta struct {
	InvocationID string     `json:"invocationId,omitempty"`
	StartedOn    *time.Time `json:"startedOn,omitempty"`
	FinishedOn   *time.Time `json:"finishedOn,omitempty"`
}

BuildMeta carries per-invocation metadata.

type Builder

type Builder struct {
	ID string `json:"id"`
}

Builder identifies the build platform. Its ID is the value provenance policy keys on ("was this built by our trusted builder?").

type OpenVEX

type OpenVEX struct {
	Context    string         `json:"@context"`
	ID         string         `json:"@id"`
	Author     string         `json:"author"`
	Timestamp  time.Time      `json:"timestamp"`
	Version    int            `json:"version"`
	Statements []VEXStatement `json:"statements"`
}

OpenVEX is a minimal OpenVEX document: a set of statements about how specific products relate to specific vulnerabilities. It lets a verifier honor a vendor's "not affected" assertion instead of failing on a raw CVE match.

type PromptRef

type PromptRef struct {
	// SHA256 is the hex SHA-256 of the exact prompt/instruction bytes.
	SHA256 string `json:"sha256"`
	// Summary is an optional short, non-sensitive human description.
	Summary string `json:"summary,omitempty"`
}

PromptRef references the instruction the agent acted on, by hash.

type Requirement

type Requirement struct {
	// ExpectedDigest is the "sha256:<hex>" the statement's subject must match.
	// Required — an empty expected digest is a programming error, not "any".
	ExpectedDigest string
	// PredicateType, if set, is the exact predicate type that must be present.
	PredicateType string
	// Policy constrains the acceptable signer identity/issuer.
	Policy sig.Policy
}

Requirement describes what a caller demands of an attestation.

type ResourceDescriptor

type ResourceDescriptor struct {
	URI    string            `json:"uri,omitempty"`
	Digest map[string]string `json:"digest,omitempty"`
}

ResourceDescriptor names a material/dependency with its digest.

type Result

type Result struct {
	// Signer is the trust-root outcome (which key/identity vouched).
	Signer sig.VerifyResult
	// Statement is the verified in-toto statement (predicate available raw).
	Statement *Statement
}

Result reports a successful attestation verification.

func Verify

func Verify(env *sig.Envelope, trust *sig.TrustRoot, req Requirement) (*Result, error)

Verify checks a DSSE-wrapped attestation against a trust root and a requirement. It fails closed on any mismatch.

type RunDetails

type RunDetails struct {
	Builder    Builder    `json:"builder"`
	Metadata   BuildMeta  `json:"metadata,omitempty"`
	Byproducts []struct{} `json:"byproducts,omitempty"`
}

RunDetails describes the builder and this specific run.

type SLSAProvenance

type SLSAProvenance struct {
	BuildDefinition BuildDefinition `json:"buildDefinition"`
	RunDetails      RunDetails      `json:"runDetails"`
}

SLSAProvenance is a trimmed SLSA v1 provenance predicate: who built the artifact, from what, and how. It answers "did this come from our pipeline?".

type Statement

type Statement struct {
	Type          string          `json:"_type"`
	Subject       []Subject       `json:"subject"`
	PredicateType string          `json:"predicateType"`
	Predicate     json.RawMessage `json:"predicate"`
}

Statement is an in-toto v1 statement. The predicate is held as raw JSON so a verifier can check the type and subject without needing to understand every predicate schema — unknown predicate shapes still verify cryptographically.

func NewAgentActionStatement

func NewAgentActionStatement(subjectName, subjectDigest string, action AgentAction) (*Statement, error)

NewAgentActionStatement builds a signed-ready in-toto statement attesting that an agent produced the artifact identified by subjectDigest. It validates that the prompt hash is a well-formed SHA-256 so a caller cannot accidentally emit an attestation with an empty or bogus prompt reference.

func NewSBOMStatement

func NewSBOMStatement(subjectName, subjectDigest, format string, sbomJSON []byte) (*Statement, error)

NewSBOMStatement binds a serialized SBOM document to an image digest as an in-toto statement. sbomJSON must be a valid JSON document (an SPDX or CycloneDX BOM); it becomes the statement's predicate verbatim.

func NewStatement

func NewStatement(subjectName, subjectDigest, predicateType string, predicate any) (*Statement, error)

NewStatement assembles a statement binding a subject digest to a typed predicate. subjectDigest must be a full "sha256:<hex>" string; the value is stored split into {"sha256": "<hex>"} per the in-toto schema. A malformed digest is rejected so we never emit an attestation about "nothing".

func ParseStatement

func ParseStatement(data []byte) (*Statement, error)

ParseStatement decodes and shape-checks an in-toto statement.

func (*Statement) DecodePredicate

func (s *Statement) DecodePredicate(v any) error

DecodePredicate unmarshals the statement's predicate into v. It is a convenience for callers that, after verification, want the typed predicate (e.g. to read a provenance builder ID or a VEX status).

func (*Statement) Marshal

func (s *Statement) Marshal() ([]byte, error)

Marshal serializes the statement as canonical JSON (the bytes that get signed inside the DSSE envelope).

func (*Statement) SubjectDigest

func (s *Statement) SubjectDigest() string

SubjectDigest returns the first subject's "sha256:<hex>" digest, or "" if the statement carries no sha256 subject digest.

type Subject

type Subject struct {
	Name   string            `json:"name"`
	Digest map[string]string `json:"digest"`
}

Subject is the artifact an attestation is about: a name plus one or more digests keyed by algorithm (e.g. {"sha256": "<hex>"}).

type VEXStatement

type VEXStatement struct {
	Vulnerability VEXVuln   `json:"vulnerability"`
	Products      []string  `json:"products"`
	Status        VEXStatus `json:"status"`
	// Justification explains a not_affected status (e.g.
	// "vulnerable_code_not_in_execute_path").
	Justification string `json:"justification,omitempty"`
}

VEXStatement is one product/vuln/status assertion.

type VEXStatus

type VEXStatus string

VEXStatus is an OpenVEX status label.

const (
	VEXNotAffected        VEXStatus = "not_affected"
	VEXAffected           VEXStatus = "affected"
	VEXFixed              VEXStatus = "fixed"
	VEXUnderInvestigation VEXStatus = "under_investigation"
)

type VEXVuln

type VEXVuln struct {
	Name string `json:"name"` // e.g. "CVE-2024-0001"
}

VEXVuln names a vulnerability.

type VSA

type VSA struct {
	Verifier           VSAVerifier   `json:"verifier"`
	TimeVerified       time.Time     `json:"timeVerified"`
	ResourceURI        string        `json:"resourceUri"`
	Policy             VSAPolicy     `json:"policy"`
	VerificationResult VerdictResult `json:"verificationResult"`
	// VerifiedLevels lists the properties that passed (e.g. "SIGNED",
	// "SLSA_PROVENANCE", "SBOM_PRESENT").
	VerifiedLevels []string `json:"verifiedLevels"`
}

VSA is a Verification Summary Attestation: a single, signed "we checked this and here is the verdict" that a downstream (deploy) system — or an orchestration agent — can trust without re-running every underlying check.

type VSAPolicy

type VSAPolicy struct {
	URI string `json:"uri,omitempty"`
}

VSAPolicy names the policy the verdict was computed under.

type VSAVerifier

type VSAVerifier struct {
	ID string `json:"id"`
}

VSAVerifier identifies who performed the verification.

type VerdictResult

type VerdictResult string

VerdictResult is the pass/fail outcome recorded in a VSA.

const (
	VerdictPassed VerdictResult = "PASSED"
	VerdictFailed VerdictResult = "FAILED"
)

Jump to

Keyboard shortcuts

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