{"record":{"id":"452ab85e9d724f95","repo":"astrid-runtime/astrid","slug":"durable-capsule-id-manifest-exceeds-its-authorit","errorCode":null,"errorMessage":"durable capsule {id} manifest exceeds its authority receipt","messagePattern":"durable capsule (.+?) manifest exceeds its authority receipt","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/astrid-capsule-install/src/storage.rs","lineNumber":330,"sourceCode":"                bail!(\"durable capsule {id} WASM hash differs between metadata and archive\");\n            }\n        } else if metadata.wasm_hash.is_some() {\n            bail!(\"durable capsule {id} metadata names a hash for a non-WASM component\");\n        }\n    } else if metadata.wasm_hash.is_some() {\n        bail!(\"durable capsule {id} metadata names a component absent from its archive\");\n    }\n    let mut effective_capabilities = manifest.capabilities.clone();\n    for component in &manifest.components {\n        if let Some(capabilities) = &component.capabilities {\n            effective_capabilities.merge_from(capabilities);\n        }\n    }\n    if !effective_capabilities\n        .expansions_from(&authority.approved_capabilities)\n        .is_empty()\n    {\n        bail!(\"durable capsule {id} manifest exceeds its authority receipt\");\n    }\n    match verification {\n        ArtifactVerification::Signed(provenance) => {\n            let signer = provenance.signer.to_string();\n            let signature = provenance.signature.to_string();\n            if authority.signer.as_deref() != Some(signer.as_str())\n                || authority.signature.as_deref() != Some(signature.as_str())\n            {\n                bail!(\"durable capsule {id} provenance differs from authority receipt\");\n            }\n        },\n        ArtifactVerification::Unsigned { .. } => {\n            if authority.signer.is_some() || authority.signature.is_some() {\n                bail!(\"durable capsule {id} authority claims provenance absent from archive\");\n            }\n        },\n    }\n    Ok(())","sourceCodeStart":312,"sourceCodeEnd":348,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-capsule-install/src/storage.rs#L312-L348","documentation":"After merging manifest-level and per-component capabilities, the effective capability set contains expansions that are not covered by the approved capabilities in the InstalledAuthority receipt. The library rejects the package because a durable capsule may never grant more permissions than its authority receipt approves; the manifest would otherwise silently escalate privileges at install time.","triggerScenarios":"read_verified_durable_package_for_owner when effective_capabilities.expansions_from(authority.approved_capabilities) is non-empty — i.e. the manifest (or a component's capabilities block) requests a capability (network, fs, etc.) not present in the authority receipt.","commonSituations":"Editing the manifest to add a capability without re-issuing the authority receipt; reusing an old authority receipt with an upgraded manifest; copying a manifest between capsules with different approved capability sets.","solutions":["Re-issue or update the authority receipt so approved_capabilities covers the manifest's requested capabilities.","Remove the extra capabilities from the manifest/component capabilities blocks to match the receipt.","Regenerate the receipt as part of the publish flow whenever capabilities change.","Diff effective vs approved capabilities (expansions_from output) to see exactly which grants are rejected."],"exampleFix":"// before: manifest requests more than receipt approves\nmanifest.capabilities.add(Capability::NetworkOutbound);\n// after: request receipt approval first, or remove the grant\n// authority.approved_capabilities must include Capability::NetworkOutbound\n// or delete the capability from the manifest","handlingStrategy":"validation","validationCode":"let mut effective = manifest.capabilities.clone();\nfor c in &manifest.components {\n    if let Some(caps) = &c.capabilities { effective.merge_from(caps); }\n}\nif !effective.expansions_from(&authority.approved_capabilities).is_empty() {\n    return Err(\"manifest requests capabilities not in authority receipt\");\n}","typeGuard":"fn within_authority(manifest: &CapsuleManifest, authority: &InstalledAuthority) -> bool {\n    let mut effective = manifest.capabilities.clone();\n    for c in &manifest.components {\n        if let Some(caps) = &c.capabilities { effective.merge_from(caps); }\n    }\n    effective.expansions_from(&authority.approved_capabilities).is_empty()\n}","tryCatchPattern":"match read_verified_durable_package_for_owner(&store, owner, id).await {\n    Ok(pkg) => pkg,\n    Err(e) if e.to_string().contains(\"exceeds its authority receipt\") => {\n        // re-issue receipt or trim capabilities\n    },\n    Err(e) => return Err(e),\n}","preventionTips":["Re-issue the authority receipt whenever manifest capabilities change.","Treat the receipt as the single source of truth for allowed capabilities.","Run expansions_from as a pre-publish lint."],"tags":["capabilities","authority","policy","security"],"backgroundTag":"insufficient-permissions","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"}