{"record":{"id":"d296121cd08f619f","repo":"astrid-runtime/astrid","slug":"signed-distro-toml-has-no-distro-signing-configu","errorCode":null,"errorMessage":"signed Distro.toml has no [distro.signing] configuration","messagePattern":"signed Distro\\.toml has no \\[distro\\.signing\\] configuration","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/init_signed_source.rs","lineNumber":302,"sourceCode":"}\n\n/// Bind exact TOML bytes into the signed lock, then verify that lock.\nfn verify_signed_manifest(\n    home: &AstridHome,\n    manifest: &DistroManifest,\n    manifest_hash: &str,\n    lock: &DistroLock,\n    sig_hex: &str,\n    accept_new_key: bool,\n) -> anyhow::Result<HashMap<String, String>> {\n    if lock.manifest_hash.as_deref() != Some(manifest_hash) {\n        bail!(\n            \"signed Distro.toml does not match Distro.lock manifest_hash; refusing to resolve members\"\n        );\n    }\n    validate_signed_member_sets(manifest, lock)?;\n    let signing = manifest.distro.signing.as_ref().ok_or_else(|| {\n        anyhow::anyhow!(\"signed Distro.toml has no [distro.signing] configuration\")\n    })?;\n    let outcome = trust::verify_and_pin(\n        home,\n        &manifest.distro.id,\n        &signing.pubkey,\n        sig_hex,\n        lock,\n        accept_new_key,\n        trust::TrustPolicy::RequireExistingPin,\n    )?;\n    tracing::info!(\n        distro = %manifest.distro.id,\n        action = ?outcome.action,\n        \"authenticated source Distro\"\n    );\n\n    Ok(lock\n        .capsules","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/init_signed_source.rs#L284-L320","documentation":"verify_signed_manifest requires the parsed Distro.toml to carry a `[distro.signing]` table (containing the pubkey) before it can verify the Ed25519 signature over the lock. If `manifest.distro.signing` is None the manifest cannot be authenticated, so the CLI refuses to proceed.","triggerScenarios":"fetch_signed_manifest verifies a signed Distro.toml whose `[distro.signing]` section is missing — typically because the signing table was removed, the wrong (unsigned/legacy) Distro.toml is deployed at the source, or the table name is misspelled.","commonSituations":"Upgrading an old distro layout to signed sources without adding `[distro.signing]`; copying a Distro.toml template that omits the signing block; a `signings`/`signing` typo in TOML.","solutions":["Add a `[distro.signing]` table with a `pubkey` field to the published Distro.toml (generate via `astrid keypair generate` and convert with the ed25519:<base64> wire form)","Confirm the source actually points at the signed manifest, not an older unsigned one","Re-check TOML section spelling and that the file parses with `signing` under `distro`"],"exampleFix":"# before\n[distro]\nid = \"my-distro\"\n# after\n[distro]\nid = \"my-distro\"\n[distro.signing]\npubkey = \"ed25519:<base64-public-key>\"","handlingStrategy":"validation","validationCode":"let toml = std::fs::read_to_string(\"Distro.toml\")?;\nlet manifest: DistroManifest = toml::from_str(&toml)?;\nif manifest.distro.signing.is_none() {\n    anyhow::bail!(\"Distro.toml is missing [distro.signing]; add it before sealing/publishing\");\n}","typeGuard":"fn has_signing(m: &DistroManifest) -> bool { m.distro.signing.is_some() }","tryCatchPattern":"match verify_signed_manifest(/*..*/).await {\n    Err(e) if e.to_string().contains(\"no [distro.signing]\") => {\n        eprintln!(\"Published Distro.toml lacks [distro.signing]; regenerate a signed manifest\");\n    }\n    r => r?,\n}","preventionTips":["Always include [distro.signing] with pubkey in published Distro.toml","Lint manifests for the signing table in CI before seal/publish","Keep Distro.toml templates updated when migrating from unsigned layouts"],"tags":["config","signing","toml"],"backgroundTag":"missing-required-config-field","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}