Properties
status: current
platform: robot.wtf (VPS)

Extracted from the original wikibot.io design. AWS-specific content archived at Archive/AWS_Design/Auth.

See also: Design/VPS_Architecture, Design/Data_Model.


Auth Overview

ATProto OAuth login — users authenticate via their ATProto identity (Bluesky handle/DID). The platform runs a self-hosted OAuth 2.1 Authorization Server for MCP connections.

Three auth paths, all converging on the same identity resolution and ACL check:

  1. Browser session: ATProto OAuth → platform issues a session JWT (signed with our RS256 key) → middleware validates JWT on each request → resolves user → checks ACL → sets Otterwiki headers.
  2. MCP OAuth (Claude.ai): Self-hosted OAuth 2.1 AS handles DCR, PKCE, token issuance, JWKS. Claude.ai discovers /.well-known/oauth-protected-resource, authenticates, presents access token. Per-wiki authorization in our middleware.
  3. Bearer token (Claude Code, API clients): Token in Authorization header → middleware hashes token, looks up in DB → resolves to user + wiki → checks ACL.

The platform middleware is the single authentication boundary. Everything downstream trusts it.

MCP Auth

OAuth 2.1 (Claude.ai): Self-hosted AS (authlib-based) provides DCR, PKCE, AS metadata, token endpoint, and JWKS. The MCP endpoint serves /.well-known/oauth-protected-resource pointing to the local AS. Per-wiki authorization happens in middleware — the AS identifies the user, middleware checks wiki access. See Design/VPS_Architecture for implementation details.

Bearer token (Claude Code / API): Each wiki gets a unique MCP bearer token, stored as a bcrypt hash in the platform DB. The user sees the token once (at creation) and can regenerate it from the dashboard. Usage: claude mcp add --transport http.

ACL Model

Simple role-based model:

Role Read Write Delete Manage ACL Delete wiki
viewer yes no no no no
editor yes yes yes no no
owner yes yes yes yes yes

Wiki creator is always owner. Owners can grant viewer/editor access to other registered users.

Authorization Flow

Layer 1 — Platform middleware (before Otterwiki sees the request):

  1. Resolve user identity from JWT or bearer token
  2. Resolve wiki from request routing
  3. Look up ACL: does this user have a grant on this wiki?
  4. If no grant and wiki is not public → 403
  5. Map ACL role to Otterwiki permission headers:
ACL role x-otterwiki-permissions header
viewer READ
editor READ,WRITE,UPLOAD
owner READ,WRITE,UPLOAD,ADMIN
anonymous (public wiki) Synthetic user with READ only
  1. Set headers: x-otterwiki-email, x-otterwiki-name, x-otterwiki-permissions
  2. Forward to Otterwiki

Layer 2 — Otterwiki (AUTH_METHOD=PROXY_HEADER):

  • Reads headers, creates ephemeral user object per request
  • No local user database — all identity comes from headers
  • Enforces READ/WRITE/UPLOAD/ADMIN based on the permissions header

For MCP and API paths, Otterwiki is not involved in auth — the handlers read the git repo directly. Authorization happens entirely in Layer 1.

Public wiki access

The platform middleware injects a synthetic anonymous user with READ permission for public wikis. Otterwiki config stays identical for all wikis:

AUTH_METHOD = "PROXY_HEADER"
READ_ACCESS = "APPROVED"          # always — public access handled by middleware
WRITE_ACCESS = "APPROVED"
ATTACHMENT_ACCESS = "APPROVED"
DISABLE_REGISTRATION = True       # no Otterwiki-level registration

Otterwiki Admin Panel — Section Disposition

The wiki owner (ACL role owner) gets ADMIN permission → access to /-/admin/*.

Admin section Disposition Reason
Application Preferences Keep Wiki branding: site name, description, logo, favicon, language
Sidebar Preferences Keep UI layout: sidebar shortcuts, custom menu items
Content and Editing Keep Git workflow: commit message mode/template, page name casing, WikiLink style
Repository Management Disable Conflicts with platform Git management
Permissions and Registration Disable Conflicts with platform auth (middleware-managed)
User Management Disable No local user database in ProxyHeaderAuth mode
Mail Preferences Disable for MVP SMTP notifications — revisit later

Implementation: Override admin navigation template to hide disabled sections. Return 404 from disabled routes in middleware (defense in depth).

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9