You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Enable API for everything UI can do, with same RBAC
Agent's Two Cents (could be wrong)
Everything below is the AI agent's best guess based on the current codebase.
Take with a grain of salt — the original request above is the only thing that came from a human.
Problem / Motivation
Kener's admin UI can do many things the public/authenticated API cannot, so anyone trying to automate or provision Kener (IaC, CI, bulk imports, external dashboards) keeps hitting gaps and has to fall back to clicking in the UI. The community has filed these gaps one endpoint at a time (incidents, maintenance events, monitor delete, subscriptions, …) instead of treating "the API should cover everything the UI does" as a single principle. This issue proposes that principle directly, plus the rule that an API caller needs exactly the same permission the UI requires for the same action — no more, no less.
Proposed Solution
Establish API ⇄ UI parity as an invariant: every action reachable from the admin UI has a corresponding v4 API endpoint, and that endpoint is gated by the same RBAC permission the UI action requires.
Concretely:
Enumerate every mutating/reading action the admin UI performs (monitors, incidents, maintenances + events, pages + reorder, triggers/alert-configs, users, roles, permissions, API keys, subscribers, email templates, site settings, image uploads).
For each, ensure a v4 API route exists with full CRUD where the UI offers it.
Route every endpoint through one shared authorization resolver that maps (path, method) → permission id and checks it against the caller's API-key permission set — the same resource.action ids the UI/session RBAC already uses.
Treat "UI can do X but API can't" (or "API requires a different/looser permission than the UI") as a bug going forward, ideally backed by a parity test.
Note: the fork xinbenlv/zn-kener has already built a large reference implementation of exactly this (a per-key RBAC resolver in src/lib/server/apiPermissions.ts plus v4 routes for users/roles/permissions/api-keys/subscribers/email-templates/monitor clone-test-data, etc.). It can serve as a working proof-of-concept / source of PRs for upstream.
Architecture Diagram
┌──────────────────────┐ ┌──────────────────────┐
│ Admin UI (manage) │ │ API client / IaC │
│ session + role │ │ Bearer API key │
└──────────┬───────────┘ └──────────┬───────────┘
│ action: "edit monitor" │ PUT /api/v4/monitors/{tag}
▼ ▼
┌────────────────────────────────────────────────────────┐
│ SINGLE shared authorization resolver │
│ requiredPermissionFor(path, method) -> "monitors.write"│
│ then assert caller has that permission id │
└──────────────────────────┬─────────────────────────────┘
│ same permission id, same check
▼
┌───────────────────────────────────┐
│ Controller / service layer │
│ (monitorsController, etc.) │
└───────────────────────────────────┘
Invariant: for every UI action there is an API route, and both arrive at the
controller having passed the IDENTICAL permission check. No UI-only actions;
no API endpoint looser or stricter than its UI equivalent.
Dependencies & Potential Blockers
No major blockers identified. The building blocks already exist in the project: a v4 API surface (src/routes/(api)/api/v4/), Bearer/API-key auth (VerifyAPIKey in apiController.ts), a permission catalog (src/lib/allPerms.ts), per-API-key permissions (migration 20260530000000_add_permissions_to_api_keys.ts), and a (path, method) → permission resolver pattern. The work is mostly closing coverage gaps and enforcing one consistent auth path, not new infrastructure.
How to Validate
Generate (or maintain) a list of every admin-UI action and assert each has a v4 endpoint — a parity test that fails when the UI gains an action with no API equivalent.
For a representative action per resource (e.g. monitor create/edit/delete, incident create/comment, maintenance event add, page edit/reorder, user/role/permission CRUD, subscriber add, email-template edit, site-setting update): call the v4 endpoint with an API key that has the matching permission → succeeds; with a key missing it → 403.
Confirm no v4 endpoint accepts an action the UI gates behind a permission the API does not check (no privilege escalation, no looser API path).
Smoke test: provision a fresh Kener instance end-to-end (monitors, a page, an incident, a maintenance window, a user with a scoped role) using only the API.
Scope Estimate
large
Key Files/Modules Likely Involved
src/routes/(api)/api/v4/ — the v4 route handlers (extend to full coverage)
src/lib/server/apiPermissions.ts — (path, method) → permission id resolver + key-permission check (reference impl from the fork)
src/lib/allPerms.ts — canonical resource.action permission catalog shared by UI and API
src/lib/server/controllers/*Controller.ts — shared business logic both UI and API should call
src/routes/(manage)/ — the admin UI actions that define the parity target
Rough Implementation Sketch
Audit the (manage) UI to produce the authoritative list of actions and the permission each requires.
Diff that list against existing api/v4 routes; file/track each missing endpoint.
Funnel all API requests through one authorization middleware that derives the required permission from (path, method) and checks the key's permission set.
Have both UI handlers and API routes delegate to the same controller functions so behavior can't drift.
Add a parity/coverage test (and ideally a docs table) so new UI features must ship their API + permission mapping.
Open Questions
Should genuinely UI-only conveniences (pure presentation, preview-only flows) be explicitly exempted from parity, and how do we mark them?
Granularity: is resource.read / resource.write (+ a few special cases like api_keys.delete) enough, or do some actions need finer-grained permissions?
Versioning: extend v4 in place, or stage breaking auth-tightening behind a new version?
Tightening auth so the API matches the UI could break existing integrations that currently call under-protected endpoints — needs a migration/communication path.
Keeping the permission map in lockstep with the UI is an ongoing maintenance burden; without an enforced test it will drift.
Resource-name/segment aliasing (e.g. alert-configs → alerts, permissions → roles) must stay consistent between UI and API to avoid wrong-permission checks.
Related Issues
Existing per-feature API/RBAC requests this umbrella would subsume (surfaced while researching this proposal):
Suggested labels:enhancement, kener-apis, AgentsValidatable, NoNewDependencies Suggested priority: p2 (medium — important parity improvement, non-blocking) (Filed by an external contributor without write access, so labels/priority are noted here rather than applied directly.)
Original Request
Agent's Two Cents (could be wrong)
Problem / Motivation
Kener's admin UI can do many things the public/authenticated API cannot, so anyone trying to automate or provision Kener (IaC, CI, bulk imports, external dashboards) keeps hitting gaps and has to fall back to clicking in the UI. The community has filed these gaps one endpoint at a time (incidents, maintenance events, monitor delete, subscriptions, …) instead of treating "the API should cover everything the UI does" as a single principle. This issue proposes that principle directly, plus the rule that an API caller needs exactly the same permission the UI requires for the same action — no more, no less.
Proposed Solution
Establish API ⇄ UI parity as an invariant: every action reachable from the admin UI has a corresponding v4 API endpoint, and that endpoint is gated by the same RBAC permission the UI action requires.
Concretely:
(path, method) → permission idand checks it against the caller's API-key permission set — the sameresource.actionids the UI/session RBAC already uses.Architecture Diagram
Dependencies & Potential Blockers
No major blockers identified. The building blocks already exist in the project: a v4 API surface (
src/routes/(api)/api/v4/), Bearer/API-key auth (VerifyAPIKeyinapiController.ts), a permission catalog (src/lib/allPerms.ts), per-API-key permissions (migration20260530000000_add_permissions_to_api_keys.ts), and a(path, method) → permissionresolver pattern. The work is mostly closing coverage gaps and enforcing one consistent auth path, not new infrastructure.How to Validate
403.Scope Estimate
large
Key Files/Modules Likely Involved
src/routes/(api)/api/v4/— the v4 route handlers (extend to full coverage)src/lib/server/apiPermissions.ts—(path, method) → permission idresolver + key-permission check (reference impl from the fork)src/lib/allPerms.ts— canonicalresource.actionpermission catalog shared by UI and APIsrc/lib/server/controllers/*Controller.ts— shared business logic both UI and API should callsrc/routes/(manage)/— the admin UI actions that define the parity targetRough Implementation Sketch
(manage)UI to produce the authoritative list of actions and the permission each requires.api/v4routes; file/track each missing endpoint.(path, method)and checks the key's permission set.Open Questions
resource.read/resource.write(+ a few special cases likeapi_keys.delete) enough, or do some actions need finer-grained permissions?v4in place, or stage breaking auth-tightening behind a new version?Potential Risks or Gotchas
alert-configs→alerts,permissions→roles) must stay consistent between UI and API to avoid wrong-permission checks.Related Issues
Existing per-feature API/RBAC requests this umbrella would subsume (surfaced while researching this proposal):
Open gaps:
Already closed (precedent / scope examples):
Suggested labels:
enhancement,kener-apis,AgentsValidatable,NoNewDependenciesSuggested priority: p2 (medium — important parity improvement, non-blocking)
(Filed by an external contributor without write access, so labels/priority are noted here rather than applied directly.)