Properties
category: reference tags: [architecture, admin, permissions, multi-tenancy] last_updated: 2026-03-17 confidence: high
Admin Panel Re-enablement
Analysis of which Otterwiki admin panels can be re-enabled in robot.wtf's multi-tenant platform, now that per-wiki SQLite databases are deployed.
Background
Otterwiki has 8 admin panels. Three are gated by PLATFORM_MODE (added in feat/P2-8-admin-panel-hiding). Per-wiki databases landed on 2026-03-17, meaning each wiki's preferences, drafts, user, and cache tables are now isolated.
Upstream bug found
handle_permissions_and_registration in otterwiki/preferences.py is missing the has_permission("ADMIN") guard that every other admin handler has. Fix submitted as fix/permissions-admin-guard — PR pending to redimp. Red/green verified.
Panel Status
Already working (no changes needed)
| Panel | Route | Notes |
|---|---|---|
| Application Preferences | /-/admin |
SITE_NAME, SITE_DESCRIPTION, SITE_LOGO, etc. SERVER_NAME hidden in PLATFORM_MODE. |
| Sidebar Preferences | /-/admin/sidebar_preferences |
Pure preferences. Works. |
| Content and Editing | /-/admin/content_and_editing |
COMMIT_MESSAGE, WIKILINK_STYLE, etc. Works. |
| Repository Management | /-/admin/repository_management |
✅ Gated in PLATFORM_MODE (2026-03-17). Route, nav link, pull webhook, and auto-push/pull all disabled. SSH key storage and outbound connections blocked. May re-enable with sandboxing if demand emerges. |
Phase 1: Permissions panel ✅ DEPLOYED (2026-03-17)
READ_ACCESS / WRITE_ACCESS / ATTACHMENT_ACCESS configurable via Otterwiki admin. Resolver enforces by intersecting with platform ACL. Registration fields hidden in PLATFORM_MODE. READ_ACCESS replaces is_public as sole source of truth for anonymous access.
Phase 2: User Management (consolidated)
Key decision (2026-03-17): Remove the "Collaborators" tab from the platform dashboard entirely. All user/access management happens in Otterwiki's User Management panel. This consolidates three layers (platform ACL, wiki preferences, per-wiki roster) into two places the wiki owner actually sees: the Permissions panel and the User Management panel.
Routes: /-/admin/user_management, /-/user/<uid>
Design: Explicit roster, not activity tracking
The per-wiki user table is an explicit roster managed by wiki admins, not an activity log. Users only exist there because an admin added them.
Admin workflow:
- Admin opens User Management panel in Otterwiki's admin
- Enters a DID handle (e.g.,
@alice.bsky.social) to add a user - Sets per-user flags: role (viewer/editor/admin),
is_approved - User can now access the wiki at whatever level their flags grant
Wiki admins can create other wiki admins.
Consolidating platform ACL into User Management
Currently, the platform dashboard has a "Collaborators" tab that manages the acls table in robot.db (granting owner/editor/viewer roles). Phase 2 moves this into Otterwiki's User Management panel:
- Remove the Collaborators tab from the dashboard (
wiki_settings.html) - Remove the Collaborators API endpoints from the management API (or deprecate)
- User Management becomes the single place to manage who can access the wiki and at what level
- The per-wiki
usertable replaces the platformaclstable as the source of truth for per-wiki access - The resolver reads from the per-wiki user table instead of (or in addition to) the platform ACL table
- The platform ACL ceiling is enforced implicitly: the wiki owner's own role (from the
wikistable) is the ceiling. The owner can grant up to their own level but not beyond.
Migration path
- On Phase 2 deploy, migrate existing
aclsentries into per-wikiusertables - Remove Collaborators tab from dashboard
- Remove or deprecate ACL management API endpoints
- Resolver reads permissions from per-wiki user table
email field decision — deferred
Otterwiki's User model keys on email. Two options:
- Appropriate
emailfor DID handles — quick, minimal schema divergence, but blocks future email notifications - Add a
handlecolumn — cleaner, but more fork divergence
Decision deferred. Future notification mechanism (email vs. BlueSky DMs) affects this choice.
Permission flow with APPROVED level
Once Phase 2 lands, the APPROVED access level becomes fully functional:
- Wiki owner sets
READ_ACCESS=APPROVEDin Permissions panel - Resolver checks per-wiki
usertable for the authenticated user's handle - If found and
is_approved=True: READ permission granted - If not found or not approved: READ stripped
Required changes
Otterwiki fork:
- Re-enable User Management + User Edit panels in PLATFORM_MODE
- Customize add-user form: accept DID handle, hide password fields
- Override
ProxyHeaderAuth.get_all_user()to query per-wiki user table - Map user flags to roles (viewer/editor/admin) for display
robot.wtf:
- Remove Collaborators tab from
wiki_settings.html - Remove or deprecate ACL management endpoints in
management/routes.py - Extend
_apply_wiki_access_restrictions()to query per-wiki user table for APPROVED level and per-user role - Migration script: copy
aclsentries to per-wikiusertables - Resolver reads per-wiki user table for permission computation
Keep disabled: Mail Preferences
Per-wiki SMTP config is a security/spam risk. Notification mechanism (email vs. BlueSky DMs) is an open question.
Implementation Order
Permissions panel✅ DeployedHide SERVER_NAME✅ DeployedRemove is_public toggle✅ DeployedUser Management✅ Deployed (2026-03-17) — platform ACL removed entirely, per-wiki user table is sole permission source, role UI (admin/editor/viewer) deployed, APPROVED access level functional, dashboard collapsed to single-page cardRepository Management✅ Gated in PLATFORM_MODE (2026-03-17) — route, nav, webhook, auto-push/pull all disabled
Remaining disabled
- Mail Preferences — per-wiki SMTP is a security/spam risk. Notification mechanism (email vs. BlueSky DMs) is an open question.
