jackin'
RoadmapIsolation & security

Security Threat Model & Signed Releases

Status: Partially implemented (Isolation & security track)

Problem

jackin' closed two credibility gaps with this work:

  • Undocumented security implementation. Symlink rejection in crates/jackin-runtime/src/instance/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.
  • 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

  • First-release activation. Signing and manifest production run only on main builds — they were skipped by design on this feature branch (preview.yml jobs skip off-main; release.yml rejects non-main dispatch). They activate on the first preview/release published after this item merges.

  • End-to-end verification gate. fetch_and_verify_manifest has never executed against a real signed bundle — unit and integration tests bypass it (cfg!(test) stub plus JACKIN_CAPSULE_BIN). After the first signed preview publishes, confirm a clean-cache capsule download verifies end-to-end before treating the 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 first signed release has shipped and the end-to-end verification gate has passed.

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