Isolation & security

Security Threat Model & 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

jackin closed two credibility gaps with this work:

  • Undocumented security implementation. Symlink rejection in crates/jackin-instance/src/auth.rs, shellfirm and tirith in the construct image, and the YOLO-flag contract in docker/runtime/entrypoint.sh 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 (crates/jackin-image/src/capsule_binary.rs) and was verified by SHA256 only — no signing, no SLSA provenance, no SBOM. A tampered artifact matching the expected SHA256 would go undetected.

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/.
  • Release verification — cosign keyless verification, SLSA provenance, SBOM inspection, and capsule-manifest auditing → /getting-started/verifying-releases/.
  • CI signing — cosign sign-blob bundles, actions/attest-build-provenance SLSA attestations, and syft CycloneDX SBOMs for every archive in .github/workflows/release.yml and .github/workflows/preview.yml; the capsule build jobs additionally produce a signed capsule-manifest.json + capsule-manifest.json.bundle.
  • Operator artifact verificationcargo 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 verificationfetch_and_verify_manifest in crates/jackin-image/src/capsule_binary.rs 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

  • 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:

    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 crates/jackin-image/src/capsule_binary.rs 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

  • No hostile multi-tenant safety claim from Docker hardening alone — that is Docker runtime hardening contract scope.
  • No microVM replacement — smolvm backend research 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.
ItemRelationship
Docker runtime hardening contractContainer escape is out of scope for this item; Docker hardening tracks that
Process-level sandboxingPer-operation isolation inside the container; complementary to the threat model
smolvm backend researchFuture microVM backend that addresses the shared-kernel residual risk
Network egress policyNetwork exfiltration threat is tracked there
Container credential exposureCredential safety beyond symlink rejection
Rust CI toolingCI workflow patterns that signing and SBOM generation follow

On this page