{"record":{"id":"17eb3bbea81d483a","repo":"astrid-runtime/astrid","slug":"shuttle-for-distro-id-is-unsigned-no-distro","errorCode":null,"errorMessage":"shuttle for '{distro_id}' is unsigned (no [distro.signing] or Distro.sig) — refusing. Re-run with --allow-unsigned to install anyway.","messagePattern":"shuttle for '(.+?)' is unsigned \\(no \\[distro\\.signing\\] or Distro\\.sig\\) — refusing\\. Re-run with --allow-unsigned to install anyway\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/astrid-cli/src/commands/distro/shuttle_install.rs","lineNumber":181,"sourceCode":"        distro: DistroLockMeta {\n            id: distro_id,\n            version: manifest.distro.version,\n            resolved_at: chrono::Utc::now().to_rfc3339(),\n        },\n        capsules: locked,\n        manifest_hash: lock.manifest_hash,\n    };\n    write_lock_to_daemon(&principal, &user_lock).await?;\n\n    eprintln!();\n    eprintln!(\"{}\", Theme::success(\"Offline installation complete.\"));\n    Ok(())\n}\n\n/// Decide whether an unsigned shuttle may proceed to the warning path.\nfn unsigned_shuttle_may_install(distro_id: &str, opts: &InitOpts) -> anyhow::Result<()> {\n    if !opts.allow_unsigned {\n        bail!(\n            \"shuttle for '{distro_id}' is unsigned (no [distro.signing] or Distro.sig) — \\\n             refusing. Re-run with --allow-unsigned to install anyway.\"\n        );\n    }\n    Ok(())\n}\n\n/// Product apply is pin-first; ordinary signed shuttles may first-pin.\nfn trust_policy(opts: &InitOpts) -> trust::TrustPolicy {\n    if opts.require_signed {\n        trust::TrustPolicy::RequireExistingPin\n    } else {\n        trust::TrustPolicy::TofuFirstPin\n    }\n}\n\n/// Install each selected capsule from the verified mirror and return\n/// the resolved [`LockedCapsule`] entries for the user's lock.","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/distro/shuttle_install.rs#L163-L199","documentation":"`unsigned_shuttle_may_install` enforces shuttle signing policy: if the unpacked distro has neither `[distro.signing]` metadata nor a `Distro.sig` signature file, installation is refused unless the user explicitly opts in with `--allow-unsigned`. This protects against installing tampered or unverified distros.","triggerScenarios":"Calling `install_from_shuttle` on a capsule with no signature and no signing metadata, without `--allow-unsigned`; the function is reached when signature verification inputs are absent entirely.","commonSituations":"Installing a self-built capsule that was packed without a signing key; a distro author forgot to run the seal/sign step; older capsules produced before signing was introduced.","solutions":["Re-run the install with `--allow-unsigned` if you built the capsule yourself and accept the risk.","Sign the capsule: generate a 32-byte ed25519 key and run the seal/sign command so `[distro.signing]`/`Distro.sig` are embedded, then install normally.","Verify you have the latest capsule — re-download/re-pack if the signature file is missing from an otherwise signed distro."],"exampleFix":"// before\n$ astrid init --shuttle app.shuttle        # unsigned -> refused\n// after\n$ astrid distro seal --key signing.key ... # produce signature\n$ astrid init --shuttle app.shuttle        # or --allow-unsigned","handlingStrategy":"try-catch","validationCode":"// check for signature inputs before install\nlet signed = capsule_contains(\"Distro.sig\") || manifest_has(\"[distro.signing]\");\nif !signed && !opts.allow_unsigned {\n    eprintln!(\"capsule is unsigned; sign it or pass --allow-unsigned\");\n    std::process::exit(1);\n}","typeGuard":null,"tryCatchPattern":"match install_from_shuttle(&path, &opts) {\n    Err(e) if e.to_string().contains(\"allow-unsigned\") => {\n        eprintln!(\"capsule unsigned: seal it with a signing key or rerun with --allow-unsigned\");\n    }\n    other => other?,\n}","preventionTips":["Always seal capsules with an ed25519 key after packing","Only use --allow-unsigned for capsules you built locally","Verify signatures on every capsule from third parties","Upgrade old capsules produced before signing was enforced"],"tags":["signing","security","unsigned","install","ed25519"],"backgroundTag":"authentication-required","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}