KLKLine FrontendDashboard · Preview · Embed shell

Admin widget builder

Persisted save auth boundary

F032 maps admin session, tenant ownership, RBAC, audit, revision and read-after-write gates before any real POST/PATCH save can be enabled.

Checked at

۰۶:۳۳:۰۸

Static source-map audit against the uploaded backend and frontend shell.

Persisted save

BLOCKED

Direct create/update remains fail-closed until every boundary passes.

Manual token UI

FORBIDDEN

Admin/runtime/provider tokens must never be pasted into UI.

Session transport

anonymous

No app-owned admin session is currently wired in the frontend shell.
F032 · auth/session/tenant/audit boundary

Persisted widget save auth boundary map

This phase maps the exact gates required before the Widget Builder can call persisted create/update. It proves what is available in the backend source map, and it explicitly keeps frontend direct save disabled because the dashboard still lacks an app-owned admin session transport and saved/applied reconciliation.

Pass

5

Backend/source guards that are already visible.

Warnings

5

Available but not enough to enable frontend save.

Blocked

2

Hard blockers before direct save.

Failed

0

Should stay zero for static source-map checks.
PASS

Admin login/refresh/logout endpoints exist in backend

/api/admin/auth/login

auth: anonymous

Backend exposes app-owned admin auth endpoints, including login, refresh and logout. Frontend still needs a safe session transport before mutations can run.

  • src/control-plane/admin-api/admin-api.controller.ts -> @Post("auth/login")
  • src/control-plane/admin-api/admin-auth-token.service.ts -> issueTokenPair(actor)
BLOCKED

Frontend app-owned session transport

auth: app-owned-session

The current dashboard has no httpOnly-cookie/server-session transport. Manual bearer token input remains forbidden, so persisted save must stay disabled.

  • apps/dashboard/src/app/admin/login/page.tsx -> shell only
  • No admin token input is allowed in Widget Builder
PASS

RBAC permission for widget writes

/api/admin/widget-instances

auth: admin-bearer

Backend resource map requires widget_instances.write for persisted create/update/delete.

  • src/control-plane/admin-api/admin-api.service.ts -> permission widget_instances.write
  • src/control-plane/admin-api/admin-panel-requirements-part2.contract.ts -> auth admin-bearer
PASS

Tenant ownership guard

auth: admin-bearer

Backend generic admin mutations resolve tenant scope and reject related records from other tenants before widget instance save.

  • AdminApiService.resolveMutationTenantId
  • AdminApiService.assertRelatedRecordTenant("license", data.licenseId, tenantId, "licenseId", "LICENSE_TENANT_MISMATCH")
WARNING

License and plan entitlement validation

auth: admin-bearer

Backend contracts describe license/widget type validation, but frontend has not yet verified read-after-write entitlement evidence through an authenticated session.

  • widget instance license/widget type checks
  • validate-config preview is available before persisted save
BLOCKED

Saved vs applied/published policy

auth: not-applicable

Frontend still needs explicit savedConfig/appliedConfig/publishedAt policy before copy-code can be tied to persisted state.

  • F040 is still pending
WARNING

Revision/conflict policy

auth: admin-bearer

Backend UUID update endpoint exists; frontend DTO now carries expectedRevision, but live conflict handling is not enabled in the builder.

  • PATCH /api/admin/widget-instances/:id
  • KlineAdminWidgetPersistedSaveRequest.expectedRevision
PASS

Audit log write on mutation

/api/admin/audit-logs

auth: admin-bearer

Backend service writes audit records for admin mutations and exposes audit log reading through admin API.

  • AdminApiService.writeAudit
  • GET /api/admin/audit-logs
WARNING

Read-after-write verification path

/api/admin/widget-instances/:id

auth: admin-bearer

GET by UUID exists, but frontend edit/list reconciliation is still pending before the builder can verify persisted responses.

  • src/control-plane/admin-api/admin-api.controller.ts -> @Get("widget-instances/:id([0-9a-fA-F-]{36})")
  • F038/F039 are still pending
PASS

No secret/token exposure in UI/evidence

auth: not-applicable

Frontend redaction helpers block token-like evidence from reports; persisted save DTO does not include admin/runtime/provider tokens.

  • redactKlineSensitiveText
  • containsUnredactedKlineSecret
  • KlineAdminWidgetPersistedSaveRequest has no credential field
WARNING

Persisted create endpoint

/api/admin/widget-instances

auth: admin-bearer

Backend create endpoint exists, but frontend must not call it until session transport, saved/applied policy and live read-after-write are green.

  • src/control-plane/admin-api/admin-api.controller.ts -> @Post("widget-instances")
WARNING

Persisted update endpoint

/api/admin/widget-instances/:id

auth: admin-bearer

Backend update endpoint exists, but frontend must not call it until persisted UUID reconciliation is available.

  • src/control-plane/admin-api/admin-api.controller.ts -> @Patch("widget-instances/:id([0-9a-fA-F-]{36})")