bytechefhq / bytechefhq/bytechef

[feature] Roles and permissions

Open
#1,051 0 comments 0 reactions 1 assignee Claimed by @ivicac View on GitHub
automation backend cloud ee frontend on-premise
Dominant language
Java
Stars
1k
Forks
170
Avg merge
11h 25m
Merged PRs (30d)
115

Description

**As an** Admin

**I want to** invite other users, assign them roles and permissions

**So that** I can properly organize access to certain parts of the ByteChef platform

## Technical Details

**Core RBAC**
- `@PreAuthorize` on service methods backed by `PermissionService` with Spring Cache
- Workspace + project scope roles with role hierarchy
- Tenant-admin short-circuit
- Custom roles (EE)
- ~~Audit log~~ — out of scope, tracked in #746

**Lifecycle safety**
- Auto-assign creator as ADMIN on workspace/project creation (`ProjectCreatedEvent` → EE listener; EE `WorkspaceServiceImpl` seeds `WorkspaceUser` ADMIN)
- Backfill migration promotes existing users to ADMIN (prevents lockout on existing EE deployments)
- Last-admin protection on delete and demote
- Cache eviction on every mutation

**UI**
- RBAC permission management in project settings
- Client-side button gating

## Acceptance Criteria

- [ ] Implementation plan reviewed
- [ ] `@PreAuthorize` enforced on workspace + project service methods
- [ ] Workspace and project roles (incl. ADMIN hierarchy) functional
- [ ] Creator auto-assigned ADMIN on create (workspace + project)
- [ ] Backfill migration applied cleanly; no existing users locked out
- [ ] Last-admin protection prevents self-lockout
- [ ] Unit tests covering `PermissionServiceImpl` and `ProjectUserServiceImpl`
- [ ] RBAC UI available in project settings with scope-appropriate gating
- [ ] Custom roles (EE) supported
- [x] ~~Audit log entries emitted for permission changes~~ — moved to #746, see Scope changes

## Scope changes

**Audit log is no longer part of this issue** (2026-09-13) — it belongs to #746. The branch carried two halves of an audit
feature and neither belonged here:

- The *declarative* half — `@AuditConnection` on nine connection-facade methods — emitted nothing at
all. The aspect that reads the annotation, and the SpEL engine behind it, live on another branch and
were never ported, so every promised trail was already empty.
- The *imperative* half did work: sixteen event/publisher pairs and 59 publish calls whose events
Spring Boot's actuator listener persisted to `persistent_audit_event`.

Both were withdrawn so the feature lands whole under #746 rather than arriving in fragments inside
an RBAC branch. What stays is what `master` already owned: `platform-audit-service` and its schema,
`WorkspaceUserAuditPublisher`, and `AuditingJdbcConfiguration`.

**The permission scope catalogue was trimmed** from 13 modules to 7 (21 scopes). Withdrawn as gating
nothing: `AGENT_*`, `AI_GATEWAY_VIEW`, `EXECUTION_*`, `MCP_*`, `VARIABLE_*` and `API_KEY_*`. The last
of those is structural rather than unfinished: a scope resolves through the workspace role its holder
has, and an API key carries no workspace, so gating on one would deny every non-admin their own keys.
API keys are restricted by ownership instead — owner-or-tenant-admin on every read and write, both
listings filtered, keys revoked when the account is deleted, and platform keys issuable only by a
tenant admin.

## Remaining Gaps

- Full integration test for `ProjectUserService`
- `@PreAuthorize` rollout to MCP, agent, and deployment services
- Client button gating across remaining UI areas
- Eleven catalogued scopes still gate nothing: `CONNECTION_*` (decided by owner-or-admin instead),
`DATA_TABLE_*`, `KNOWLEDGE_BASE_*`, `DEPLOYMENT_VIEW` — each either needs a gate or should follow the
withdrawn groups
- No tenant-level custom role: a custom role is defined tenant-globally but only ever takes effect
through a workspace membership, and tenant powers hang off the `ROLE_ADMIN` authority, which is not
composable

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.