trust

package
v1.13.2 Latest Latest
Warning

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

Go to latest
Published: Jun 11, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

External anchoring of signed checkpoints to the Rekor transparency log.

Rekor (https://docs.sigstore.dev/logging/overview/) is Sigstore's public, append-only transparency log. Anchoring a checkpoint publishes a hashedrekord entry: the SHA-256 of the checkpoint payload, the Ed25519 signature over it, and the public key. Once accepted, the entry is publicly fetchable and cannot be removed, so a third party can confirm the chain head existed at the integrated time without trusting the operator of this gateway.

Rekor does not yet verify ML-DSA signatures, which is why checkpoints are dual-signed: ML-DSA-65 travels in the local evidence bundle, Ed25519 goes to the log.

Package trust provides cryptographic audit chains, compliance evaluation, and evidence export for the AIR Blackbox Gateway trust layer.

Signed chain checkpoints.

A checkpoint is a canonical snapshot of the audit chain head: the chain length, the hash of the most recent entry, and the time it was cut. Checkpoints are signed with ML-DSA-65 (post-quantum) and Ed25519, so they can be verified locally far into the future and anchored to external transparency logs today.

Threat model: the HMAC chain proves internal consistency, but the operator holds the HMAC secret and could rewrite history. A signed checkpoint that has been anchored externally (see anchor.go) proves the chain head existed at a point in time, in a log the operator does not control.

ML-DSA-65 (FIPS 204) post-quantum digital signature support.

ML-DSA-65 (formerly Dilithium3) is a lattice-based signature scheme standardized by NIST as FIPS 204. It provides 128-bit post-quantum security, meaning signatures remain secure even against future quantum computers.

This module provides:

  • Key generation (keys never leave the machine)
  • Signing of audit chain entries and evidence bundles
  • Verification of ML-DSA-65 signatures
  • Fallback to Ed25519 when circl is not available

The signing key is generated locally and stored in the configured key directory. It never leaves the machine or touches the network.

Package trust — PDF evidence export. Wraps GenerateEvidencePackage() output in a professional compliance report PDF suitable for regulatory handoff.

Requires: github.com/jung-kurt/gofpdf/v2

Index

Constants

View Source
const DefaultRekorServer = "https://rekor.sigstore.dev"

DefaultRekorServer is Sigstore's public Rekor instance.

Variables

This section is empty.

Functions

func ExportPDF added in v1.8.0

func ExportPDF(pkg *EvidencePackage, path string, opts PDFOptions) error

ExportPDF renders an EvidencePackage into a compliance report PDF and writes it to the given path. Returns an error if rendering or file write fails.

func FetchRekorEntry added in v1.13.2

func FetchRekorEntry(server, uuid string) ([]byte, error)

FetchRekorEntry retrieves a previously anchored entry by UUID, so anyone can confirm the anchor exists in the public log.

func Verify added in v1.8.0

func Verify(sd SignedData, data []byte) (bool, error)

Verify checks a signature against the provided public key and data.

func VerifyAttestation

func VerifyAttestation(pkg *EvidencePackage, secret string) bool

VerifyAttestation checks that an evidence package's attestation signature matches its contents. Returns true if the package hasn't been tampered with.

func VerifySignedCheckpoint added in v1.13.2

func VerifySignedCheckpoint(sc SignedCheckpoint) error

VerifySignedCheckpoint verifies every signature in the checkpoint against its payload bytes. It returns an error describing the first failure, or nil if all signatures are valid.

Types

type AuditChain

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

AuditChain maintains an ordered, signed sequence of AIR record hashes. It is safe for concurrent use.

func NewAuditChain

func NewAuditChain(secret string) *AuditChain

NewAuditChain creates a new audit chain with the given HMAC signing key.

func (*AuditChain) Append

func (ac *AuditChain) Append(runID string, recordJSON []byte) ChainEntry

Append adds a new AIR record to the chain. It computes the SHA-256 hash of the record JSON, signs it with the previous entry's hash, and returns the new chain entry.

func (*AuditChain) Entries

func (ac *AuditChain) Entries() []ChainEntry

Entries returns a copy of all chain entries.

func (*AuditChain) Head added in v1.13.2

func (ac *AuditChain) Head() (int64, string)

Head returns the current chain length and head hash. The head hash is empty when the chain has no entries.

func (*AuditChain) Len

func (ac *AuditChain) Len() int64

Len returns the number of entries in the chain.

func (*AuditChain) Verify

func (ac *AuditChain) Verify() (valid bool, brokenAt int64, err error)

Verify walks the chain and checks that every entry's signature is valid and every prev_hash matches the actual hash of the previous entry. Returns (true, 0, nil) if valid, or (false, brokenAt, err) if tampered.

type ChainEntry

type ChainEntry struct {
	Sequence   int64     `json:"sequence"`    // monotonic counter (1-based)
	RunID      string    `json:"run_id"`      // the AIR record this signs
	RecordHash string    `json:"record_hash"` // sha256 of the AIR record JSON
	PrevHash   string    `json:"prev_hash"`   // hash of the previous ChainEntry (empty for first)
	Signature  string    `json:"signature"`   // HMAC-SHA256(sequence|run_id|record_hash|prev_hash, secret)
	Timestamp  time.Time `json:"timestamp"`
}

ChainEntry is one signed link in the audit chain. Each entry includes the hash of the previous entry, forming a tamper-proof chain similar to a blockchain — modifying any record breaks the chain.

type Checkpoint added in v1.13.2

type Checkpoint struct {
	ChainLength int64  `json:"chain_length"`
	HeadHash    string `json:"head_hash"` // sha256 of the latest ChainEntry JSON
	Timestamp   string `json:"timestamp"` // RFC3339 UTC, when the checkpoint was cut
}

Checkpoint is the canonical payload that gets signed and anchored.

func (Checkpoint) PayloadBytes added in v1.13.2

func (c Checkpoint) PayloadBytes() []byte

PayloadBytes returns the canonical bytes that signatures cover. json.Marshal on a struct emits fields in declaration order, so this is deterministic for a given Checkpoint value.

type ComplianceConfig

type ComplianceConfig struct {
	Frameworks []string `yaml:"frameworks" json:"frameworks"`
}

ComplianceConfig holds which frameworks to evaluate.

type ComplianceReport

type ComplianceReport struct {
	GeneratedAt    time.Time `json:"generated_at"`
	GatewayVersion string    `json:"gateway_version"`
	Frameworks     []string  `json:"frameworks"`
	Controls       []Control `json:"controls"`
	Summary        Summary   `json:"summary"`
}

ComplianceReport is the result of evaluating the gateway against one or more compliance frameworks.

func EvaluateCompliance

func EvaluateCompliance(cfg ComplianceConfig, chainLen int64, hasVault bool, hasGuardrails bool, hasAnalytics bool) *ComplianceReport

EvaluateCompliance maps gateway capabilities to SOC 2 and ISO 27001 controls and evaluates which ones pass based on the current configuration.

type Control

type Control struct {
	ID             string        `json:"id"`              // e.g. "CC6.1" or "A.12.4.1"
	Framework      string        `json:"framework"`       // "SOC2" or "ISO27001"
	Name           string        `json:"name"`            // human-readable control name
	Description    string        `json:"description"`     // what the control requires
	Status         ControlStatus `json:"status"`          // pass, fail, or partial
	Evidence       string        `json:"evidence"`        // how the gateway satisfies this
	GatewayFeature string        `json:"gateway_feature"` // which layer provides it
}

Control is a single compliance control mapped to a gateway capability.

type ControlStatus

type ControlStatus string

ControlStatus represents whether a compliance control is satisfied.

const (
	ControlPass    ControlStatus = "pass"
	ControlFail    ControlStatus = "fail"
	ControlPartial ControlStatus = "partial"
)

type EvidencePackage

type EvidencePackage struct {
	ExportedAt       time.Time         `json:"exported_at"`
	GatewayID        string            `json:"gateway_id"`
	ChainLength      int64             `json:"chain_length"`
	ChainValid       bool              `json:"chain_valid"`
	ChainBrokenAt    int64             `json:"chain_broken_at,omitempty"`
	AuditEntries     []ChainEntry      `json:"audit_entries"`
	ComplianceReport *ComplianceReport `json:"compliance_report"`
	RecordCount      int64             `json:"record_count"`
	TimeRange        TimeRange         `json:"time_range"`
	Attestation      string            `json:"attestation"` // HMAC of package contents
}

EvidencePackage bundles the audit chain, compliance report, and verification results into a single exportable JSON document for regulators and auditors.

func GenerateEvidencePackage

func GenerateEvidencePackage(chain *AuditChain, compliance *ComplianceReport, gatewayID string, secret string) *EvidencePackage

GenerateEvidencePackage creates a signed evidence package from the current audit chain and compliance report. The package itself is signed with HMAC-SHA256 so regulators can verify the export hasn't been tampered with.

type PDFOptions added in v1.8.0

type PDFOptions struct {
	Title       string // report title (default: "AIR Blackbox — Compliance Evidence Report")
	Subtitle    string // subtitle line (default: "Generated by AIR Blackbox Gateway")
	CompanyName string // organization name shown on cover
	LogoPath    string // optional path to logo image (PNG/JPG)
}

PDFOptions configures the PDF report layout.

type RekorAnchor added in v1.13.2

type RekorAnchor struct {
	Server         string `json:"server"`
	UUID           string `json:"uuid"`
	LogIndex       int64  `json:"log_index"`
	IntegratedTime int64  `json:"integrated_time"` // unix seconds, per the log
	AnchoredAt     string `json:"anchored_at"`     // RFC3339, local clock
	AlreadyExisted bool   `json:"already_existed"`
}

RekorAnchor is the receipt returned after a checkpoint is accepted by (or already present in) the transparency log.

func AnchorToRekor added in v1.13.2

func AnchorToRekor(server string, sc SignedCheckpoint) (RekorAnchor, error)

AnchorToRekor publishes the Ed25519 signature from a signed checkpoint to the given Rekor server. The checkpoint must contain an Ed25519 signature; it errors otherwise with an explanation.

type SignatureAlgorithm added in v1.8.0

type SignatureAlgorithm string

SignatureAlgorithm identifies which algorithm produced a signature.

const (
	AlgoMLDSA65 SignatureAlgorithm = "ML-DSA-65"
	AlgoEd25519 SignatureAlgorithm = "Ed25519"
)

type SignedCheckpoint added in v1.13.2

type SignedCheckpoint struct {
	Checkpoint Checkpoint    `json:"checkpoint"`
	Signatures []SignedData  `json:"signatures"`
	Anchors    []RekorAnchor `json:"anchors,omitempty"`
}

SignedCheckpoint bundles a checkpoint with one or more signatures over its payload bytes.

func CheckpointFromEntries added in v1.13.2

func CheckpointFromEntries(entries []ChainEntry, signers ...*Signer) (SignedCheckpoint, error)

CheckpointFromEntries cuts a checkpoint from exported chain entries, as returned by GET /v1/audit/export. The head hash is recomputed from the final entry, so it matches a checkpoint cut against the live chain.

func CreateCheckpoint added in v1.13.2

func CreateCheckpoint(ac *AuditChain, signers ...*Signer) (SignedCheckpoint, error)

CreateCheckpoint cuts a checkpoint at the current chain head and signs it with every provided signer. At least one signer is required and the chain must not be empty.

type SignedData added in v1.8.0

type SignedData struct {
	Algorithm SignatureAlgorithm `json:"algorithm"`
	Signature string             `json:"signature"`  // hex-encoded
	PublicKey string             `json:"public_key"` // hex-encoded
	SignedAt  string             `json:"signed_at"`
}

SignedData wraps a signature with metadata for verification.

type Signer added in v1.8.0

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

Signer provides post-quantum signing and verification.

func NewSigner added in v1.8.0

func NewSigner(keyDir string) (*Signer, error)

NewSigner creates a Signer with ML-DSA-65 key generation. Keys are stored in keyDir. If keys already exist, they are loaded. If circl is not available at compile time, falls back to Ed25519.

func NewSignerEd25519 added in v1.13.2

func NewSignerEd25519(keyDir string) (*Signer, error)

NewSignerEd25519 creates a Signer that uses Ed25519 regardless of ML-DSA availability. Rekor and most current transparency logs verify Ed25519 but not yet ML-DSA, so anchored checkpoints carry both signature types.

func (*Signer) Algorithm added in v1.8.0

func (s *Signer) Algorithm() SignatureAlgorithm

Algorithm returns which signature algorithm is active.

func (*Signer) Sign added in v1.8.0

func (s *Signer) Sign(data []byte) (SignedData, error)

Sign signs arbitrary data and returns a SignedData structure.

func (*Signer) SignChain added in v1.8.0

func (s *Signer) SignChain(chain *AuditChain) (SignedData, error)

SignChain signs the entire audit chain and returns a SignedData.

func (*Signer) SignEvidencePackage added in v1.8.0

func (s *Signer) SignEvidencePackage(pkg *EvidencePackage) (SignedData, error)

SignEvidencePackage signs an evidence package JSON.

type Summary

type Summary struct {
	TotalControls int     `json:"total_controls"`
	Passing       int     `json:"passing"`
	Failing       int     `json:"failing"`
	Partial       int     `json:"partial"`
	PassRate      float64 `json:"pass_rate"`
}

Summary provides aggregate pass/fail counts for a compliance report.

type TimeRange

type TimeRange struct {
	Earliest time.Time `json:"earliest"`
	Latest   time.Time `json:"latest"`
}

TimeRange captures the earliest and latest timestamps in the audit chain.

Jump to

Keyboard shortcuts

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