Documentation
¶
Overview ¶
Package verifier implements offline bundle verification with a four-level trust model.
Trust Levels ¶
Verification produces one of four trust levels (highest to lowest):
- verified: The exact bundle inventory and checksums are valid, the bundle attestation is verified, the binary attestation is verified and identity-pinned to NVIDIA CI, and there is no external data.
- attested: Full chain verified but external data (--data) was used, capping trust because the data's own provenance is unknown.
- unverified: The exact bundle inventory and checksums are valid but no attestation files are present (--attest not used).
- unknown: Missing, malformed, incomplete, or unmanaged bundle inventory; invalid checksums; or failed attestation verification.
Verification Chain ¶
Verify performs a five-step offline verification:
- Read checksums.txt once and verify the exact closed-world bundle inventory
- Check for bundle attestation file
- Verify bundle attestation against trusted root, binding to checksums.txt digest and requiring a valid OIDC-issued certificate
- Check for binary attestation file
- Verify binary attestation with identity pinning to NVIDIA CI and binding to the binary digest recorded in the verified bundle attestation
All verification is fully offline using the locally cached or embedded Sigstore trusted root. No network calls are made during verification.
Identity Pinning ¶
Binary attestation verification pins to NVIDIA's GitHub Actions OIDC issuer and a repository pattern matching NVIDIA/aicr workflows. This ensures the binary was built by NVIDIA CI. The pattern can be overridden via VerifyOptions.CertificateIdentityRegexp but must always contain the github.com/NVIDIA/aicr/ prefix.
Index ¶
- Constants
- func GetTrustLevels() []string
- func ParseVersionConstraint(expr string) (*constraints.ParsedConstraint, error)
- func ValidateIdentityPattern(pattern string) error
- func VerifyBinaryAttestation(ctx context.Context, bundlePath string, identityPattern string, ...) (string, error)
- func VerifyBinaryAttestationData(ctx context.Context, data []byte, identityPattern string, ...) (string, error)
- type Policy
- type TrustLevel
- type VerifyOptions
- type VerifyResult
Constants ¶
const ( TrustedOIDCIssuer = "https://token.actions.githubusercontent.com" TrustedRepositoryPattern = `^https://github\.com/NVIDIA/aicr/\.github/workflows/on-tag\.yaml@refs/tags/.*` )
Identity pinning constants for NVIDIA CI.
Variables ¶
This section is empty.
Functions ¶
func GetTrustLevels ¶ added in v0.12.0
func GetTrustLevels() []string
GetTrustLevels returns all valid trust level names sorted alphabetically. This excludes "max" which is a meta-value for auto-detection, not a real level.
func ParseVersionConstraint ¶ added in v0.19.0
func ParseVersionConstraint(expr string) (*constraints.ParsedConstraint, error)
ParseVersionConstraint parses a CLI-version constraint expression using the same grammar CheckPolicy enforces at verify time, applying the bare-version default (e.g. "0.8.0" means ">= 0.8.0").
Exported so configuration layers can reject a malformed constraint when the document is loaded rather than after a full verification run. Sharing the parser is what keeps the two entry points from drifting: a value that parses at load time is guaranteed to parse when Policy is evaluated.
Note the check is operator-level only. The underlying parser splits off a leading comparison operator and rejects an empty remainder, but does not verify that the remainder is version-shaped, so ">= not-a-version" parses here and fails later at Evaluate.
func ValidateIdentityPattern ¶
ValidateIdentityPattern checks that a certificate identity pattern is CONFINED to the NVIDIA/aicr GitHub repository, not merely that it mentions it. Accepts both literal and regex-escaped forms of the domain (e.g., "github.com" or "github\.com").
Confinement needs two rules together, because the identity matcher pins only the OIDC issuer beyond this pattern: a widened pattern silently degrades the gate to "any GitHub Actions workflow in any repository" rather than failing visibly.
- The pattern must BEGIN with the repository prefix (an optional leading "^" aside). Requiring it as a prefix rather than a substring is what makes the check sound: a pattern that starts with a literal, and whose root is not an alternation, can only match strings starting with that literal. A mere substring test admits alternations that reach the prefix down one branch while another branch matches something else entirely.
- The root must not be an alternation, since only one branch of an alternation has to match.
Together these reject `(good|https://github.com/attacker/x/.*)` (does not begin with the prefix) and `^https://github\.com/NVIDIA/aicr/.*|.*$` (root alternation), while still accepting alternatives placed AFTER the prefix, e.g. `.../aicr/\.github/workflows/(on-tag|release)\.yaml@.*`, where every branch is already behind the pin.
A leading "^" is optional rather than required so existing unanchored patterns keep working. That is safe for the identity form this is matched against: a GitHub Actions SAN cannot embed a second "://", because neither repository names nor git refs may contain ":".
func VerifyBinaryAttestation ¶
func VerifyBinaryAttestation(ctx context.Context, bundlePath string, identityPattern string, artifactDigest []byte) (string, error)
VerifyBinaryAttestation verifies the binary attestation with identity pinning to the given OIDC issuer and repository pattern, binding the attestation to the given artifact digest. Returns the signer identity on success.
func VerifyBinaryAttestationData ¶ added in v0.19.0
func VerifyBinaryAttestationData(ctx context.Context, data []byte, identityPattern string, artifactDigest []byte) (string, error)
VerifyBinaryAttestationData verifies an already-read binary attestation (Sigstore bundle bytes) against the NVIDIA-CI identity pattern and the artifact digest. VerifyBinaryAttestation reads a file then delegates here; callers that already hold the bytes (e.g. the aicrd server, which caches and embeds them) call this directly to verify the exact content they will use, avoiding a verify-then-reread window.
Types ¶
type Policy ¶
type Policy struct {
// MinTrustLevel is the minimum required trust level ("max" resolves to
// the highest achievable level for the bundle).
MinTrustLevel string
// RequireCreator requires the bundle attestation creator to match.
RequireCreator string
// VersionConstraint is a version constraint expression for the CLI version.
// Supports operators: >=, >, <=, <, ==, !=.
// A bare version (e.g. "0.8.0") is treated as ">= 0.8.0".
VersionConstraint string
}
Policy defines verification requirements to enforce after verification.
type TrustLevel ¶
type TrustLevel string
TrustLevel represents the verification trust level of a bundle.
const ( // TrustUnknown indicates missing checksum files, or an attestation // (bundle or binary) that is present but fails verification. A present // binary attestation whose digest cannot be extracted, or that does not // verify, is a hard failure — unknown, never a degraded attested (#1550). TrustUnknown TrustLevel = "unknown" // TrustUnverified indicates checksums are valid but no attestation files exist // (bundle was created with --attest not used). TrustUnverified TrustLevel = "unverified" // TrustAttested indicates the full chain is cryptographically verified but // external data (--data) was used, capping trust because the data's own // provenance is unknown. TrustAttested TrustLevel = "attested" // TrustVerified indicates checksums valid, bundle attestation verified, // binary attestation verified with identity pinned to NVIDIA CI, and no // external data. TrustVerified TrustLevel = "verified" )
func ParseTrustLevel ¶
func ParseTrustLevel(s string) (TrustLevel, error)
ParseTrustLevel parses a string into a TrustLevel.
func (TrustLevel) MeetsMinimum ¶
func (t TrustLevel) MeetsMinimum(minimum TrustLevel) bool
MeetsMinimum returns true if this trust level is at least the given minimum.
type VerifyOptions ¶
type VerifyOptions struct {
// CertificateIdentityRegexp overrides the default identity pinning pattern
// for binary attestation verification. Must BEGIN with
// "https://github.com/NVIDIA/aicr/" (a leading "^" is allowed) and must
// not use top-level alternation; see ValidateIdentityPattern.
// Defaults to TrustedRepositoryPattern if empty.
CertificateIdentityRegexp string
// Key selects public-key verification of the bundle attestation instead of
// keyless certificate-identity verification. A KMS key URI
// (awskms:// | gcpkms:// | azurekms:// | hashivault://) or a local PEM public-key file.
// Independent of CertificateIdentityRegexp, which pins the (separate) binary
// attestation; the two coexist (see #1152).
Key string
// TrustRoot is a path to a sigstore-go trusted_root.json for verifying the
// bundle attestation against a private Fulcio/Rekor. ADDITIVE: unioned with
// AICR's public-good root, so NVIDIA-signed and privately-signed bundles
// both verify. Counterpart to `bundle --fulcio-url`/`--rekor-url`.
// Composable with Key. Does NOT affect the binary attestation, which is
// always NVIDIA-public-CI-signed and stays pinned to the public-good root.
TrustRoot string
// IgnoreTLog enables offline/air-gapped verification of the key-signed
// bundle attestation: it skips the transparency-log (and observer-timestamp)
// requirement so a bundle produced by `bundle --signing-key ... --tlog-upload=false`
// (#409) verifies with no transparency-log network calls. Full offline
// operation additionally requires a local PEM Key: a KMS Key URI still makes a
// live GetPublicKey call via NewKeyVerificationIdentity to resolve the key.
// ONLY valid with Key set (the air-gapped path is key-based, not keyless);
// Verify rejects it otherwise. INSECURE relative to the default: without a
// tlog/timestamp there is no trusted proof of when the signature was made.
// Does NOT affect the keyless or binary-attestation paths, which always
// require a transparency log.
IgnoreTLog bool
}
VerifyOptions configures verification behavior.
type VerifyResult ¶
type VerifyResult struct {
// TrustLevel is the computed trust level for the bundle.
TrustLevel TrustLevel `json:"trustLevel"`
// ChecksumsPassed indicates whether all content files match checksums.txt.
ChecksumsPassed bool `json:"checksumsPassed"`
// ChecksumFiles is the number of files verified by checksum.
ChecksumFiles int `json:"checksumFiles"`
// BundleAttested indicates whether the bundle attestation was verified.
BundleAttested bool `json:"bundleAttested"`
// BinaryAttested indicates whether the binary attestation was verified.
BinaryAttested bool `json:"binaryAttested"`
// IdentityPinned indicates whether the binary attestation identity was pinned to NVIDIA CI.
IdentityPinned bool `json:"identityPinned"`
// BundleCreator is the OIDC identity from the bundle attestation signing certificate.
BundleCreator string `json:"bundleCreator,omitempty"`
// BinaryBuilder is the certificate subject from the binary attestation.
BinaryBuilder string `json:"binaryBuilder,omitempty"`
// ToolVersion is the aicr version extracted from the attestation predicate.
ToolVersion string `json:"toolVersion,omitempty"`
// HasExternalData indicates the bundle contains external data files (data/ directory).
HasExternalData bool `json:"hasExternalData"`
// TrustReason explains why the trust level was set to its current value.
TrustReason string `json:"trustReason,omitempty"`
// Errors contains verification failure messages.
Errors []string `json:"errors,omitempty"`
}
VerifyResult contains the outcome of bundle verification.
func Verify ¶
func Verify( ctx context.Context, bundleDir string, opts *VerifyOptions, ) (result *VerifyResult, err error)
Verify performs full verification of a bundle directory. Returns a VerifyResult describing the trust level and verification details. Any returned staged-snapshot cleanup failure clears an otherwise successful result and is reported as an internal error.
func (*VerifyResult) CheckPolicy ¶
func (r *VerifyResult) CheckPolicy(p Policy) (string, error)
CheckPolicy validates the verification result against a policy. Returns an empty string if all checks pass, or a failure description.
func (*VerifyResult) MaxAchievableTrustLevel ¶
func (r *VerifyResult) MaxAchievableTrustLevel() TrustLevel
MaxAchievableTrustLevel returns the highest trust level this bundle could achieve based on its contents. Used by --min-trust-level max to enforce that verification reached the expected level:
- verified: standard bundle with both attestations, no external data
- attested: external data present (caps trust regardless of attestation chain)
- unverified: no attestation files (bundle created without --attest)
- unknown: checksums failed or missing
Note the max is computed from what the bundle CONTAINS, not what verified: a bundle whose binary attestation is present but fails verification reports TrustUnknown while its max achievable stays verified, so --min-trust-level max correctly fails it.