Files
safetynet/docs/admin-security.md
T
2026-10-13 10:34:48 +02:00

4.1 KiB

Management access and deployment

Management is a separate web application. Browser enrollment never grants management authority. The server authenticates and authorizes each management endpoint, including personal bookmark routes registered before the general management router.

Roles

Configure exact group names from the verified OIDC groups claim:

Environment variable Role Authority
OIDC_ADMIN_GROUP Administrator Publish policy and teaching references; all management operations
OIDC_OPERATOR_GROUP Operator Read policy/audit, enroll/revoke devices, review/edit personal bookmarks if policy permits, prepare teaching drafts and test integrations; cannot publish policy or change document inspection policy
OIDC_AUDITOR_GROUP Auditor Read overview, policy, security audit and teaching drafts; cannot mutate management state or inspect personal bookmarks

Operator and auditor group mappings are disabled until configured. Multiple matching groups use the highest role: administrator, then operator, then auditor. Membership is validated during signed OIDC login. Sessions expire after eight hours; group removal at the identity provider does not yet immediately invalidate an existing session. Administrators can inventory active sessions and immediately revoke existing cookies through the Access & sessions panel. Continuous group synchronization remains production work. Revoking an existing session does not prevent a new login while the identity provider still grants the management group.

GET /api/admin/session and the overview return the normalized role and permission list. The frontend uses these to explain unavailable operations. Backend permission checks remain authoritative: session-supplied permission arrays are ignored, unknown roles are rejected and new endpoints have no access until assigned an explicit permission.

GET /api/admin/sessions returns at most 500 active sessions with opaque random revocation IDs, subject, display name, role and expiry. It never returns credentials or database session hashes. POST /api/admin/sessions/:id/revoke accepts an empty object and atomically deletes the session and its handle. Only the administrator's sessions.manage permission allows either route. Session review and revocation audit records contain the acting administrator and counts, without target credentials or target identities.

Bootstrap and transport

ADMIN_TOKEN is a development credential accepted only with an HTTP loopback PUBLIC_URL. Development HTTP startup also rejects a non-loopback bind address. HTTPS management never accepts this shared token. HTTPS server startup requires OIDC_ISSUER and OIDC_CLIENT_ID, and the protected policy management channel. Configure the reverse proxy to terminate HTTPS and keep the management service bound privately; do not publish the development HTTP listener.

Cookie sessions use HttpOnly, SameSite=Lax and Secure for HTTPS. Cookie-authenticated mutations and logout require an exact Origin match with PUBLIC_URL; configure the externally visible canonical origin correctly. Cross-site writes are rejected. Responses have a restrictive same-origin CSP, forbid framing and disable caching. Bearer development fixtures do not need a browser Origin header.

This implements three application roles and optional mandatory independent policy approval through REQUIRE_INDEPENDENT_POLICY_APPROVAL. The author cannot approve its own immutable proposal; all policy publication paths use one publisher. See policy-review.md. Restrictive device groups and explicit pilot rollout are implemented in group-policy-rollout.md. Dynamic IdP membership, phishing-resistant MFA enforcement, IdP logout/back-channel revocation, HSM custody and independently assessed production deployment remain open.

Verification

The server tests exercise real signed OIDC operator/auditor sessions, direct unauthorized management requests, personal bookmark read denial, policy publication denial, unknown-role rejection, forged session permission rejection, exact-origin cookie writes, remote bootstrap-token rejection, opaque session inventory and immediate session revocation.