astrid-runtime/astrid · critical
capsule capabilities changed after authority decision
Error message
capsule capabilities changed after authority decision
What it means
`authority_for_install_source` compares `approved.approved_capabilities` (the capability ceiling the operator approved) with `manifest.capabilities` (the capabilities the capsule now requests). This error is thrown when the capsule's requested capabilities were expanded after the authority decision — a privilege-escalation guard that stops an unreviewed capability grant from being installed under an old, narrower approval.
Source
Thrown at crates/astrid-capsule-install/src/authority.rs:940
bail!(
"capsule content changed after authority decision (approved {}, found {})",
approved.content_digest,
content_digest
);
}
if approved.signer != signer || approved.signature != signature {
bail!("capsule provenance changed after authority decision");
}
if approved.capsule_id != manifest.package.name
|| approved.version != manifest.package.version
{
bail!("capsule identity or version changed after authority decision");
}
if approved.manifest_digest != manifest_digest {
bail!("capsule manifest changed after authority decision");
}
if approved.approved_capabilities != manifest.capabilities {
bail!("capsule capabilities changed after authority decision");
}
return Ok(approved);
}
// Calling the legacy library install API is itself an operator-authority
// action. User-facing CLI and daemon entry points use explicit decisions;
// this path preserves the existing trusted embedding API while recording
// the same exact content and capability ceiling.
Ok(InstalledAuthority {
schema_version: 1,
source: AuthoritySource::OperatorDistribution,
capsule_id: manifest.package.name.clone(),
version: manifest.package.version.clone(),
content_digest,
manifest_digest,
signer,
signature,
approved_capabilities: manifest.capabilities.clone(),View on GitHub (pinned to affd8760f4)
Solutions
- Re-run the authority approval so the operator reviews and approves the new capability set, then install with the new receipt
- Revert the capabilities section of Capsule.toml to the approved set and retry
- If the new capabilities are intentional, document and complete a fresh review before installing
Example fix
// before
bail!("capsule capabilities changed after authority decision");
// after: obtain a new decision covering the expanded capabilities
// let authority = decision::approve_with_capabilities(source_dir, &manifest.capabilities)?;
// install_from_local_path_internal(source_dir, Some(authority)) Defensive patterns
Strategy: validation
Validate before calling
// Ensure requested capabilities match the approved ceiling before install
let manifest = load_manifest(source_dir.join("Capsule.toml"))?;
assert_eq!(approved.approved_capabilities, manifest.capabilities,
"capability set changed since approval; re-run operator review"); Type guard
fn capabilities_unchanged(approved: &InstalledAuthority, m: &CapsuleManifest) -> bool {
approved.approved_capabilities == m.capabilities
} Try / catch
match authority_for_install_source(source_dir, &manifest, Some(approved)) {
Err(e) if e.to_string().contains("capabilities changed") => request_capability_review(&manifest.capabilities),
other => other.map(install),
} Prevention
- Treat any capability addition as requiring a fresh security review
- Keep the capabilities section frozen between review and install
- Review dependency updates for new capability requirements before approving
- Log capability diffs in CI to catch accidental edits
When it happens
Trigger: Calling `install_from_local_path_internal` with an approved `InstalledAuthority` where `approved.approved_capabilities != manifest.capabilities`, i.e. the `capabilities` section of Capsule.toml changed after approval (added permissions like network, fs access, etc.).
Common situations: A developer adds a new permission to Capsule.toml after the operator reviewed it; a dependency update pulls in capability requirements; accidentally editing the capabilities block while changing something else.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- materialized capsule manifest exceeds durable authority appr
- manifest exceeds its installed capability approval: {details
- installed authority receipt does not match capsule '{capsule
- capsule content changed after authority decision (approved {
- capsule provenance changed after authority decision
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/b31d2fce72ee76be.
Report an issue: GitHub.