security: make the artifact-integrity envelope algorithm-agile before a second algorithm exists
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 9
- Forks
- 0
- Avg merge
- 3h 3m
- Merged PRs (30d)
- 509
Description
Problem
The digest format is shaped like it names an algorithm and does not. ContentDigestPrefix = "sha256:" is a constant with ContentDigestHexLen = sha256.Size * 2 (pkg/flowstate/v1/digest.go:29-32); validateDigestPin requires exactly that prefix and 64 lower-case hex (plugin/admission.go:149-178); every comparison is a whole-string compare. A sha384: or blake3: pin is a startup error by construction, and PinsConfig is a strict-mode map[string]string (plugin/pins_config.go:20,:40), so a future pins file that grows a signers: or algorithms: key is refused by every older binary. Both refusals are the right direction — which is exactly why the extension shape should be decided once, deliberately, rather than grown under pressure when a second algorithm arrives.
The repository has already made this call twice and written down why: payloadcodec stamps a key id on every ciphertext because rotation "cannot be retrofitted onto history already written" (pkg/flowstate/v1/payloadcodec/payloadcodec.go), and ResolvedPlugin carries claims_schema_version beside claims_digest with an explicit "empty means not asserted" compatibility rule (proto/flowstate/v1/workflow.proto:684-716). Integrity values live in the same two kinds of hard-to-edit place: reviewed operator configuration and durable run pins.
On post-quantum readiness, measured rather than recalled: go.mod pins go 1.27.0, whose standard library carries crypto/mldsa (FIPS 204) with crypto.Signer, PKCS#8/x509 round-trip, and TLS verification support; measured sizes are ML-DSA-44 pk 1312 B / sig 2420 B up to ML-DSA-87 at 2592/4627 (caveat: unavailable under FIPS 140-3 Go module v1.0.0, available v1.26.0+). So a PQ signing arm is a zero-new-dependency option for this toolchain today. One consequence for the format fork: the in-tree JOSE dependency's algorithm set (RS/PS/ES/EdDSA/HS) carries no ML-DSA as read from the module cache — re-verify upstream — so a JWS-shaped envelope would foreclose PQ until that grows. For hybrid classical+PQ, the composition rule has an in-tree precedent worth copying verbatim: webhook verify: requires every declared scheme to pass, not any one (pkg/flowstate/v1/webhookverify.go:99-101), because satisfying only the weaker half would make adding a scheme a way to weaken the control. Both verify, or the launch is refused. The envelope must also inherit the "never none, never HMAC-for-signatures" rule the auth policy already enforces for JOSE (pkg/flowstate/v1/auth/policy.go:487-518).
Desired outcome
A recorded decision on the integrity-envelope container — algorithm identifier, key id, support for multiple signatures with all-must-verify, and the versioning/compatibility rule — decided independently of who signs (trust-root decision filed separately), so the format is not chosen implicitly by whichever library that decision picks.
Acceptance
- A design record states the envelope shape, its compatibility rule for older readers (refusal, not silent ignore — matching today's strict parses), and the hybrid rule.
- Adding a second algorithm (e.g. an ML-DSA arm beside Ed25519) is demonstrably a configuration/registry change, not a format break, argued against the current
sha256:-only spellings.
Constraints and dependencies
Sequenced with the trust-root decision: decide this first or together, otherwise the container gets picked implicitly. #1019 rotates the auth signing key inside JOSE and is precedent, not a home; #1216's rehearsal mints no attestations yet, which is exactly why the envelope can still be chosen freely.
Open questions
Whether digest agility (sha256: → multi-algorithm) and signature agility ride one envelope or two; whether the FIPS-module caveat matters for any deployment this project targets.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading pkg/flowstate/v1/digest.go, plugin/admission.go, plugin/pins_config.go, and the cited payloadcodec, workflow, webhook, and auth-policy code. Compare the current sha256-only validation and strict configuration parsing with the stated algorithm, key-id, multi-signature, and compatibility questions. Done means a design record answers those questions and shows that adding an algorithm is a registry or configuration change rather than a format break.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- cryptography, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100