Object storage should be self-serve: a declared store waits on two manual operator steps Feature Request open
Migrated from github.com/carlosframework/platform issue #381, opened 2026-09-02. GitHub issues are closed for this repo; see AGENTS.md, "Work is tracked on amadan, not GitHub".
Still outstanding: Object storage should be self-serve: the account apply and operator approve doors are unbuilt.
---
Raised by Paul on 2026-09-02, from James finding that carloku has no object storage backend at all — his app's declaration had been sitting since 2026-08-29 waiting on an operator who did not know he was waiting.
The gap
carlos store create is a request. Everything after it is a human. A tenant who declares a store today hits two separate operator-side blockers, and can act on neither:
- The deployment may have no backend.
CARLOS_STORE_BACKEND(plusCARLOS_STORE_REGIONandCARLOS_STORE_BUCKET_PREFIX, all three or the consolelog.Fatals at boot —cmd/console/main.go:492) live only in the console's root env file. Turning object storage on for a whole deployment is an SSM/root edit and a console restart. This is #368's problem exactly, in its most expensive instance: the flagship deployment has shipped the store primitive since #55 and has never had it switched on, because switching it on is not acarlosverb. - Every individual grant is a manual operator verb. Even with a backend configured, each app needs a person on
CARLOS_STORE_OPERATORSto runcarlos store grant --app <a>, once, per app, forever.
Status does tell a waiting member which of the two they are behind — that part works, and was designed for it. What it cannot do is get them unstuck.
Why the gate exists, and what must survive
The grant gate is not ceremony. grant creates real estate — a bucket, an IAM user, an inline policy, an access key — in the deployment's cloud account, on the operator's bill. internal/console/apistore.go:14 calls it the deployment's first explicit operator-identity gate, and that reasoning is still right: no tenant should be able to mint chargeable AWS resources on someone else's account just by asking.
So self-serve cannot mean "delete the gate". It means moving the money decision from per-app to once, so the operator makes it deliberately and the tenants stop queueing behind a person.
The shape
carlos console setfor the deployment half (#368). Object storage is the strongest argument for that issue: three coupled variables, a fatal boot check if you get them half right, and a whole primitive dark until they are set.- An operator-set grant policy for the per-app half. Something like a per-account store allowance the operator sets once — a bucket count, or a budget, or simply "auto-grant declarations in this account" — after which
carlos store createprovisions inline and the tenant never learns the word "grant". Operators who want to keep approving each one keep today's behaviour by setting no policy; the fail-closed default does not change. - Whatever the policy, the record keeps saying who granted. The three blocks (member declares / operator grants / console provisions) are the audit trail, and a policy-driven grant should fill the operator block with the policy that authorised it, not leave it null or forge a person.
Adjacent
- #55 — the object-storage primitive this is the missing operator half of.
- #368 — console config through a verb; blocker 1 is a special case of it.
- #375 —
kind:mediasits on top of an app having a store at all, so whatever fraction of apps never get past the grant queue is the ceiling on media adoption too.
Evidence
Confirmed on carloku 2026-09-02: carlos store create answers "this deployment has no object storage backend configured yet". Two tenants (James, Tony) are waiting on a bucket behind it as of filing.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Hw5sFjqcaUair6oV2EJvTS