-
Notifications
You must be signed in to change notification settings - Fork 0
feat(release): keyless cosign, SPDX SBOM, and SLSA on the same tag #108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
seonghobae
merged 6 commits into
feat/issue-84-signed-release
from
feat/issue-84-cosign-sbom
Aug 25, 2026
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
ef89a7e
feat(release): keyless cosign, SPDX SBOM, and SLSA on the same tag
seonghobae 550c237
feat(release): refuse lightweight tags and pin k8s by digest
seonghobae 2119788
docs: record PR #109 in the product-technical gap baseline
seonghobae d00c78f
feat(waf): detect OWASP CRS attack battery on the live binary
seonghobae f62e7ab
Merge pull request #110 from ContextualWisdomLab/feat/issue-11-attack…
seonghobae b8094c4
Merge pull request #109 from ContextualWisdomLab/feat/issue-84-unsign…
seonghobae File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| # Doctoring — CI attack-evidence battery (issue #11) | ||
|
|
||
| This note grounds the issue #11 slice: the compiled gateway binary is started | ||
| in CI with a hermetic libcoraza engine, a deterministic OWASP CRS attack | ||
| battery is fired over real HTTP, and every attempt must be blocked with the | ||
| cited CRS rule id and recorded as a security event that keeps the forwarded | ||
| client IP unmasked. | ||
|
|
||
| ## What is proven (and what is not) | ||
|
|
||
| Proven end to end on the real binary: operator-supplied `CORAZA_LIB_PATH` | ||
| loading, rules-file admission, per-transaction evaluation of method/URI/body, | ||
| block responses citing `coraza/crs: rule <id>`, benign traffic still | ||
| forwarding, and unmasked client attribution in `/api/events`. | ||
|
|
||
| Not proven: detection *quality* against arbitrary live traffic. The CI engine | ||
| is the build-script ABI stub (`src/coraza_abi_stub.rs`), a fixture that | ||
| mirrors the libcoraza C ABI, not Coraza itself. Quality evidence stays with an | ||
| operator deployment using a real libcoraza plus the OWASP Core Rule Set; this | ||
| slice only removes "the path was never exercised in CI" from the gap list. | ||
|
|
||
| ## Adopted standards and literature | ||
|
|
||
| OWASP Foundation. (n.d.). *OWASP Core Rule Set documentation*. | ||
| https://coreruleset.org/docs/ | ||
|
|
||
| - **Design impact:** Battery entries map to canonical CRS rule families — | ||
| 942100 SQLi (libinjection), 941100 XSS (libinjection), 930100 path | ||
| traversal, 932100 Unix command injection, 944120 Log4j JNDI. Rule ids in | ||
| block reasons and events stay CRS ids so operator dashboards read the same | ||
| vocabulary in CI evidence and production. | ||
|
|
||
| Scarfone, K., & Mell, P. (2007). *Guide to intrusion detection and prevention | ||
| systems (IDPS)* (NIST Special Publication 800-94). National Institute of | ||
| Standards and Technology. https://doi.org/NIST.SP.800-94 | ||
|
|
||
| - **Design impact:** IDPS evaluation distinguishes the detection *path* from | ||
| detection *efficacy*. SP 800-94's testing guidance motivates keeping the two | ||
| claims separate: CI asserts the prevention path (signature → interrupt → | ||
| block → record), while efficacy against evasive payloads requires curated | ||
| corpora and is explicitly out of scope for this fixture. | ||
|
|
||
| Saltzer, J. H., & Schroeder, M. D. (1975). The protection of information in | ||
| computer systems. *Proceedings of the IEEE*, *63*(9), 1278–1308. | ||
| https://doi.org/10.1109/PROC.1975.9939 | ||
|
|
||
| - **Design impact:** Complete mediation and fail-safe defaults. The battery | ||
| runs through the same route pipeline (`mode: block`) as production traffic, | ||
| so no test-only bypass exists; an engine that fails to load refuses startup | ||
| before bind instead of degrading silently. | ||
|
|
||
| MITRE. (n.d.). *CWE-20: Improper input validation*. MITRE Corporation. | ||
| https://cwe.mitre.org/data/definitions/20.html | ||
|
|
||
| - **Design impact:** The battery covers encoded variants (`%3Cscript`, | ||
| `%24%7BJNDI`, `..%2F`) because input-validation defects classically live at | ||
| decoding boundaries; the gateway evaluates the raw request line exactly as | ||
| received, so fixtures pin that behavior rather than a decoded copy. | ||
|
|
||
| ## Verification posture | ||
|
|
||
| - `tests/binary.rs::live_gateway_detects_owasp_attack_battery_end_to_end` | ||
| spawns the binary, creates the block route over the admin API, fires nine | ||
| battery cases (GET query attacks across five rule families plus a POST-body | ||
| XSS), asserts HTTP 403 + `engine=coraza` + cited rule id per case, asserts a | ||
| benign request forwards, and asserts `/api/events` records one event per | ||
| attempt with `X-Forwarded-For` preserved verbatim. | ||
| - `src/coraza_inprocess.rs::stub_engine_battery_matches_each_owasp_family` | ||
| pins the fixture contract itself, including first-match ordering so the | ||
| overlapping `; cat /etc/passwd` payload attributes to RCE (932100), not | ||
| traversal. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| # Doctoring — signed release, SBOM, and provenance | ||
|
|
||
| This note grounds issue #84 remainder (keyless Sigstore signatures and | ||
| SBOM/SLSA attestations on the same `vX.Y.Z` tag as checksums/GHCR). | ||
| IEEE/ACM PDFs are not redistributed. NIST SP 800-218 is a U.S. government | ||
| work and is committed at `docs/papers/nist-sp-800-218-ssdf.pdf`. | ||
|
|
||
| ## Adopted standards and literature | ||
|
|
||
| Sigstore. (n.d.). *Cosign documentation*. https://docs.sigstore.dev/cosign/ | ||
|
|
||
| - **Design impact:** The release workflow uses GitHub OIDC (`id-token: write`) | ||
| for keyless signing. No long-lived Cosign key is stored. Blobs (binary, | ||
| `SHA256SUMS`, SBOMs, image digest file) get `cosign sign-blob` bundles. | ||
| The GHCR image is signed by digest (`image@sha256:…`), never by a moving | ||
| tag. | ||
|
|
||
| SLSA Project. (2025). *SLSA specification version 1.2*. | ||
| https://slsa.dev/spec/v1.2/ | ||
|
|
||
| - **Design impact:** `actions/attest-build-provenance` binds the binary and | ||
| the image digest to in-toto SLSA provenance. `actions/attest-sbom` binds | ||
| SPDX SBOMs to the same subjects. GitHub Release is created only after | ||
| signatures and attestations succeed. | ||
|
|
||
| National Institute of Standards and Technology. (2022). *Secure Software | ||
| Development Framework (SSDF) version 1.1* (NIST SP 800-218). | ||
| https://doi.org/10.6028/NIST.SP.800-218 | ||
| `docs/papers/nist-sp-800-218-ssdf.pdf` | ||
|
|
||
| - **Design impact:** PS.3 / PW.4 — produce integrity evidence (checksums, | ||
| SBOM, signatures, provenance) for the shipped artifact. A tag alias is | ||
| not promotion authority; operators verify the digest and signatures | ||
| (`docs/runbooks/release.md`). | ||
|
|
||
| Anchore. (n.d.). *Syft*. https://github.com/anchore/syft | ||
|
|
||
| - **Design impact:** `scripts/release-sbom.sh` fails closed without Syft and | ||
| rejects non-SPDX JSON. Binary and container filesystem SBOMs are both | ||
| attached to the GitHub Release. | ||
|
|
||
| ## Operator next action | ||
|
|
||
| Tag `vX.Y.Z` from the reviewed merge commit on `main`. After the Release | ||
| workflow finishes, verify with the commands in `docs/runbooks/release.md`. | ||
| Point Kubernetes at the digest in `IMAGE-DIGEST.txt`, not at `latest`. |
Binary file not shown.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔴 Docker push digest parses the image size, not the digest
awk '/digest:/{d=$NF}'takes the last field of the docker push line<tag>: digest: sha256:<hex> size: <n>, which is the numeric size, not thesha256:digest.test -npasses on the non-empty number, so the release proceeds withref=ghcr.io/...@<size>and feeds that bad digest to every cosign and attestation step.Was this helpful? React with 👍 or 👎 to provide feedback.