This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/TURNOVER.md
Jeffrey Smith 4235e9e023
All checks were successful
CI/CD / detect-changes (pull_request) Successful in 3s
CI/CD / test-sqlite (pull_request) Has been skipped
CI/CD / test-go-pg (pull_request) Has been skipped
CI/CD / test-frontend (pull_request) Has been skipped
CI/CD / build-and-deploy (pull_request) Has been skipped
update turnover doc for v0.2.0 PR 1
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 17:31:16 +00:00

5.4 KiB

Switchboard Core — Session Turnover

Date: 2026-03-26 Author: Jeffrey Smith (jasafpro@gmail.com) Session: v0.2.0 PR 1 — Full RBAC migration


What Was Done

PR 1: Admin → RBAC group migration — COMPLETE

Branch feat/admin-rbac-migration (PR #1), 3 commits:

  1. Admin → RBAC group migrationsurface.admin.access permission + Admins system group replaces hardcoded role == "admin" checks. Admin bypass removed from RequirePermission. Bootstrap/seed/OIDC/admin handlers sync group membership.

  2. Remove token budgets + allowed models from groups — Provider-era cruft: token_budget_daily, token_budget_monthly, allowed_models columns, ResolveTokenBudget(), ResolveModelAllowlist(), and all store/handler/UI code deleted. -283 lines.

  3. Drop users.role column — Full RBAC. Zero magic roles. The role column, UserRoleAdmin/UserRoleUser constants, CountByRole(), DefaultRole config, role in JWT claims, and all role-based shortcuts removed. Everyone group membership is now explicit (all users added on create). 28 files changed.

Net result: -364 lines across 3 commits.

Architecture after this PR:

  • Everyone group (00000000...0001): all users explicitly added on creation. Carries extension.use, workflow.submit.
  • Admins group (00000000...0002): carries all 7 kernel permissions including surface.admin.access. Not special-cased — just a group with permissions.
  • Permission resolution: union of all group memberships. No implicit groups, no role shortcuts, no admin bypass.
  • Admin middleware: checks surface.admin.access grant via resolveAndCachePerms.
  • JWT claims: user_id + email only. No role.
  • OIDC: isIdPAdmin() maps IdP role claim → Admins group membership. No role column writes.
  • User creation paths: builtin register, OIDC auto-provision, mTLS auto-provision, admin create, bootstrap, seed — all call EnsureEveryoneGroup().

Known Issues

  1. Frontend test job: FE test suite may have remaining stale references from Phase 0 gut (pre-existing)
  2. Traefik middleware: rbac-traefik.yaml needs one-time manual apply by cluster admin (pre-existing, non-blocking)
  3. SEED_USERS: Not set in K8s secrets (pre-existing)
  4. Editor modules: src/editor/*.mjs still reference "Chat Switchboard" (pre-existing, low priority)
  5. K8s deploy: PR not yet merged to main — CI/CD will need a deploy after merge

What's Next

Merge PR #1

Review and merge feat/admin-rbac-migration to main.

v0.2.0 — Remaining PRs

PR 2: Settings cascade

  • Add user_overridable flag to settings schema
  • RBAC controls scope auth (admin → global, team-admin → team, user → personal)
  • Resolution: user → team → global (first non-null wins)

PR 3: ICD (API contract)

  • Generate full OpenAPI spec from registered routes
  • Document kernel-only endpoints

PR 4: Trigger system

  • Time triggers (cron), webhook (inbound HTTP), event (bus subscription)
  • Extensions register match expressions at install

PR 5: SDK stabilization

  • sb.slots(), sb.actions, sb.api.ext(), sb.storage
  • Theme tokens exposed to extensions

Architecture Decisions (this session)

Decision Detail
Full RBAC — no magic roles users.role column dropped entirely. All authorization through group membership + permission grants.
Explicit Everyone membership No implicit "all users get Everyone perms". Every user added to Everyone group on create. member_count reflects reality.
Admins group not special-cased Code never checks group identity — only checks for surface.admin.access permission. Any group can grant it.
No new migrations pre-MVP Edit existing SQL files in place. Schema isn't in production.
JWT simplified Claims carry user_id + email only. Permissions resolved server-side from groups on every request.
OIDC role → group sync isIdPAdmin() replaces resolveRole(). IdP admin claim maps to Admins group membership, not a DB column.
Token budgets/allowed models removed Provider-era cruft. Belongs in a future provider extension, not the kernel.

File Locations

What Where
Roadmap ROADMAP.md
Changelog CHANGELOG.md
CI workflow .gitea/workflows/ci.yaml
K8s manifests k8s/
Docker compose (local dev) docker-compose.yml (SQLite, port 3000)
Nginx template nginx.conf.template
Migrations server/database/migrations/{postgres,sqlite}/
Permission constants server/auth/permissions.go
Admin middleware server/middleware/admin.go
Group store server/store/{postgres,sqlite}/groups.go
Bootstrap/seed server/handlers/auth.go
Admin handlers server/handlers/admin.go
Groups UI src/js/sw/surfaces/admin/groups.js
Users UI src/js/sw/surfaces/admin/users.js
SDK API src/js/sw/sdk/api-domains.js
Memory (Claude) .claude/projects/-config-Projects-core/memory/

Gitea Secrets/Vars Needed

Secrets: POSTGRES_USER, POSTGRES_USER_PASSWORD, POSTGRES_ADMIN_USER, POSTGRES_ADMIN_PASSWORD, ENCRYPTION_KEY

Vars: DOMAIN, NAMESPACE, S3_BUCKET, S3_ENDPOINT, STORAGE_BACKEND, STORAGE_CLASS, STORAGE_SIZE

Not yet configured: S3_ACCESS_KEY, S3_SECRET_KEY (using PVC for now), SEED_USERS (needed for initial admin bootstrap)