Skip to content

Authentication & RBAC

Authentication & RBAC

Rakkr is default-deny: nothing is permitted unless a role grants the permission and the actor is in scope for the specific resource. The console mirrors these rules for usability, but the API is the only enforcement point.

Who authenticates

ActorCredentialUsed for
Operators / adminsUser session token (bearer)The console and all /api/v1 user routes
Recorder agentsNode credential token (bearer)Agent service routes, scoped to one node
Automation (scheduler, runners)Service identityBackground actions, audited like any actor

Local sign-in

POST /api/v1/auth/login takes { email, password }, verified against a DB-persisted user (Argon2/bcrypt) or the env-configured local admin. On success the controller mints rakkr_<random>, stores only its SHA-256 hash, and returns a token with a 12-hour TTL. Disabling, deleting, or password-resetting a user revokes their active sessions.

Configure the local admin with RAKKR_LOCAL_ADMIN_EMAIL / _PASSWORD / _NAME / _ID. In production (NODE_ENV=production) a password is mandatory — the controller refuses to start with the dev default.

Azure AD / OIDC

OIDC is an optional Authorization Code + PKCE flow, disabled by default. When enabled, GET /api/v1/auth/oidc/login redirects to Entra, and the callback exchanges the code, syncs the user into RBAC, and returns a session. Group and app-role claims can sync into Rakkr roles and scoped grants. Setup steps and all RAKKR_OIDC_* variables are in the configuration reference; the checked behavior baseline is AZURE_AD_OIDC_BASELINE.

Node credentials

Nodes are enrolled from the console (node:manage), which issues a one-time token stored only as a hash. The agent presents it as a bearer token; agent routes verify the credential and enforce that it matches the node in the path. Rotate tokens from the Nodes page. Credentials are scoped strictly to their own node’s jobs, recordings, meters, and events.

The permission model

A user’s effective access is computed in layers:

role permissions ─┐
resource grants ├─► allow? ──► unless an explicit DENY policy applies
access policies ─┘
  1. Roles → permissions. Each role maps to a fixed permission set (defined in @rakkr/shared). owner has everything; admin has everything except system:admin; operator, viewer, and auditor are progressively narrower. See the permissions reference.
  2. Resource scope. Having a permission isn’t enough — the actor must be in scope for the target. owner/admin bypass scope; everyone else needs a matching resource grant or an allow access policy.
  3. Explicit deny wins. A deny access policy overrides any role grant or inherited visibility.

Hierarchical scope

Scope expands through the resource hierarchy, so a grant at any level applies downward:

ScopeExamples
Globalauth settings, roles, system settings
Site / Roomsite-wide inventory; room health, live listen
Nodeenroll, configure, control
Interface / Channelmeters, channel maps, listen, record
Schedulecreate, edit, run-now, delete
Recordingplayback, download, rename, tag, delete
Alertacknowledge, suppress, resolve

A recording, for instance, expands to its schedule, node, room, and site — a grant on the node covers the recordings captured there. A recorder-level deny blocks node access, its recordings, meters, live listen, and controls together.

Access policies and grants

Administrators (auth:manage) manage access on the Access page:

  • Access policies — structured allow | deny rules for a subject (user, group, or everyone) on a resource (type + id), with a reason. The composer builds these; explicit deny always takes precedence.
  • Resource grants — direct per-user scope grants (e.g. “this user can act on node_x32_test”).
  • Users, roles, groups — create local users, assign roles/groups, reset passwords, enable/disable, and delete (you cannot disable or delete your own account).

For local development you can seed grants and policies with RAKKR_LOCAL_RESOURCE_GRANTS and RAKKR_LOCAL_ACCESS_POLICIES.

Audit

Every privileged route writes an audit event — including denied attempts and automated service actions. Events capture actor, permission, target, outcome (allowed/denied/failed/succeeded/partial), reason, correlation IDs, and before/after snapshots for writes. The Audit page (audit:read) filters by actor, action, permission, target, outcome, reason, and time, expands before/after detail, and exports scoped CSV.

The checked RBAC/audit contract is the RBAC_AUDIT_BASELINE. The console’s permission mirroring is itself regression-tested so privileged controls can’t be exposed by UI state alone.