# Security Threat Model & Signed Releases (https://jackin.tailrocks.com/roadmap/security-threat-model-and-signed-releases/)



**Status**: Partially implemented — signing/release artifacts have shipped in dev releases, and operator artifact verification passed end to end against `jackin-dev-v0.1.13` on 2026-07-04; clean-cache capsule download verification and residual Fulcio-chain hardening remain

## Problem [#problem]

jackin❯ closed two credibility gaps with this work:

* **Undocumented security implementation.** Symlink rejection in <RepoFile path="crates/jackin-instance/src/auth.rs">crates/jackin-instance/src/auth.rs</RepoFile>, `shellfirm` and `tirith` in the construct image, and the YOLO-flag contract in <RepoFile path="docker/runtime/entrypoint.sh">docker/runtime/entrypoint.sh</RepoFile> were enforced in code but invisible to operators, role authors, and contributors who reason about the trust boundary.
* **Unsigned capsule binary.** `jackin-capsule` is downloaded into every container at runtime (<RepoFile path="crates/jackin-image/src/capsule_binary.rs">crates/jackin-image/src/capsule\_binary.rs</RepoFile>) and was verified by SHA256 only — no signing, no SLSA provenance, no SBOM. A tampered artifact matching the expected SHA256 would go undetected.

## Shipped [#shipped]

All implementation landed on this branch. Operator and contributor detail now live in canonical docs, not here:

* **Security implementation** — threat model, the six `auth.rs` security functions, `shellfirm`/`tirith` rationale, and the YOLO-flag contract for all five agents → [/reference/security-implementation/](/reference/security-implementation/).
* **Release verification** — cosign keyless verification, SLSA provenance, SBOM inspection, and capsule-manifest auditing → [/getting-started/verifying-releases/](/getting-started/verifying-releases/).
* **CI signing** — cosign `sign-blob` bundles, `actions/attest-build-provenance` SLSA attestations, and `syft` CycloneDX SBOMs for every archive in <RepoFile path=".github/workflows/release.yml">.github/workflows/release.yml</RepoFile> and <RepoFile path=".github/workflows/preview.yml">.github/workflows/preview\.yml</RepoFile>; the capsule build jobs additionally produce a signed `capsule-manifest.json` + `capsule-manifest.json.bundle`.
* **Operator artifact verification** — `cargo xtask release-verify <archive>.tar.gz` checks the published `.sha256`, cosign bundle identity/issuer, GitHub artifact attestation, and SBOM JSON. The gate passed against `jackin-dev-v0.1.13` (`jackin-dev-0.1.13-aarch64-unknown-linux-gnu.tar.gz`, published 2026-07-02) on 2026-07-04, and a tampered archive copy failed closed at the digest check.
* **In-process verification** — `fetch_and_verify_manifest` in <RepoFile path="crates/jackin-image/src/capsule_binary.rs">crates/jackin-image/src/capsule\_binary.rs</RepoFile> verifies the cosign bundle (embedded Sigstore production Rekor key via `ManualTrustRoot`, no TUF network call), pins the certificate SAN to the `release.yml` / `preview.yml` signing workflows, and hard-aborts on any failure — no warn-and-continue. The `JACKIN_CAPSULE_BIN` override and Homebrew-packaged binaries bypass the download path unchanged.

## Remaining [#remaining]

* **Clean-cache capsule download gate.** Dev releases now exist after the signing workflows landed (latest observed: `jackin-dev-v0.1.13`, 2026-07-02). Operator archive verification is proven by `cargo xtask release-verify`, but the remaining in-process gate is a clean-cache capsule download against one of those signed bundles; unit and integration tests still bypass it (`cfg!(test)` stub plus `JACKIN_CAPSULE_BIN`). Confirm before treating the download path as proven:

  ```bash
  rm -rf ~/.jackin/cache/jackin-capsule/
  unset JACKIN_CAPSULE_BIN
  cargo run --bin jackin -- console --debug   # expect: "capsule manifest signature verified"
  ```

  If verification regresses, `JACKIN_CAPSULE_BIN=/path/to/jackin-capsule` unblocks launches while a fix lands.
* **Rekor key rotation.** The embedded `SIGSTORE_REKOR_PUB_KEY_B64` in <RepoFile path="crates/jackin-image/src/capsule_binary.rs">crates/jackin-image/src/capsule\_binary.rs</RepoFile> must be updated when Sigstore rotates the production Rekor signing key (announced at blog.sigstore.dev).
* **Fulcio certificate chain not validated (known residual).** `Client::verify_blob` in sigstore-rs 0.14 does not chain-verify the certificate to a Fulcio root or check the OIDC issuer. The Rekor body cross-check (`verify_rekor_body_binds_bundle`) now closes the field-swap attack (an attacker can no longer keep a legitimate Rekor SET and substitute a self-signed cert, because the body hash and cert fields are verified against each other). However, an attacker who can forge a Rekor log entry (extremely high bar — requires the Rekor private key) or who obtains a Fulcio-issued cert with a matching SAN through any other means would still pass all checks. Full closure requires adding Fulcio root cert pool validation using `x509-cert`'s chain-building API against embedded Fulcio intermediate and root certs, or upgrading to a higher-level sigstore-rs API that includes the full keyless verification contract.

This item retires once the capsule download path has been clean-cache verified end to end and the remaining verification residuals are either fixed or explicitly accepted.

## Non-goals [#non-goals]

* No hostile multi-tenant safety claim from Docker hardening alone — that is [Docker runtime hardening contract](/roadmap/docker-runtime-hardening-contract/) scope.
* No microVM replacement — [smolvm backend research](/reference/research/isolation/smolvm-backend/) tracks that separately.
* No retroactive signing of historical releases — provenance starts from the first workflow that includes signing.
* No source-level (`cargo-cyclonedx`) SBOM — `syft scan` on the binary archive is sufficient for the supply chain transparency goal here.

## Related roadmap items [#related-roadmap-items]

| Item                                                                                                             | Relationship                                                                    |
| ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| [Docker runtime hardening contract](/roadmap/docker-runtime-hardening-contract/)                                 | Container escape is out of scope for this item; Docker hardening tracks that    |
| [Process-level sandboxing](/reference/research/security/process-sandboxing/process-level-sandboxing/)            | Per-operation isolation inside the container; complementary to the threat model |
| [smolvm backend research](/reference/research/isolation/smolvm-backend/)                                         | Future microVM backend that addresses the shared-kernel residual risk           |
| [Network egress policy](/roadmap/network-egress-policy/)                                                         | Network exfiltration threat is tracked there                                    |
| [Container credential exposure](/reference/research/security/credential-exposure/container-credential-exposure/) | Credential safety beyond symlink rejection                                      |
| [Rust CI tooling](/reference/research/ci/rust-tooling/rust-ci-tooling/)                                          | CI workflow patterns that signing and SBOM generation follow                    |

## Related files [#related-files]

* <RepoFile path="crates/jackin-image/src/capsule_binary.rs">crates/jackin-image/src/capsule\_binary.rs</RepoFile> — `fetch_and_verify_manifest`, embedded Rekor key, SAN identity check
* <RepoFile path=".github/workflows/release.yml">.github/workflows/release.yml</RepoFile> — tagged-release signing + capsule manifest
* <RepoFile path=".github/workflows/preview.yml">.github/workflows/preview\.yml</RepoFile> — rolling-preview signing + capsule manifest
* [/reference/security-implementation/](/reference/security-implementation/) — contributor-facing security internals
* [/getting-started/verifying-releases/](/getting-started/verifying-releases/) — operator-facing verification guide
