Commit b93485d
feat(api-server): RBAC enforcement with scope-aware authorization (#1660)
## Summary
Implements specs/security/rbac-enforcement.spec.md — scope-aware RBAC
authorization for the ambient-api-server.
- **Scope-aware middleware**: Evaluates bindings against the specific
project/agent/session/credential being accessed
- **User auto-provisioning**: Creates User record from JWT claims on
first authenticated request
- **Bootstrap bindings**: project:owner on POST /projects,
credential:owner on POST /credentials
- **List filtering**: Projects, sessions, credentials filtered to
caller's authorized scope
- **Error opacity**: Singleton GET returns 404 (not 403), mutations
return opaque 403
- **Escalation prevention**: Role hierarchy enforced, internal roles
blocked, scoped to target project
- **Last-owner protection**: 409 on deleting sole owner binding
- **Credential binding**: Requires both credential:owner AND
project:owner
- **gRPC authorization**: Watch streams filtered by authorized project
IDs
- **seed-admin CLI**: Initial admin bootstrap command
- **New Project button**: Dashboard dialog with DNS-1123 validation
## Test plan
- [x] 124 e2e tests passing (idempotent, self-cleaning)
- [x] Generative escalation matrix: 43 combinations derived from
hierarchy rule
- [x] Integration tests with real RBAC middleware
- [x] Unit tests for scope extraction, permission matching, hierarchy
checks
- [x] E2e wired into CI pipeline
Generated with [Claude Code](https://claude.com/claude-code)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* RBAC enforcement with role hierarchies and scope-aware permissions;
list endpoints now hide/disallow items when unauthorized
* Automatic owner bindings for newly created projects and credentials
* Admin-seed CLI for bootstrapping an admin account
* UI: "New Project" dialog with DNS-1123 name validation and create flow
* Credential token access now subject to RBAC controls
* **Bug Fixes**
* Last-owner protection for role bindings
* Partial unique username index to prevent duplicate users
* **Tests**
* Comprehensive RBAC integration tests and a new end-to-end RBAC test
suite
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>1 parent bd7ae53 commit b93485d
112 files changed
Lines changed: 7553 additions & 1170 deletions
File tree
- .github/workflows
- components
- ambient-api-server
- cmd/ambient-api-server
- environments
- openapi
- pkg
- api/openapi
- api
- docs
- cmd
- middleware
- rbac
- plugins
- agents
- common
- credentials
- inbox
- projectSettings
- projects
- roleBindings
- scheduledSessions
- sessions
- users
- test
- e2e
- integration
- ambient-ui
- src
- adapters
- app/(dashboard)
- _components
- components
- ports
- queries
- test-results
- e2e/scripts
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
| 35 | + | |
35 | 36 | | |
36 | 37 | | |
37 | 38 | | |
| |||
55 | 56 | | |
56 | 57 | | |
57 | 58 | | |
| 59 | + | |
| 60 | + | |
58 | 61 | | |
59 | 62 | | |
60 | 63 | | |
| |||
142 | 145 | | |
143 | 146 | | |
144 | 147 | | |
| 148 | + | |
| 149 | + | |
145 | 150 | | |
146 | 151 | | |
147 | 152 | | |
| |||
186 | 191 | | |
187 | 192 | | |
188 | 193 | | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
189 | 206 | | |
190 | 207 | | |
191 | 208 | | |
| |||
222 | 239 | | |
223 | 240 | | |
224 | 241 | | |
| 242 | + | |
225 | 243 | | |
226 | 244 | | |
227 | 245 | | |
| |||
232 | 250 | | |
233 | 251 | | |
234 | 252 | | |
| 253 | + | |
235 | 254 | | |
236 | 255 | | |
237 | 256 | | |
| |||
317 | 336 | | |
318 | 337 | | |
319 | 338 | | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
320 | 352 | | |
321 | 353 | | |
322 | 354 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
226 | 226 | | |
227 | 227 | | |
228 | 228 | | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
229 | 247 | | |
230 | 248 | | |
231 | 249 | | |
| |||
Lines changed: 1 addition & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
36 | | - | |
37 | 36 | | |
38 | 37 | | |
39 | 38 | | |
| |||
52 | 51 | | |
53 | 52 | | |
54 | 53 | | |
55 | | - | |
| 54 | + | |
56 | 55 | | |
57 | 56 | | |
58 | 57 | | |
| |||
Lines changed: 0 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
40 | | - | |
41 | 40 | | |
42 | 41 | | |
43 | 42 | | |
| |||
Lines changed: 1 addition & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| 39 | + | |
39 | 40 | | |
40 | 41 | | |
41 | 42 | | |
| |||
0 commit comments