|
8 | 8 | Seeding is idempotent - existing scopes/roles are not duplicated. |
9 | 9 | """ |
10 | 10 |
|
11 | | -from __future__ import annotations |
12 | | - |
13 | | -from typing import TYPE_CHECKING |
| 11 | +from typing import NamedTuple |
14 | 12 | from uuid import UUID, uuid4 |
15 | 13 |
|
16 | 14 | from sqlalchemy import select |
17 | 15 | from sqlalchemy.dialects.postgresql import insert as pg_insert |
| 16 | +from sqlalchemy.ext.asyncio import AsyncSession |
18 | 17 |
|
19 | 18 | from tracecat.authz.enums import ScopeSource |
20 | 19 | from tracecat.authz.scopes import PRESET_ROLE_SCOPES |
21 | 20 | from tracecat.db.models import Organization, Role, RoleScope, Scope |
22 | 21 | from tracecat.logger import logger |
23 | 22 |
|
24 | | -if TYPE_CHECKING: |
25 | | - from sqlalchemy.ext.asyncio import AsyncSession |
26 | | - |
27 | 23 | # ============================================================================= |
28 | 24 | # System Scope Definitions |
29 | 25 | # ============================================================================= |
30 | 26 |
|
31 | 27 | # These are the canonical system scopes that should exist in every deployment. |
32 | | -# Format: (name, resource, action, description) |
33 | 28 |
|
34 | | -SYSTEM_SCOPE_DEFINITIONS: list[tuple[str, str, str, str]] = [ |
| 29 | + |
| 30 | +class ScopeDefinition(NamedTuple): |
| 31 | + name: str |
| 32 | + resource: str |
| 33 | + action: str |
| 34 | + description: str |
| 35 | + |
| 36 | + |
| 37 | +SYSTEM_SCOPE_DEFINITIONS: list[ScopeDefinition] = [ |
35 | 38 | # Org-level scopes |
36 | | - ("org:read", "org", "read", "View organization settings"), |
37 | | - ("org:update", "org", "update", "Modify organization settings"), |
38 | | - ("org:delete", "org", "delete", "Delete organization"), |
| 39 | + ScopeDefinition("org:read", "org", "read", "View organization settings"), |
| 40 | + ScopeDefinition("org:update", "org", "update", "Modify organization settings"), |
| 41 | + ScopeDefinition("org:delete", "org", "delete", "Delete organization"), |
39 | 42 | # Org member management |
40 | | - ("org:member:read", "org:member", "read", "List organization members"), |
41 | | - ("org:member:invite", "org:member", "invite", "Invite users to organization"), |
42 | | - ("org:member:remove", "org:member", "remove", "Remove users from organization"), |
43 | | - ("org:member:update", "org:member", "update", "Change member organization roles"), |
| 43 | + ScopeDefinition( |
| 44 | + "org:member:read", "org:member", "read", "List organization members" |
| 45 | + ), |
| 46 | + ScopeDefinition( |
| 47 | + "org:member:invite", "org:member", "invite", "Invite users to organization" |
| 48 | + ), |
| 49 | + ScopeDefinition( |
| 50 | + "org:member:remove", "org:member", "remove", "Remove users from organization" |
| 51 | + ), |
| 52 | + ScopeDefinition( |
| 53 | + "org:member:update", "org:member", "update", "Change member organization roles" |
| 54 | + ), |
44 | 55 | # Billing |
45 | | - ("org:billing:read", "org:billing", "read", "View billing information"), |
46 | | - ("org:billing:manage", "org:billing", "manage", "Manage billing"), |
| 56 | + ScopeDefinition( |
| 57 | + "org:billing:read", "org:billing", "read", "View billing information" |
| 58 | + ), |
| 59 | + ScopeDefinition("org:billing:manage", "org:billing", "manage", "Manage billing"), |
47 | 60 | # RBAC administration |
48 | | - ( |
| 61 | + ScopeDefinition( |
49 | 62 | "org:rbac:read", |
50 | 63 | "org:rbac", |
51 | 64 | "read", |
52 | 65 | "View roles, scopes, groups, and assignments", |
53 | 66 | ), |
54 | | - ( |
| 67 | + ScopeDefinition( |
55 | 68 | "org:rbac:manage", |
56 | 69 | "org:rbac", |
57 | 70 | "manage", |
58 | 71 | "Create/update/delete roles, scopes, groups, and manage assignments", |
59 | 72 | ), |
60 | 73 | # Workspace-level scopes |
61 | | - ("workspace:read", "workspace", "read", "View workspace settings"), |
62 | | - ("workspace:create", "workspace", "create", "Create workspaces"), |
63 | | - ("workspace:update", "workspace", "update", "Modify workspace settings"), |
64 | | - ("workspace:delete", "workspace", "delete", "Delete workspace"), |
| 74 | + ScopeDefinition("workspace:read", "workspace", "read", "View workspace settings"), |
| 75 | + ScopeDefinition("workspace:create", "workspace", "create", "Create workspaces"), |
| 76 | + ScopeDefinition( |
| 77 | + "workspace:update", "workspace", "update", "Modify workspace settings" |
| 78 | + ), |
| 79 | + ScopeDefinition("workspace:delete", "workspace", "delete", "Delete workspace"), |
65 | 80 | # Workspace member management |
66 | | - ("workspace:member:read", "workspace:member", "read", "List workspace members"), |
67 | | - ("workspace:member:invite", "workspace:member", "invite", "Add users to workspace"), |
68 | | - ( |
| 81 | + ScopeDefinition( |
| 82 | + "workspace:member:read", "workspace:member", "read", "List workspace members" |
| 83 | + ), |
| 84 | + ScopeDefinition( |
| 85 | + "workspace:member:invite", |
| 86 | + "workspace:member", |
| 87 | + "invite", |
| 88 | + "Add users to workspace", |
| 89 | + ), |
| 90 | + ScopeDefinition( |
69 | 91 | "workspace:member:remove", |
70 | 92 | "workspace:member", |
71 | 93 | "remove", |
72 | 94 | "Remove users from workspace", |
73 | 95 | ), |
74 | | - ( |
| 96 | + ScopeDefinition( |
75 | 97 | "workspace:member:update", |
76 | 98 | "workspace:member", |
77 | 99 | "update", |
78 | 100 | "Change member workspace roles", |
79 | 101 | ), |
80 | 102 | # Workflow scopes |
81 | | - ("workflow:read", "workflow", "read", "View workflows and their details"), |
82 | | - ("workflow:create", "workflow", "create", "Create new workflows"), |
83 | | - ("workflow:update", "workflow", "update", "Modify existing workflows"), |
84 | | - ("workflow:delete", "workflow", "delete", "Delete workflows"), |
85 | | - ("workflow:execute", "workflow", "execute", "Run/trigger workflows"), |
| 103 | + ScopeDefinition( |
| 104 | + "workflow:read", "workflow", "read", "View workflows and their details" |
| 105 | + ), |
| 106 | + ScopeDefinition("workflow:create", "workflow", "create", "Create new workflows"), |
| 107 | + ScopeDefinition( |
| 108 | + "workflow:update", "workflow", "update", "Modify existing workflows" |
| 109 | + ), |
| 110 | + ScopeDefinition("workflow:delete", "workflow", "delete", "Delete workflows"), |
| 111 | + ScopeDefinition("workflow:execute", "workflow", "execute", "Run/trigger workflows"), |
86 | 112 | # Case scopes |
87 | | - ("case:read", "case", "read", "View cases"), |
88 | | - ("case:create", "case", "create", "Create new cases"), |
89 | | - ("case:update", "case", "update", "Modify existing cases"), |
90 | | - ("case:delete", "case", "delete", "Delete cases"), |
| 113 | + ScopeDefinition("case:read", "case", "read", "View cases"), |
| 114 | + ScopeDefinition("case:create", "case", "create", "Create new cases"), |
| 115 | + ScopeDefinition("case:update", "case", "update", "Modify existing cases"), |
| 116 | + ScopeDefinition("case:delete", "case", "delete", "Delete cases"), |
91 | 117 | # Table scopes |
92 | | - ("table:read", "table", "read", "View tables"), |
93 | | - ("table:create", "table", "create", "Create new tables"), |
94 | | - ("table:update", "table", "update", "Modify existing tables"), |
95 | | - ("table:delete", "table", "delete", "Delete tables"), |
| 118 | + ScopeDefinition("table:read", "table", "read", "View tables"), |
| 119 | + ScopeDefinition("table:create", "table", "create", "Create new tables"), |
| 120 | + ScopeDefinition("table:update", "table", "update", "Modify existing tables"), |
| 121 | + ScopeDefinition("table:delete", "table", "delete", "Delete tables"), |
96 | 122 | # Schedule scopes |
97 | | - ("schedule:read", "schedule", "read", "View schedules"), |
98 | | - ("schedule:create", "schedule", "create", "Create new schedules"), |
99 | | - ("schedule:update", "schedule", "update", "Modify existing schedules"), |
100 | | - ("schedule:delete", "schedule", "delete", "Delete schedules"), |
| 123 | + ScopeDefinition("schedule:read", "schedule", "read", "View schedules"), |
| 124 | + ScopeDefinition("schedule:create", "schedule", "create", "Create new schedules"), |
| 125 | + ScopeDefinition( |
| 126 | + "schedule:update", "schedule", "update", "Modify existing schedules" |
| 127 | + ), |
| 128 | + ScopeDefinition("schedule:delete", "schedule", "delete", "Delete schedules"), |
101 | 129 | # Agent scopes |
102 | | - ("agent:read", "agent", "read", "View agents"), |
103 | | - ("agent:create", "agent", "create", "Create new agents"), |
104 | | - ("agent:update", "agent", "update", "Modify existing agents"), |
105 | | - ("agent:delete", "agent", "delete", "Delete agents"), |
106 | | - ("agent:execute", "agent", "execute", "Run/trigger agents"), |
| 130 | + ScopeDefinition("agent:read", "agent", "read", "View agents"), |
| 131 | + ScopeDefinition("agent:create", "agent", "create", "Create new agents"), |
| 132 | + ScopeDefinition("agent:update", "agent", "update", "Modify existing agents"), |
| 133 | + ScopeDefinition("agent:delete", "agent", "delete", "Delete agents"), |
| 134 | + ScopeDefinition("agent:execute", "agent", "execute", "Run/trigger agents"), |
107 | 135 | # Secret scopes |
108 | | - ("secret:read", "secret", "read", "View secrets"), |
109 | | - ("secret:create", "secret", "create", "Create new secrets"), |
110 | | - ("secret:update", "secret", "update", "Modify existing secrets"), |
111 | | - ("secret:delete", "secret", "delete", "Delete secrets"), |
| 136 | + ScopeDefinition("secret:read", "secret", "read", "View secrets"), |
| 137 | + ScopeDefinition("secret:create", "secret", "create", "Create new secrets"), |
| 138 | + ScopeDefinition("secret:update", "secret", "update", "Modify existing secrets"), |
| 139 | + ScopeDefinition("secret:delete", "secret", "delete", "Delete secrets"), |
112 | 140 | # Wildcard action scopes (for role assignments) |
113 | | - ("action:*:execute", "action", "execute", "Execute any registry action"), |
114 | | - ( |
| 141 | + ScopeDefinition( |
| 142 | + "action:*:execute", "action", "execute", "Execute any registry action" |
| 143 | + ), |
| 144 | + ScopeDefinition( |
115 | 145 | "action:core.*:execute", |
116 | 146 | "action:core", |
117 | 147 | "execute", |
|
125 | 155 |
|
126 | 156 | # Preset roles seeded per-organization. |
127 | 157 | # Slugs match the keys in PRESET_ROLE_SCOPES from scopes.py. |
128 | | -PRESET_ROLE_DEFINITIONS: dict[str, tuple[str, str, frozenset[str]]] = { |
129 | | - # slug → (name, description, scopes) |
130 | | - "workspace-viewer": ( |
| 158 | + |
| 159 | + |
| 160 | +class RoleDefinition(NamedTuple): |
| 161 | + name: str |
| 162 | + description: str |
| 163 | + scopes: frozenset[str] |
| 164 | + |
| 165 | + |
| 166 | +PRESET_ROLE_DEFINITIONS: dict[str, RoleDefinition] = { |
| 167 | + # slug → RoleDefinition(name, description, scopes) |
| 168 | + "workspace-viewer": RoleDefinition( |
131 | 169 | "Viewer", |
132 | 170 | "Read-only access to workspace resources", |
133 | 171 | PRESET_ROLE_SCOPES["workspace-viewer"], |
134 | 172 | ), |
135 | | - "workspace-editor": ( |
| 173 | + "workspace-editor": RoleDefinition( |
136 | 174 | "Editor", |
137 | 175 | "Create and edit resources, no delete or admin access", |
138 | 176 | PRESET_ROLE_SCOPES["workspace-editor"], |
139 | 177 | ), |
140 | | - "workspace-admin": ( |
| 178 | + "workspace-admin": RoleDefinition( |
141 | 179 | "Admin", |
142 | 180 | "Full workspace capabilities", |
143 | 181 | PRESET_ROLE_SCOPES["workspace-admin"], |
144 | 182 | ), |
145 | | - "organization-owner": ( |
| 183 | + "organization-owner": RoleDefinition( |
146 | 184 | "Owner", |
147 | 185 | "Full organization control", |
148 | 186 | PRESET_ROLE_SCOPES["organization-owner"], |
149 | 187 | ), |
150 | | - "organization-admin": ( |
| 188 | + "organization-admin": RoleDefinition( |
151 | 189 | "Admin", |
152 | 190 | "Organization admin without delete or billing manage", |
153 | 191 | PRESET_ROLE_SCOPES["organization-admin"], |
154 | 192 | ), |
155 | | - "organization-member": ( |
| 193 | + "organization-member": RoleDefinition( |
156 | 194 | "Member", |
157 | 195 | "Basic organization membership", |
158 | 196 | PRESET_ROLE_SCOPES["organization-member"], |
|
0 commit comments