Capabilities
A scope is necessary, but it is not always sufficient. Lumio also applies class-wide guard bars based on the credential type.
Key-Kind Matrix
| Surface | lm_usr_* personal key | lm_svc_* service key | lm_dev_* developer key |
|---|---|---|---|
Account-scoped REST and GraphQL guarded by resource:action | Yes, when the key belongs to the account and holds the scope | Yes, when the key belongs to the account and holds the scope | No account context |
User-scoped ideas:* operations | Yes, when it holds the ideas:* scope | No user identity | No user identity |
| First-party user surfaces | Yes | No | No |
| Developer extension publishing routes | Yes, when the user is an approved developer and holds the required extension-dev:* scope | No developer identity | Yes, when bound to the owning developer profile or team and holding the required extension-dev:* scope |
| Developer key management | Yes, through first-party user auth | No | No, a developer key cannot mint, rename, or revoke developer keys |
| Admin routes | No | No | No |
| WebSocket account channels | Yes, when account and scope checks pass | Yes, when account and scope checks pass | No account context |
WebSocket ext-logs, overlay, and widget channels | No by construction | No by construction | No by construction |
Class-Wide Bars
require_first_party_user guards sensitive user-actor surfaces. It accepts logged-in users and personal lm_usr_* keys because they carry a user id. It rejects service and developer keys with 403. Anonymous requests receive 401. Common first-party surfaces include /v1/users/*, /v1/accounts/*, /v1/notifications/*, /v1/setting-presets/*, /v1/watchlist/*, billing reads, /v1/tokens/*, /v1/api-keys/*, service-key reads and edits, developer-key management, and developer application/profile/team management. Billing checkout, portal access, and cancellation instead require an interactive user session; portal access and cancellation also require plan:edit.
require_session_user accepts only an interactive signed-in user session. Personal, service, and developer API keys cannot create or rotate service keys, start billing checkout or portal sessions, cancel a subscription, change payout settings, request a payout, or start Stripe Connect onboarding. Each operation still checks its applicable permission and feature gate.
require_admin_permission accepts only logged-in users with admin permissions and system keys with explicit admin grants. No public API key kind can reach admin routes. This covers /v1/admin/*, /v1/user-roles/*, crawler controls, CSP report review, copyright moderation, ideas moderation, extension review, developer verification, and developer limit administration.
require_user_permission accepts logged-in users and personal lm_usr_* keys. Service keys are rejected because they have no user identity. This is why the ideas:* family is personal-key-only.
Developer-Key Reach
Developer keys are deliberately narrow. They carry only extension-dev:* scopes and are bound to a developer profile or developer team. They can call extension publishing routes that resolve ownership from that developer identity. They cannot call account APIs, admin APIs, key-management APIs, application/profile onboarding routes, payout setup routes that need a user actor, or user-scoped ideas:* routes. They can manage the secrets of the extensions they own.