Documentation
¶
Overview ¶
Package verify checks a DSSE attestation against a bundle and a trust roster, emitting SG-PRV findings (design §7.3, rule-verification.md §4).
Index ¶
Constants ¶
const ( FormatSGMT1 = "sgmt-1" FormatOMS = "oms" )
Signature formats a Result can describe. A consumer reads Format to know which trust path produced the verdict — the two formats have different guarantees, and reporting one as the other would hide that.
Variables ¶
var ( ErrNotACard = errors.New("not a surfaceguard skill card") ErrUnsupportedSchema = errors.New("unsupported skill-card schema version") ErrNoContentHash = errors.New("card has no content_hash (emitted before v1 gained one)") )
Errors a card document can fail with before it can be checked against anything. These are malformed *input*, not a failed verification: a file that is not a surfaceguard card cannot make a false claim about a bundle, so the caller reports them as usage errors rather than as tampering.
var ErrNoSignatureFile = errors.New("verify: bundle has no signature file")
ErrNoSignatureFile is returned by DetectFormats when a bundle carries neither signature.
Functions ¶
func CardVerificationFailed ¶
func CardVerificationFailed(res *CardResult) bool
CardVerificationFailed decides exit code 2 for a card check. A mismatch is a claim that has been shown false, which is the same class as SG-PRV-003.
Types ¶
type CardResult ¶
type CardResult struct {
// Card is the parsed card, for a caller that wants to show its claims.
Card *scan.Card
// CardHash is the content hash the card asserts; BundleHash is the root
// recomputed from the bundle on disk. Match reports whether they agree —
// the whole point of the check.
CardHash string
BundleHash string
Match bool
Findings []model.Finding
}
CardResult is the outcome of checking a card against the bundle it claims to describe: does this card's subject exist, and is it this one?
func VerifyCard ¶
func VerifyCard(b *skill.Bundle, card *scan.Card) *CardResult
VerifyCard checks a parsed card against a bundle. The comparison is the bundle's SGMT-1 Merkle root — the same value an attestation signs — so a card verifies exactly when it describes this bundle, byte for byte, and stops verifying the moment one file changes.
This is deliberately *not* a re-scan. A card's verdict and risk score are products of the policy in force when it was emitted; re-deriving them under the verifier's own policy would report a policy difference as a card defect. What a card can honestly be held to is its subject.
type Result ¶
type Result struct {
// Format is the signature format this result describes (FormatSGMT1 or
// FormatOMS).
Format string
Present bool
SignatureValid bool // at least one cryptographically valid signature
Trusted bool // a valid signature from a roster key
// Revoked reports that every signature which verified did so with a key the
// roster lists under `revoked`. It is not the negation of Trusted: a key that
// is simply absent from the roster leaves both false, and the two states need
// different words — "the key is revoked" is a decision the consumer made,
// "the key is unknown" is one they have not made yet.
Revoked bool
// IdentityRejected reports a signature that verified with a roster key
// whose identity no trust.identities rule admits. It is distinct from
// Revoked — the consumer did not reject *this publisher*, they scoped which
// identities they accept — and from an unknown key, which is no decision at
// all.
IdentityRejected bool
MerkleMatch bool
// Certificate-bound (keyless) details, set only for a certificate or
// sigstore OMS bundle. CertError explains why such a signature could not be
// established — most often that no roots are configured, which is a
// consumer decision rather than a defect.
CertIdentity string
CertIssuer string
CertError string
SignedAt time.Time
// LogInclusionVerified reports that the transparency-log inclusion proof
// reconstructs its claimed root — the entry really is in that tree.
// LogCheckpointVerified additionally reports that a log key the consumer
// pinned signed the checkpoint committing to that tree, which is what makes
// it *the* log rather than any tree at all.
LogInclusionVerified bool
LogCheckpointVerified bool
Expired bool
Publisher string
Statement *attest.Statement
Findings []model.Finding
}
Result summarizes verification.
func VerifyOMS ¶
VerifyOMS checks an OpenSSF Model Signing bundle against the skill on disk and the trust roster, reporting the same SG-PRV states the SGMT-1 path does so a consumer does not need to know which format was used.
Two trust paths are supported. A `key` bundle is checked against the roster's public keys. A `certificate` or `sigstore` bundle is checked against the consumer's configured CA roots, and the identity bound into the certificate is then admitted (or not) by trust.identities — which is what makes keyless signing usable without anyone holding a long-lived key.
data is the raw skill.oms.sig. Pass **nil** when the file is absent; an empty but non-nil slice means the file exists and is empty, which is a malformed bundle rather than a missing one — the spec's own `invalid/empty.bundle.json` vector is exactly that case, and reporting it as "unsigned" would let a truncated signature look like a skill nobody had signed yet.
func VerifyOMSAt ¶
VerifyOMSAt is VerifyOMS with the directory that relative trust.roots paths are resolved against — normally the directory holding the policy file, so a policy means the same thing wherever the command is run from.