{"record":{"id":"8b65ff55f74cd261","repo":"astrid-runtime/astrid","slug":"distro-distro-id-has-no-signing-key-pin-at","errorCode":null,"errorMessage":"distro '{distro_id}' has no signing-key pin at {} — install the operator-verified key before use; this path does not create a first-use pin","messagePattern":"distro '(.+?)' has no signing-key pin at (.+?) — install the operator-verified key before use; this path does not create a first-use pin","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/distro/trust.rs","lineNumber":167,"sourceCode":"\n    let pinned = read_pinned(home, distro_id)?;\n    let action = match pinned {\n        Some(pin_key) if pin_key == pubkey => TrustAction::PinnedMatch,\n        Some(pin_key) => {\n            // Valid signature, but under a key that differs from the pin.\n            if !accept_new_key {\n                bail!(\n                    \"distro '{distro_id}' is pinned to {} but this artifact is signed by {} — \\\n                     refusing. Re-run with --accept-new-key only if you trust the new key.\",\n                    sign::pubkey_to_wire(&pin_key),\n                    key_str,\n                );\n            }\n            write_pin(home, distro_id, &key_str)?;\n            TrustAction::NewKeyAccepted\n        },\n        None if policy == TrustPolicy::RequireExistingPin => {\n            bail!(\n                \"distro '{distro_id}' has no signing-key pin at {} — install the operator-verified \\\n                 key before use; this path does not create a first-use pin\",\n                trust_path(home, distro_id).display()\n            );\n        },\n        None => {\n            write_pin(home, distro_id, &key_str)?;\n            TrustAction::ToFuTrusted\n        },\n    };\n\n    audit_trust(distro_id, &key_str, action);\n\n    Ok(TrustOutcome {\n        pubkey,\n        key_str,\n        action,\n    })","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/distro/trust.rs#L149-L185","documentation":"When the trust policy is RequireExistingPin, verify_and_pin refuses a distro that has no signing-key pin on record instead of creating a first-use pin (TOFU) implicitly. The operator must install a pre-verified pin before use; this closed path exists for high-assurance environments.","triggerScenarios":"First install of a distro_id under TrustPolicy::RequireExistingPin where trust_path(home, distro_id) does not exist — no pin was ever provisioned on this machine.","commonSituations":"Fresh machines/CI runners provisioned without the operator's verified key pin; pin file deleted or home directory changed; onboarding a new distro under strict policy without the pin-distribution step.","solutions":["Provision the operator-verified pin file at the trust path shown in the error before installing","Run a pin-installation/TOFU step explicitly as part of machine provisioning","Switch to a policy that permits first-use pinning if implicit TOFU is acceptable"],"exampleFix":"// before: no pin on fresh CI runner -> refused\n// after: provision pin during setup\n// astrid distro trust pin distro-id <verified-pubkey>","handlingStrategy":"validation","validationCode":"let pin_path = trust_path(home, distro_id);\nif !pin_path.exists() {\n    return Err(anyhow!(\"no pin for {distro_id}; provision it first\"));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Provision verified pins during machine/CI provisioning","Include pin installation in onboarding runbooks","Verify pin file presence before scheduling offline installs"],"tags":["security","key-pinning","policy","trust-on-first-use"],"backgroundTag":"authentication-required","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}