carlos / platform Public

store/grant is a registration that lies: Allow(Admin) outside, operator-address gate inside Issue open

Migrated from github.com/carlosframework/platform issue #263, opened 2026-08-23. GitHub issues are closed for this repo; see AGENTS.md, "Work is tracked on amadan, not GitHub".

Still outstanding: store/grant registers as Allow(Admin) while gating internally on operator address, so the role table misreports its authority.

---

Noticed while giving the email family its role table (#240).

POST /api/cli/apps/{account}/{app}/store/grant registers as:

s.cliRoute("POST /api/cli/apps/{account}/{app}/store/grant", svcrole.Allow(svcrole.Admin), s.handleAPIStoreGrant)

but the handler resolves an address against CARLOS_STORE_OPERATORS. A service principal's audit identity is service:<sqid>/<name> (auditActor), which can never appear on that list — so an admin-role service credential passes the role gate and is then refused inside, always.

That is exactly the shape authcli.go argues against in its own words, at the instances-manifest door:

> a registration reading "instance may pass" while the handler refuses is a registration that lies

The cost is not an escalation — nothing gets in that shouldn't. It is that the role table, which is meant to be the one place a door's authority is written down, misreports this door. Someone reading it sees "an admin service may grant a store" and it has never been true.

Suggested fix: register it svcrole.Set{} and add it to closedDoors, so the refusal is structural and the caller gets the honest "this door is closed to service credentials — no role reaches it; it needs a person" rather than a 404 from an operator check it could never have passed.

For contrast, POST .../email/pause in #240 is the same shape (operator-address gate inside) and is registered svcrole.Set{} for this reason, with /email/pause added to policyDoors.

Worth checking whether any other operator-gated door has the same mismatch.