Skip to content

Security & RBAC

Access control in StackRivet is default-deny: a protected endpoint is denied unless a permission explicitly allows it. Generated modules ship with their permission annotations, so a new module is locked down by default rather than open by accident.

  • Spring Security + a revocable token. On login the server verifies the credentials, loads the user’s roles and permissions, and issues a token; the token can be revoked (e.g. force-logout).
  • Login logs record every success and failure (with the failure reason); login-failure lockout is built in.
  • Passwords are stored as a strong hash — never in plaintext. Passwords, tokens and secrets never appear in logs.
sequenceDiagram
  actor User
  participant Web
  participant API as Auth API
  participant Sec as Security
  participant DB as Database
  User->>Web: enter username + password
  Web->>API: POST /api/v1/auth/login
  API->>Sec: verify credentials
  Sec->>DB: load user, roles, permissions
  DB-->>Sec: permission context
  Sec-->>API: issue token
  API-->>Web: token, user info, menu
  Web->>API: protected request (Bearer token)
  API->>Sec: authenticate + authorize
  Sec-->>API: allow or deny (401 / 403)

Authorization is enforced at five distinct layers — UI hiding alone is never the control:

LayerControlsEnforced
MenuWhat navigation a user seesServer-provided menu tree
ButtonWhich UI actions are availablePermission directive / component
APIWhich server endpoints a user may call@PreAuthorize-style annotations + URL matcher
DataWhich rows a query may returnQuery interceptor (see below)
AssetAccess to private filesRights check before a signed URL is issued

Default responses: 401 when unauthenticated, 403 when unauthorized.

StackRivet ships the standard enterprise org model in the Community edition:

  • Users, roles, departments, posts (job positions).
  • Menus with menu, button and API permissions attached to roles.

Roles aggregate permissions; users are assigned roles (and a department/post), and the effective permission set is resolved at login.

Data permissions are enforced on the server

Section titled “Data permissions are enforced on the server”

Row-level data scope is not a frontend convenience — it is enforced in the persistence layer.

  • The Community edition enforces the self / department / department-and-below / all scopes through a DataPermissionInterceptor, which injects the scope condition into queries. It is not frontend hiding.
  • The mechanism is extensible through the DataScopeTableContributor SPI. The mechanism ships in Community; custom data-permission policies are unlocked in Pro / Enterprise (the “mechanism up front, unlock by edition” approach).

This matters because the most common access-control bug — “the row was hidden in the UI but the API still returned it” — is structurally prevented.

  • No plaintext passwords anywhere.
  • No password, token or secret in any log line.
  • Private files require a rights check before a signed URL is minted — a signed URL is never handed out unconditionally.

The Community edition documented here includes account/password login, JWT/token management, login logs and lockout, basic password policy, session management, force-logout, full RBAC, and the basic data-permission scopes.

Enterprise authentication features — MFA, OIDC, SAML, LDAP/AD, enterprise SSO (WeCom / DingTalk / Lark) and single logout — are not in Community; they are detailed on the pricing page. The architecture leaves clean extension points for them.