seal

package
v0.14.0 Latest Latest
Warning

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

Go to latest
Published: Oct 31, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package seal provides HMAC-SHA256 sealing for export bundles. The intent is auditor-grade tamper detection: an operator configures a secret with --seal-key, the bundle carries a MANIFEST that lists every file with its SHA-256, the secret signs the MANIFEST, and "fleetsweeper verify" checks the signature and then every file against the MANIFEST. The signature format and header conventions mirror the inbound webhook signature scheme so a single secret style is reusable across the tool.

Index

Constants

View Source
const DefaultPolicyReportNamespace = "fleetsweeper"

DefaultPolicyReportNamespace is the namespace placed on bundled PolicyReports when BundleOptions leaves it empty. The server's seal endpoint always uses it, so an export made with the default seals to the same signature as the endpoint.

View Source
const FileName = "MANIFEST.sig"

FileName is the bundle entry carrying the signature of ManifestFile.

View Source
const ManifestFile = "MANIFEST"

ManifestFile is the bundle entry listing every other file with its SHA-256. The signature covers it, so it vouches for every file it lists.

View Source
const Prefix = "sha256="

Prefix is the algorithm tag emitted on every signature. The canonical header form is "sha256=<lowercase hex>", chosen for consistency with the inbound webhook signature header.

Variables

View Source
var ErrBundle = errors.New("seal: bundle is malformed")

ErrBundle is returned when a bundle archive is not in the layout WriteBundle produces.

View Source
var ErrContents = errors.New("seal: bundle contents do not match the manifest")

ErrContents is returned when a bundle's files do not match its MANIFEST: a listed file is missing or altered, or a file is not listed.

View Source
var ErrMalformed = errors.New("seal: signature is malformed")

ErrMalformed is returned when a signature header is missing the expected "sha256=" prefix or is not valid hex.

View Source
var ErrManifest = errors.New("seal: manifest is malformed")

ErrManifest is returned when a MANIFEST cannot be parsed.

View Source
var ErrMismatch = errors.New("seal: signature mismatch")

ErrMismatch is returned when a signature does not match the data. This is the value to look for when reporting tamper detection.

View Source
var ErrMissingKey = errors.New("seal: secret key is required")

ErrMissingKey is returned when sealing or verifying without a secret.

View Source
var ErrUnsealed = errors.New("seal: bundle is not sealed")

ErrUnsealed is returned when verifying a bundle that has no MANIFEST or no signature.

Functions

func Bundle added in v0.12.0

func Bundle(files map[string][]byte, key string) (string, error)

Bundle adds ManifestFile and its signature under FileName to files and returns the signature.

func BundleFiles added in v0.10.0

func BundleFiles(rpt *report.Report, results map[string]map[string]scanner.Result, scanID string,
	opts BundleOptions) (map[string][]byte, error)

BundleFiles returns every file of the export bundle for one stored scan, keyed by path relative to the bundle root. Every file derives from rpt, results, scanID, and opts alone, so the same scan yields the same bytes on every call. rpt must be built with the scan's own timestamp for that to hold.

func CheckManifest added in v0.10.0

func CheckManifest(manifest []byte, files map[string][]byte) error

CheckManifest verifies that files match manifest exactly: every listed file is present with the listed digest, and every file other than ManifestFile and FileName is listed. It does not check the signature; callers verify the manifest's signature first. The error wraps ErrContents and names each missing, altered, and unlisted file.

func Manifest added in v0.10.0

func Manifest(files map[string][]byte) []byte

Manifest returns the MANIFEST for files, keyed by path relative to the bundle root: one "<sha256 hex> <path>" line per file, sorted by path, the layout sha256sum writes. Entries named ManifestFile or FileName are left out.

func ReadBundle added in v0.10.0

func ReadBundle(r io.Reader) (string, map[string][]byte, error)

ReadBundle reads a bundle in the layout WriteBundle produces and returns its root directory and its files keyed by path relative to that root. Entries outside a single root, entries that are not regular files, paths that climb with "..", and duplicate paths are errors, so nothing in the archive can hide from verification.

func Sign

func Sign(data []byte, key string) (string, error)

Sign returns the canonical "sha256=<hex>" signature for data using key. Returns ErrMissingKey when key is empty so callers cannot accidentally produce a constant-zero seal.

func SignReader

func SignReader(r io.Reader, key string) (string, error)

SignReader streams from r and returns the canonical signature. Useful when sealing large reports without holding the full byte slice in memory.

func Verify

func Verify(data []byte, signature, key string) error

Verify recomputes the signature for data with key and constant-time compares it against signature. Returns ErrMalformed, ErrMissingKey, or ErrMismatch on failure so callers can distinguish operator error (missing key, wrong header format) from tamper detection.

func VerifyBundle added in v0.10.0

func VerifyBundle(files map[string][]byte, key string) error

VerifyBundle checks that FileName is a valid signature of ManifestFile under key, then that every file matches the manifest. A bundle without either entry returns ErrUnsealed.

func VerifyReader

func VerifyReader(r io.Reader, signature, key string) error

VerifyReader is the streaming variant of Verify. It exists so the verify command can validate a multi-megabyte report.json without allocating the full body up front.

func WriteBundle added in v0.10.0

func WriteBundle(w io.Writer, root string, files map[string][]byte, modTime time.Time) error

WriteBundle writes files as a gzipped tar with every entry under root, in path order, each stamped with modTime truncated to the second. Equal inputs give equal bytes.

Types

type BundleOptions added in v0.10.0

type BundleOptions struct {
	// PolicyReportNamespace is the namespace on bundled PolicyReports. Empty means
	// DefaultPolicyReportNamespace.
	PolicyReportNamespace string
	// Cost is the cost correlation to include as cost.json. Nil leaves it out.
	Cost *cost.Analysis
	// Sealed records in METADATA.txt that the bundle carries a MANIFEST and signature.
	Sealed bool
}

BundleOptions selects the optional contents of an export bundle.

Jump to

Keyboard shortcuts

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