feat: granular RBAC with resource/operation bindings, users, groups
Some checks failed
CI / lint (pull_request) Has been cancelled
CI / typecheck (pull_request) Has been cancelled
CI / test (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
CI / package (pull_request) Has been cancelled

- Replace admin role with granular roles: view, create, delete, edit, run
- Two binding types: resource bindings (role+resource+optional name) and
  operation bindings (role:run + action like backup, logs, impersonate)
- Name-scoped resource bindings for per-instance access control
- Remove role from project members (all permissions via RBAC)
- Add users, groups, RBAC CRUD endpoints and CLI commands
- describe user/group shows all RBAC access (direct + inherited)
- create rbac supports --subject, --binding, --operation flags
- Backup/restore handles users, groups, RBAC definitions
- mcplocal project-based MCP endpoint discovery
- Full test coverage for all new functionality

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Michal
2026-02-23 11:05:19 +00:00
parent a6b5e24a8d
commit dcda93d179
67 changed files with 7256 additions and 498 deletions

View File

@@ -15,13 +15,17 @@ model User {
name String?
passwordHash String
role Role @default(USER)
provider String?
externalId String?
version Int @default(1)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
sessions Session[]
auditLogs AuditLog[]
projects Project[]
sessions Session[]
auditLogs AuditLog[]
ownedProjects Project[]
projectMemberships ProjectMember[]
groupMemberships GroupMember[]
@@index([email])
}
@@ -71,6 +75,7 @@ model McpServer {
templateVersion String?
instances McpInstance[]
projects ProjectServer[]
@@index([name])
}
@@ -117,23 +122,95 @@ model Secret {
@@index([name])
}
// ── Groups ──
model Group {
id String @id @default(cuid())
name String @unique
description String @default("")
version Int @default(1)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
members GroupMember[]
@@index([name])
}
model GroupMember {
id String @id @default(cuid())
groupId String
userId String
createdAt DateTime @default(now())
group Group @relation(fields: [groupId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([groupId, userId])
@@index([groupId])
@@index([userId])
}
// ── RBAC Definitions ──
model RbacDefinition {
id String @id @default(cuid())
name String @unique
subjects Json @default("[]")
roleBindings Json @default("[]")
version Int @default(1)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([name])
}
// ── Projects ──
model Project {
id String @id @default(cuid())
name String @unique
description String @default("")
proxyMode String @default("direct")
llmProvider String?
llmModel String?
ownerId String
version Int @default(1)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade)
owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade)
servers ProjectServer[]
members ProjectMember[]
@@index([name])
@@index([ownerId])
}
model ProjectServer {
id String @id @default(cuid())
projectId String
serverId String
createdAt DateTime @default(now())
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
server McpServer @relation(fields: [serverId], references: [id], onDelete: Cascade)
@@unique([projectId, serverId])
}
model ProjectMember {
id String @id @default(cuid())
projectId String
userId String
createdAt DateTime @default(now())
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([projectId, userId])
}
// ── MCP Instances (running containers) ──
model McpInstance {