Pulse/docs/RBAC.md
rcourtman 9496d6f6d8 Fix four customer-facing doc drift findings (RBAC, OIDC, helm, webhooks)
RBAC.md (alerts:read → monitoring:read):
The example team-setup table told operators to issue API tokens with an
"alerts:read" scope. That scope does not exist in pkg/auth/scopes.go;
defined scopes are monitoring:read, settings:read, etc. /api/alerts/ is
gated by RequireAuth (no specific scope required), so an integrator
issuing a token would naturally pick the closest real scope —
monitoring:read — and that is what the doc should have shown.

OIDC.md (OIDC_GROUP_ROLE_MAPPINGS, OIDC_CA_BUNDLE):
Both env vars were documented but zero code reads them. OIDC config is
per-provider in internal/config/sso.go and OIDCProviderConfig in
internal/config/oidc.go: groupRoleMappings is a map field; caBundle is a
path field. Replace both env-var snippets with the actual UI/API path so
operators following the secure-install flow don't silently get no group
mapping or no custom CA trust. Same drift pattern as the earlier rc.1 →
rc.5 PULSE_RELAY_* aspiration-without-implementation.

WEBHOOKS.md (missing helpers):
notifications.go's templateFuncMap registers jsonString and pathescape
on every webhook template, but the helper list only documented title /
upper / lower / printf / urlquery / urlencode / urlpath. Add both, with
a short note that jsonString is the safe way to embed arbitrary string
values inside a JSON payload — Pulse's shipped templates use it
everywhere a value goes inside JSON, and operators writing custom
templates were missing the canonical escape primitive.

KUBERNETES.md (helm path + markdown fence):
- "deployment.strategy.type=Recreate" was the wrong helm path. The
  chart's strategy block is at the top level (deploy/helm/pulse/values.yaml
  line 9), so `strategy.type=Recreate` is what operators must actually
  --set. Following the broken path produced no override and left RWO
  PVC deployments on the default RollingUpdate, the exact Multi-Attach
  failure mode the note was trying to warn against.
- Trailing ```text on the helm-template code block closed the fence
  but tagged it as a language, breaking markdown rendering in some
  readers. Reduced to plain ```.

All four are doc-only changes; no code reads the names they document.
2026-05-12 15:54:24 +01:00

5.9 KiB

Role-Based Access Control (RBAC)

RBAC lets you define custom roles with granular permissions and assign them to users. This restricts what each user can see and do in Pulse.

Requires: Pro, legacy Pro+, or Cloud license with the rbac capability.

For plan details, see PULSE_PRO.md. For API endpoints, see API Reference.


Concepts

Roles

A role is a named set of permissions. Each permission is an (action, resource) pair:

  • action: read, write, delete, or admin
  • resource: A Pulse resource type (e.g., alerts, settings, nodes, ai)

Pulse ships with built-in roles: admin (full access), operator (manage alerts and resources), viewer (read-only), and auditor (audit log access). You can create additional custom roles for more granular control.

Role Assignment

Users can hold multiple roles. Their effective permissions are combined across all assigned roles. Explicit deny rules take precedence over allow grants.

OIDC Group Mapping

When using OIDC/SSO, roles can be automatically assigned based on group membership. See OIDC Group-to-Role Mapping for configuration.


Quick Start

  1. Activate a Pro, grandfathered Pro+, or Cloud license in Settings → Plans.
  2. Go to Settings → Security → Access Control.
  3. Create roles with the permissions you need.
  4. Assign roles to users.

Managing Roles

Creating a Role

UI: Settings → Security → Access Control → Create Role

API:

curl -X POST http://localhost:7655/api/admin/roles \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "operator",
    "name": "Operator",
    "description": "Can view and manage alerts",
    "permissions": [
      {"action": "read", "resource": "alerts"},
      {"action": "write", "resource": "alerts"},
      {"action": "read", "resource": "nodes"}
    ]
  }'

Listing Roles

curl http://localhost:7655/api/admin/roles \
  -H "Authorization: Bearer $TOKEN"

Updating a Role

curl -X PUT http://localhost:7655/api/admin/roles/operator \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Operator",
    "description": "Updated description",
    "permissions": [
      {"action": "read", "resource": "alerts"},
      {"action": "write", "resource": "alerts"},
      {"action": "read", "resource": "nodes"},
      {"action": "read", "resource": "ai"}
    ]
  }'

Deleting a Role

curl -X DELETE http://localhost:7655/api/admin/roles/operator \
  -H "Authorization: Bearer $TOKEN"

Managing User Assignments

Listing Users and Their Roles

curl http://localhost:7655/api/admin/users \
  -H "Authorization: Bearer $TOKEN"

Setting Roles for a User

Role assignments are set as a complete list — the user's roles are replaced with the provided set:

curl -X PUT http://localhost:7655/api/admin/users/jane/roles \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"roleIds": ["operator", "viewer"]}'

To remove all custom roles from a user, send an empty list:

curl -X PUT http://localhost:7655/api/admin/users/jane/roles \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"roleIds": []}'

Note: Users cannot modify their own role assignments (self-escalation prevention).


Automatic Role Assignment via OIDC

If you use an OIDC identity provider, Pulse can automatically assign roles based on group membership on each login.

UI: Settings → Security → Single Sign-On → Group Role Mappings

Environment variable:

# Format: group1=role1,group2=role2
OIDC_GROUP_ROLE_MAPPINGS="oidc-admins=admin,oidc-operators=operator,oidc-viewers=viewer"

How it works:

  • On each login, Pulse reads the user's groups from the OIDC groups claim.
  • Matching groups are mapped to Pulse roles.
  • A user can receive multiple roles from multiple group mappings.
  • When at least one mapped role is found, role assignments are updated to match. Note: logins with zero matching groups do not clear existing role assignments.
  • Role changes are logged to the audit log as oidc_role_assignment events.

See OIDC documentation for full configuration details.


Organization Roles (Multi-Tenant)

In multi-tenant deployments (Cloud Enterprise), each organization has its own role hierarchy:

Role Permissions
Owner Full control. Can transfer ownership and delete the org.
Admin Manage members, shares, and org settings. Cannot transfer ownership.
Editor Read/write access to org resources. Cannot manage members.
Viewer Read-only access to all org data.

These organization roles are separate from the RBAC custom roles described above. Organization roles control access within a specific tenant, while RBAC roles control access to Pulse features globally.

See Multi-Tenant Organizations for details.


Example: Team Setup

A typical team configuration:

User Role Access
alice admin Full access to everything
bob operator Can view nodes/VMs and manage alerts
carol viewer Read-only access to monitoring views and metrics
monitoring-bot API token with monitoring:read scope Automated alert polling