# Authentication and authorization

Canonical: https://docs.shumoku.dev/en/server/next/concepts/authentication
Language: en
Server documentation version: next
Product version: 0.1.6-beta.4
Channel: development

This documentation describes the Server currently in development.

apps/server/docs/design/authentication-authorization.md

# Authentication and authorization

Principal resolution, proxy SSO, permissions, and future identity providers.

Shumoku separates authentication (who made the request) from authorization (what that identity may do). Every authenticated path resolves to one `AuthPrincipal` before policy is evaluated:

```
interface AuthPrincipal {
  subject: string
  role: 'anonymous' | 'viewer' | 'user' | 'admin'
  authMethod: 'anonymous' | 'password' | 'bearer' | 'proxy'
}
```

Current subjects are `local-admin`, `dev-automation`, and `proxy:<external-id>`. Proxy identities can use `viewer`, `user`, or `admin`; persistent user management is not yet exposed. This lets a future local-user or OIDC provider issue the same principal without changing route authorization.

## Permissions

Routes authorize permissions, not cookie presence or authentication method.

| Role | Permissions |
| --- | --- |
| `anonymous` | none |
| `viewer` | `workspace:read` |
| `user` | `workspace:read`, `workspace:write` |
| `admin` | all user permissions plus `admin:manage` |

Data-source and topology-source configuration, Settings, plugin management, and administrator diagnostics require `admin:manage`. Other workspace reads require `workspace:read`; mutations require `workspace:write`. A viewer is an authenticated read-only workspace user, not an anonymous fallback. Future user-facing data-source consumption should receive its own narrow permission and response DTO rather than exposing stored configuration.

HTTP and WebSocket authentication share the same principal types and permission definitions. Middleware attaches the resolved principal to the raw request via `getRequestPrincipal(request)`, so future handlers and audit logging can obtain the subject without parsing cookies again.

## Proxy authentication

`resolveRequestPrincipal` is shared by HTTP middleware, authentication status, and the WebSocket upgrade resolver. Proxy mode is exclusive: it ignores local sessions and does not fall back to development bearer credentials. Local login, setup, and password changes are disabled. Initial administrator bootstrap is still required; emergency local access requires disabling proxy mode and restarting.

Without a role header, the default role is `viewer`. Configuring a role header makes recognized membership mandatory; missing or unknown groups deny access. An explicit group map is optional; otherwise exact role names are accepted. Multiple recognized groups grant the highest role independently of header order. The proxy must replace client-supplied identity and role headers on every request, and the server must be reachable exclusively through that proxy.

Proxy principals are resolved per HTTP request and on WebSocket connection. Existing sockets retain their principal until disconnected; logout and role changes do not immediately revoke them. No local session is issued for proxy identities, and local logout cannot terminate the upstream SSO session.

A `proxy:` subject separates this identity from local accounts but is not a permanent internal user ID. Prefer immutable external identifiers; email can change. Future user management must explicitly associate provider/external IDs with internal users rather than automatically merging accounts by email.

## Sessions and future providers

Sessions store `subject`, `role`, and `auth_method`. Migration 033 upgrades existing sessions to `local-admin` / `admin` / `password`. The initial administrator Secret remains a credential bootstrap mechanism; it does not define route permissions.

When adding multiple users, introduce the user/identity store behind principal resolution and keep these invariants:

*   Routes never inspect password hashes, cookies, or provider-specific claims.
*   Providers translate their identity into `AuthPrincipal` at the boundary.
*   Authorization uses permissions, not provider names or scattered role checks.
*   Role changes invalidate or refresh affected sessions.
*   Audit records use `principal.subject` as the actor identifier.

This keeps local passwords, OIDC, LDAP, and service credentials interchangeable from the API’s point of view.

## Public demo deployment boundary

`PUBLIC_DEMO` describes a future deployment experience, not an authentication mode in the server. A demo launcher should provision an isolated, disposable container per visitor, seed sample data, generate a per-instance administrator credential, and send the visitor through the normal login flow. The credential may be shown alongside that instance’s login form because the entire instance is temporary and dedicated to that visitor.

The server must not promote anonymous requests to `viewer`, reuse management APIs as public APIs, or weaken WebSocket authentication. The launcher is responsible for expiration, resource limits, network egress policy, and teardown. If a shared public catalog is added later, it should use dedicated public routes and explicit publish state rather than the authenticated workspace API.
