astrid-runtime/astrid · error
capsule install authority was not approved
Error message
capsule install authority was not approved
What it means
When no automated or flag-based approval applies, authority_decision prints the capsule's provenance, signer, content digest, and any new capability expansions, then asks 'Approve this exact install once? [y/N]'. If the operator's stdin answer is anything other than y/yes (case-insensitive), the install is aborted with this error. It is the normal refusal outcome of the interactive consent gate, not a malfunction.
Source
Thrown at crates/astrid-cli/src/commands/capsule/install/authority.rs:78
for expansion in &inspection.capability_expansions {
let semantic = semantic_expansion(expansion);
eprintln!(" - {}", semantic.action);
if !semantic.scope.is_empty() {
eprintln!(" Scope: {}", semantic.scope.join("; "));
}
eprintln!(" Impact: {}", semantic.impact);
}
}
eprint!("Approve this exact install once? [y/N] ");
std::io::Write::flush(&mut std::io::stderr())?;
let mut answer = String::new();
std::io::stdin().read_line(&mut answer)?;
if matches!(answer.trim().to_ascii_lowercase().as_str(), "y" | "yes") {
Ok(AuthorityDecision::ExplicitApproval {
content_digest: inspection.content_digest.clone(),
})
} else {
bail!("capsule install authority was not approved")
}
}
pub(super) fn daemon_install_authority(
source: &str,
principal: &astrid_core::PrincipalId,
prompt: &ManualInstallOptions,
) -> anyhow::Result<CapsuleInstallAuthority> {
let home = AstridHome::resolve()?;
let path = Path::new(source.strip_prefix("file://").unwrap_or(source));
let inspection = if path.is_file() {
inspect_archive_for_principal_with_layout(
path,
&home,
principal,
false,
crate::workspace_layout::current(),
)?View on GitHub (pinned to affd8760f4)
Solutions
- Re-run the install interactively and answer `y` or `yes` at the 'Approve this exact install once?' prompt if you trust the artifact.
- Ensure stdin is a TTY or an open pipe; EOF (e.g. `cmd < /dev/null` or nohup without stdin) is treated as refusal.
- For scripted trusted installs, pass `--approve-untrusted` (after reviewing the digest) instead of relying on piped input.
- Verify the capsule's signer and content digest printed before the prompt; if they are unexpected, keep declining and investigate the source.
- For operator distribution scenarios, use the batch mode path which grants OperatorDistribution authority without prompting.
Example fix
# before (non-interactive stdin, instant refusal) echo -n | astrid capsule install ./x.capsule # after printf 'y\n' | astrid capsule install ./x.capsule # or run interactively / use --approve-untrusted
Defensive patterns
Strategy: try-catch
Validate before calling
# guard: only run when interactive, or pre-approve via flag
[ -t 0 ] || { echo "non-interactive stdin: pass --approve-untrusted"; exit 1; } Try / catch
match authority_decision(&inspection, &prompt) {
Ok(decision) => install_with(decision),
Err(e) if e.to_string().contains("not approved") => eprintln!("install declined by operator"),
Err(e) => return Err(e),
} Prevention
- Run installs from an interactive terminal when you intend to answer the approval prompt.
- Pipe an explicit 'y\n' only when you have verified the artifact's digest.
- Use --approve-untrusted for scripted trusted installs instead of relying on stdin.
- Check that the capsule's signer and capability expansions match expectations before approving.
When it happens
Trigger: Interactive capsule install reaches the approval prompt (non-LocalRuntime provenance, not BATCH_MODE, no --approve-untrusted, no --yes) and stdin yields a line that does not trim/lowercase to "y" or "yes" — e.g. pressing Enter, typing "n", "no", or EOF (empty read, as when stdin is /dev/null or a closed pipe).
Common situations: User intentionally declines an untrusted capsule; running the command in a non-interactive shell where stdin returns EOF immediately, so the read yields an empty string and counts as refusal; scripting around the prompt by piping nothing; user misreads the prompt and types "no" expecting a different flow.
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
- capsule '{}' is {}; --yes configures values but does not app
- manifest exceeds its installed capability approval: {details
- capsule '{}' is {}; explicit local approval is required
- {name} is not installed beside the Astrid CLI; refusing a PA
- headless approval automation is unsupported: approvals canno
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/b3f0eca144998e4b.
Report an issue: GitHub.