mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-09-12 04:55:47 +03:00
180 lines
6.4 KiB
Markdown
180 lines
6.4 KiB
Markdown
# RBAC User Isolation Roadmap
|
|
|
|
## Overview
|
|
|
|
GNS3 3.0 ships with a complete RBAC framework (ACE + Role + Privilege models), but the user isolation layer is incomplete. Users can see resources they should not have access to because:
|
|
|
|
- Resource creation does not auto-grant the creator an ACE
|
|
- List endpoints return unfiltered results
|
|
- Two GET endpoints have RBAC checks bypassed via FIXME
|
|
|
|
This document tracks the incremental work to close those gaps. Each phase is independent and deployable.
|
|
|
|
## Current State
|
|
|
|
| Resource | Route Check | List Filtering | Auto-ACE on Create | ACE Cleanup on Delete |
|
|
|---|---|---|---|---|
|
|
| Project | `Project.Audit/Modify/Allocate` | Partial — pool isolation exists but non-pool projects leak | **Missing** | Done |
|
|
| Template | `Template.Audit` **FIXME** | None — all templates returned | **Missing** | Done |
|
|
| Node | `Node.Audit/Modify/Allocate` | N/A (inherits project) | Inherits project | N/A |
|
|
| Link | `Link.Audit/Modify/Allocate` | N/A (inherits project) | Inherits project | N/A |
|
|
| Drawing | `Drawing.Audit/Modify/Allocate` | N/A (inherits project) | Inherits project | N/A |
|
|
| Snapshot | `Snapshot.Audit/Allocate/Restore` | N/A (inherits project) | Inherits project | N/A |
|
|
| Image | `Image.Audit/Allocate` | None — all images returned | **Missing** | Missing |
|
|
| Compute | `Compute.Audit` **FIXME** | None — all computes returned | N/A (shared infra) | Done |
|
|
| Appliance | `Appliance.Audit/Allocate` | None — all appliances returned | N/A (builtin) | N/A |
|
|
| Symbol | `Symbol.Audit/Allocate` | None — all symbols returned | N/A (builtin) | N/A |
|
|
|
|
## Architecture
|
|
|
|
```mermaid
|
|
graph TD
|
|
subgraph Client
|
|
WebUI
|
|
CLI
|
|
end
|
|
|
|
subgraph "Controller API"
|
|
Auth[get_current_active_user]
|
|
PrivCheck[has_privilege]
|
|
Routes[Resource Routes]
|
|
AutoACE[auto-ACE on create]
|
|
ListFilter[ACE-based list filtering]
|
|
end
|
|
|
|
subgraph "RBAC Engine"
|
|
ACE[(ACE table)]
|
|
Role[(Role table)]
|
|
Privilege[(Privilege table)]
|
|
Checker[check_user_has_privilege]
|
|
end
|
|
|
|
WebUI --> Auth
|
|
CLI --> Auth
|
|
Auth --> Routes
|
|
Routes --> PrivCheck
|
|
Routes --> AutoACE
|
|
Routes --> ListFilter
|
|
PrivCheck --> Checker
|
|
ListFilter --> Checker
|
|
Checker --> ACE
|
|
Checker --> Role
|
|
Role --> Privilege
|
|
```
|
|
|
|
## Business Process
|
|
|
|
### Project creation with auto-ACE
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
actor U as User
|
|
participant API as POST /projects
|
|
participant Ctrl as Controller
|
|
participant ACE as ACE Table
|
|
|
|
U->>API: Create project
|
|
API->>API: has_privilege("Project.Allocate")
|
|
API->>Ctrl: add_project()
|
|
Ctrl-->>API: project
|
|
API->>ACE: create ACE<br/>(user=creator, role=User,<br/>path=/projects/{id})
|
|
API-->>U: 201 + project
|
|
```
|
|
|
|
### Project listing with ACE filtering
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
actor U as User
|
|
participant API as GET /projects
|
|
participant Ctrl as Controller
|
|
participant ACE as ACE Table
|
|
|
|
U->>API: List projects
|
|
API->>API: get_current_active_user (not superadmin)
|
|
loop Each project
|
|
API->>ACE: check_user_has_privilege(user, path, "Project.Audit")
|
|
ACE-->>API: True/False
|
|
end
|
|
API-->>U: filtered list
|
|
```
|
|
|
|
## Phased Plan
|
|
|
|
### Phase 1 — MVP: Project isolation
|
|
|
|
**Goal**: Users only see projects they created or were granted access to.
|
|
|
|
| Task | Files | Detail |
|
|
|---|---|---|
|
|
| Auto-ACE on project create | `projects.py` — `create_project()` | After `add_project()`, create ACE: user=creator, role=User, path=`/projects/{id}` |
|
|
| Fix project list filtering | `projects.py` — `get_projects()` | Remove "sees all non-pool projects" path. Return only projects passing ACE check. |
|
|
|
|
**Estimate**: 2 files, ~30 lines changed.
|
|
|
|
### Phase 2 — Template isolation
|
|
|
|
**Goal**: Users see their own templates + builtin templates only.
|
|
|
|
| Task | Files | Detail |
|
|
|---|---|---|
|
|
| Auto-ACE on template create | `templates.py` — `create_template()` | Same pattern as project |
|
|
| Fix template list filtering | `templates.py` — `get_templates()` | Filter by ACE; builtin templates always visible |
|
|
| Uncomment `Template.Audit` | `templates.py` lines 75, 167 | Restore `has_privilege("Template.Audit")` |
|
|
|
|
**Dependency**: Web UI must handle 403 from `GET /templates/{id}`. Mitigation: keep builtin templates unconditionally visible so the UI always has data.
|
|
|
|
### Phase 3 — Image isolation (optional)
|
|
|
|
**Goal**: Users see only images they uploaded.
|
|
|
|
| Task | Files |
|
|
|---|---|
|
|
| Auto-ACE on image upload | `images.py` — `upload_image()` |
|
|
| Fix image list filtering | `images.py` — `get_images()` |
|
|
| ACE cleanup on delete | `images.py` — `delete_image()` |
|
|
|
|
### Phase 4 — Default ACE for "Users" group (optional)
|
|
|
|
**Goal**: Users in "Users" group can create/list resources without admin ACE intervention.
|
|
|
|
| Task | Detail |
|
|
|---|---|
|
|
| Default ACE on `/projects` | Grant "Users" group → User role → `/projects` (propagate=False) |
|
|
| Default ACE on `/templates` | Grant "Users" group → User role → `/templates` (propagate=False) |
|
|
|
|
## API Endpoints Changed
|
|
|
|
### Phase 1
|
|
|
|
| Method | Path | Change |
|
|
|---|---|---|
|
|
| `POST` | `/v3/projects` | Auto-create ACE for creator |
|
|
| `GET` | `/v3/projects` | Filter by user ACEs |
|
|
|
|
### Phase 2
|
|
|
|
| Method | Path | Change |
|
|
|---|---|---|
|
|
| `POST` | `/v3/templates` | Auto-create ACE for creator |
|
|
| `GET` | `/v3/templates` | Filter by user ACEs + builtin |
|
|
| `GET` | `/v3/templates/{id}` | Restore `Template.Audit` check |
|
|
|
|
## Design Decisions
|
|
|
|
1. **Compute stays shared**: Computes are infrastructure, not user-owned. The `Compute.Audit` FIXME stays — all authenticated users see computes.
|
|
|
|
2. **No DB migration required**: All phases use the existing ACE/role/privilege tables. No schema changes.
|
|
|
|
3. **Performance**: Project list filtering is O(n) — iterates all projects and checks ACE per project. Acceptable for < 500 projects. Can optimize later with direct ACE path queries.
|
|
|
|
4. **The FIXME dependency**: `Template.Audit` was commented out because web UI crashes on 403. Fix requires either (a) auto-ACE so users own their templates, or (b) web UI 403 handling.
|
|
|
|
## References
|
|
|
|
- Discussion: https://github.com/GNS3/gns3-server/discussions/1949
|
|
- RBAC models: `gns3server/db/models/acl.py`, `roles.py`, `privileges.py`
|
|
- RBAC repository: `gns3server/db/repositories/rbac.py`
|
|
- Auth dependency: `gns3server/api/routes/controller/dependencies/authentication.py`
|
|
- RBAC dependency: `gns3server/api/routes/controller/dependencies/rbac.py`
|