Problem
astrid init --distro <url> [--principal <p>] installs a distro's capsules per-principal but attaches zero capsule-access grants. The flow (run_init → install_capsules → install_capsule_batch, plus write_env_files and a distro.lock) writes capsule files and env config under the target principal's home, and the Distro.toml schema has no grant/capability fields.
Capsule access is gated per-principal at dispatch (a principal may invoke a capsule only if that capsule is in its profile's grant set, or it holds admin *). New principals get no capsule access by default. So after init, a non-default principal has the capsule files but cannot invoke any of their tools — every tool call fails authorization.
The only way to make such a principal work today is an out-of-band, human-copied step:
astrid agent modify <p> --add-capsule <name> --add-capsule <name> ...
whose capsule list must manually mirror the distro's [capsules] set. External plugin repos literally carry "SYNC" comments to keep these lists aligned. Users who skip the step get a silently broken principal.
Proposed fix: --grant-capsules flag on astrid init
Add an opt-in --grant-capsules flag (valid only together with --distro). When set, after the distro's capsules install successfully, apply capsule-access grants for exactly the set of capsules that installed for the target principal, using the same underlying mechanism as agent modify --add-capsule (the admin.agent.modify kernel path; refactor to a shared helper, no duplicated grant logic).
- Idempotent: a re-run over an already-granted principal succeeds with no error or duplicate grants (kernel
apply_set_delta dedups).
default no-op: the bootstrap default principal holds admin *, which bypasses the capsule-access filter entirely, so per-capsule grants are meaningless for it — the flag is a no-op with an informational line.
- Failure handling: capsules are already installed at grant time; if the grant fails (daemon down, caller lacks
agent:modify), print the exact manual agent modify ... --add-capsule ... command and exit non-zero.
- Discoverability: when
--distro + a non-default --principal are used without the flag, print the exact agent modify command (or --grant-capsules on re-run) so the out-of-band step is discoverable.
- Security stance: grants derive strictly from the locally-resolved installed capsule set (not arbitrary manifest strings), applied only on explicit operator opt-in. No auto-granting without the flag; no changes to ingress-trust/approval; no grant fields added to
Distro.toml.
Problem
astrid init --distro <url> [--principal <p>]installs a distro's capsules per-principal but attaches zero capsule-access grants. The flow (run_init→install_capsules→install_capsule_batch, pluswrite_env_filesand adistro.lock) writes capsule files and env config under the target principal's home, and theDistro.tomlschema has no grant/capability fields.Capsule access is gated per-principal at dispatch (a principal may invoke a capsule only if that capsule is in its profile's grant set, or it holds admin
*). New principals get no capsule access by default. So afterinit, a non-defaultprincipal has the capsule files but cannot invoke any of their tools — every tool call fails authorization.The only way to make such a principal work today is an out-of-band, human-copied step:
whose capsule list must manually mirror the distro's
[capsules]set. External plugin repos literally carry "SYNC" comments to keep these lists aligned. Users who skip the step get a silently broken principal.Proposed fix:
--grant-capsulesflag onastrid initAdd an opt-in
--grant-capsulesflag (valid only together with--distro). When set, after the distro's capsules install successfully, apply capsule-access grants for exactly the set of capsules that installed for the target principal, using the same underlying mechanism asagent modify --add-capsule(theadmin.agent.modifykernel path; refactor to a shared helper, no duplicated grant logic).apply_set_deltadedups).defaultno-op: the bootstrapdefaultprincipal holds admin*, which bypasses the capsule-access filter entirely, so per-capsule grants are meaningless for it — the flag is a no-op with an informational line.agent:modify), print the exact manualagent modify ... --add-capsule ...command and exit non-zero.--distro+ a non-default--principalare used without the flag, print the exactagent modifycommand (or--grant-capsuleson re-run) so the out-of-band step is discoverable.Distro.toml.