Watch
1
0
Fork
You've already forked RedFlag
0
RedFlag/server/internal/services/posture.go
Fimeg e2dab2845a supply-chain: gate our own deps, ship the verdict signed
dep-scan.sh gates go/npm/cargo on push and bakes an attested posture into the
release — embedded in the server, signed into the manifest. Reasoning and the
two Moby exceptions are in SECURITY.md.

(posture-builder runs rustup; bookworm's cargo is too old for cargo-audit.)
2026-06-14 11:43:23 -04:00

78 lines
3 KiB
Go

package services
import (
_ "embed"
"encoding/json"
"log"
)
// Supply-chain posture — RedFlag's attestation of its OWN dependency hygiene,
// folded into the signed release manifest so it rides the same Ed25519 trust
// root as the binaries. The installer verifies the manifest signature before
// trusting any of this, so the posture cannot be forged by editing a file next
// to the binary: tamper breaks the signature and the install refuses.
//
// The content is generated at build time by scripts/dep-scan.sh (the same gate
// that fails the release on an un-accepted reachable vulnerability) and embedded
// here. A bare `go build` outside that pipeline embeds the committed stub with
// Attested=false — an honest "this build was not gated", which the installer
// treats as a refusal-worthy posture.
//go:embed posture-build.json
var postureBuildJSON []byte
// DependencyException is a known, accepted reachable vulnerability with the
// documented reason it is tolerated. Mirrors a line in .govulncheck-allow.
type DependencyException struct {
ID string `json:"id"`
Reason string `json:"reason"`
}
// EcosystemScan is one scanner's verdict over one ecosystem.
type EcosystemScan struct {
Ecosystem string `json:"ecosystem"` // go, npm, cargo
Tool string `json:"tool"` // govulncheck, npm-audit, cargo-audit
Status string `json:"status"` // clean, accepted, blocked
Accepted int `json:"accepted"`
Blocked int `json:"blocked"`
}
// SupplyChainPosture is RedFlag's own dependency attestation for this build.
type SupplyChainPosture struct {
// Attested is true only when this posture was produced by the gated build
// pipeline. A stub/dev build is Attested=false.
Attested bool `json:"attested"`
GeneratedAt int64 `json:"generated_at"`
Substrate map[string]string `json:"substrate"` // go, rustc, node, npm, docker versions
Scans []EcosystemScan `json:"scans"`
Exceptions []DependencyException `json:"exceptions"`
}
// Blocked reports whether any ecosystem carries an un-accepted reachable vuln.
// A clean build never embeds a blocked scan (the gate fails the release first),
// so this is defense-in-depth for a tampered or hand-built artifact.
func (p SupplyChainPosture) Blocked() bool {
for _, s := range p.Scans {
if s.Blocked > 0 {
return true
}
}
return false
}
// loadEmbeddedPosture parses the build-time posture. A parse failure is logged
// and degraded to an explicit un-attested posture rather than a crash — the
// manifest still signs, and the installer refuses on Attested=false.
func loadEmbeddedPosture() SupplyChainPosture {
var p SupplyChainPosture
if err := json.Unmarshal(postureBuildJSON, &p); err != nil {
log.Printf("[ERROR] [server] [posture] embedded posture-build.json unparseable: %v", err)
return SupplyChainPosture{Attested: false}
}
return p
}
// EmbeddedPosture returns the build-time supply-chain posture for this server.
func EmbeddedPosture() SupplyChainPosture {
return loadEmbeddedPosture()
}