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
- Variables
- func Bundle(files map[string][]byte, key string) (string, error)
- func BundleFiles(rpt *report.Report, results map[string]map[string]scanner.Result, ...) (map[string][]byte, error)
- func CheckManifest(manifest []byte, files map[string][]byte) error
- func Manifest(files map[string][]byte) []byte
- func ReadBundle(r io.Reader) (string, map[string][]byte, error)
- func Sign(data []byte, key string) (string, error)
- func SignReader(r io.Reader, key string) (string, error)
- func Verify(data []byte, signature, key string) error
- func VerifyBundle(files map[string][]byte, key string) error
- func VerifyReader(r io.Reader, signature, key string) error
- func WriteBundle(w io.Writer, root string, files map[string][]byte, modTime time.Time) error
- type BundleOptions
Constants ¶
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.
const FileName = "MANIFEST.sig"
FileName is the bundle entry carrying the signature of ManifestFile.
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.
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 ¶
var ErrBundle = errors.New("seal: bundle is malformed")
ErrBundle is returned when a bundle archive is not in the layout WriteBundle produces.
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.
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.
var ErrManifest = errors.New("seal: manifest is malformed")
ErrManifest is returned when a MANIFEST cannot be parsed.
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.
var ErrMissingKey = errors.New("seal: secret key is required")
ErrMissingKey is returned when sealing or verifying without a secret.
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
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
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
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
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 ¶
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 ¶
SignReader streams from r and returns the canonical signature. Useful when sealing large reports without holding the full byte slice in memory.
func Verify ¶
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
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 ¶
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.
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.