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.
Authentication
Section titled “Authentication”- 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)
Five permission layers
Section titled “Five permission layers”Authorization is enforced at five distinct layers — UI hiding alone is never the control:
| Layer | Controls | Enforced |
|---|---|---|
| Menu | What navigation a user sees | Server-provided menu tree |
| Button | Which UI actions are available | Permission directive / component |
| API | Which server endpoints a user may call | @PreAuthorize-style annotations + URL matcher |
| Data | Which rows a query may return | Query interceptor (see below) |
| Asset | Access to private files | Rights check before a signed URL is issued |
Default responses: 401 when unauthenticated, 403 when unauthorized.
RBAC model
Section titled “RBAC model”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
DataScopeTableContributorSPI. 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.
Secret hygiene
Section titled “Secret hygiene”- 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.
Edition boundary
Section titled “Edition boundary”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.