guardrail-core 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/autopilot.test.d.ts +7 -0
- package/dist/__tests__/autopilot.test.d.ts.map +1 -0
- package/dist/__tests__/autopilot.test.js +156 -0
- package/dist/__tests__/tier-config.test.d.ts +9 -0
- package/dist/__tests__/tier-config.test.d.ts.map +1 -0
- package/dist/__tests__/tier-config.test.js +230 -0
- package/dist/__tests__/utils/hash-inline.test.d.ts +2 -0
- package/dist/__tests__/utils/hash-inline.test.d.ts.map +1 -0
- package/dist/__tests__/utils/hash-inline.test.js +62 -0
- package/dist/__tests__/utils/hash.test.d.ts +3 -0
- package/dist/__tests__/utils/hash.test.d.ts.map +1 -0
- package/dist/__tests__/utils/hash.test.js +95 -0
- package/dist/__tests__/utils/simple.test.d.ts +1 -0
- package/dist/__tests__/utils/simple.test.d.ts.map +1 -0
- package/dist/__tests__/utils/simple.test.js +10 -0
- package/dist/__tests__/utils/utils-simple.test.d.ts +1 -0
- package/dist/__tests__/utils/utils-simple.test.d.ts.map +1 -0
- package/dist/__tests__/utils/utils-simple.test.js +6 -0
- package/dist/__tests__/utils/utils.test.d.ts +15 -0
- package/dist/__tests__/utils/utils.test.d.ts.map +1 -0
- package/dist/__tests__/utils/utils.test.js +172 -0
- package/dist/autopilot/autopilot-runner.d.ts +33 -0
- package/dist/autopilot/autopilot-runner.d.ts.map +1 -0
- package/dist/autopilot/autopilot-runner.js +479 -0
- package/dist/autopilot/index.d.ts +6 -0
- package/dist/autopilot/index.d.ts.map +1 -0
- package/dist/autopilot/index.js +25 -0
- package/dist/autopilot/types.d.ts +102 -0
- package/dist/autopilot/types.d.ts.map +1 -0
- package/dist/autopilot/types.js +18 -0
- package/dist/cache/index.d.ts +7 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +22 -0
- package/dist/cache/redis-cache.d.ts +145 -0
- package/dist/cache/redis-cache.d.ts.map +1 -0
- package/dist/cache/redis-cache.js +459 -0
- package/dist/ci/github-actions.d.ts +77 -0
- package/dist/ci/github-actions.d.ts.map +1 -0
- package/dist/ci/github-actions.js +277 -0
- package/dist/ci/index.d.ts +12 -0
- package/dist/ci/index.d.ts.map +1 -0
- package/dist/ci/index.js +27 -0
- package/dist/ci/pre-commit.d.ts +65 -0
- package/dist/ci/pre-commit.d.ts.map +1 -0
- package/dist/ci/pre-commit.js +286 -0
- package/dist/entitlements.d.ts +149 -0
- package/dist/entitlements.d.ts.map +1 -0
- package/dist/entitlements.js +464 -0
- package/dist/env.d.ts +113 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +204 -0
- package/dist/fix-packs/__tests__/generate-fix-packs.test.d.ts +7 -0
- package/dist/fix-packs/__tests__/generate-fix-packs.test.d.ts.map +1 -0
- package/dist/fix-packs/__tests__/generate-fix-packs.test.js +250 -0
- package/dist/fix-packs/generate-fix-packs.d.ts +15 -0
- package/dist/fix-packs/generate-fix-packs.d.ts.map +1 -0
- package/dist/fix-packs/generate-fix-packs.js +505 -0
- package/dist/fix-packs/index.d.ts +8 -0
- package/dist/fix-packs/index.d.ts.map +1 -0
- package/dist/fix-packs/index.js +23 -0
- package/dist/fix-packs/types.d.ts +113 -0
- package/dist/fix-packs/types.d.ts.map +1 -0
- package/dist/fix-packs/types.js +71 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/metrics/prometheus.d.ts +99 -0
- package/dist/metrics/prometheus.d.ts.map +1 -0
- package/dist/metrics/prometheus.js +306 -0
- package/dist/quota-ledger.d.ts +119 -0
- package/dist/quota-ledger.d.ts.map +1 -0
- package/dist/quota-ledger.js +462 -0
- package/dist/rbac/__tests__/permissions.test.d.ts +8 -0
- package/dist/rbac/__tests__/permissions.test.d.ts.map +1 -0
- package/dist/rbac/__tests__/permissions.test.js +350 -0
- package/dist/rbac/index.d.ts +9 -0
- package/dist/rbac/index.d.ts.map +1 -0
- package/dist/rbac/index.js +32 -0
- package/dist/rbac/permissions.d.ts +71 -0
- package/dist/rbac/permissions.d.ts.map +1 -0
- package/dist/rbac/permissions.js +247 -0
- package/dist/rbac/types.d.ts +69 -0
- package/dist/rbac/types.d.ts.map +1 -0
- package/dist/rbac/types.js +213 -0
- package/dist/tier-config.d.ts +203 -0
- package/dist/tier-config.d.ts.map +1 -0
- package/dist/tier-config.js +675 -0
- package/dist/types.d.ts +365 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/utils.d.ts +36 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +127 -0
- package/dist/verified-autofix/__tests__/format-validator.test.d.ts +11 -0
- package/dist/verified-autofix/__tests__/format-validator.test.d.ts.map +1 -0
- package/dist/verified-autofix/__tests__/format-validator.test.js +285 -0
- package/dist/verified-autofix/__tests__/pipeline.test.d.ts +11 -0
- package/dist/verified-autofix/__tests__/pipeline.test.d.ts.map +1 -0
- package/dist/verified-autofix/__tests__/pipeline.test.js +389 -0
- package/dist/verified-autofix/__tests__/repo-fingerprint.test.d.ts +11 -0
- package/dist/verified-autofix/__tests__/repo-fingerprint.test.d.ts.map +1 -0
- package/dist/verified-autofix/__tests__/repo-fingerprint.test.js +236 -0
- package/dist/verified-autofix/__tests__/workspace.test.d.ts +11 -0
- package/dist/verified-autofix/__tests__/workspace.test.d.ts.map +1 -0
- package/dist/verified-autofix/__tests__/workspace.test.js +314 -0
- package/dist/verified-autofix/format-validator.d.ts +101 -0
- package/dist/verified-autofix/format-validator.d.ts.map +1 -0
- package/dist/verified-autofix/format-validator.js +446 -0
- package/dist/verified-autofix/index.d.ts +14 -0
- package/dist/verified-autofix/index.d.ts.map +1 -0
- package/dist/verified-autofix/index.js +39 -0
- package/dist/verified-autofix/pipeline.d.ts +68 -0
- package/dist/verified-autofix/pipeline.d.ts.map +1 -0
- package/dist/verified-autofix/pipeline.js +330 -0
- package/dist/verified-autofix/repo-fingerprint.d.ts +56 -0
- package/dist/verified-autofix/repo-fingerprint.d.ts.map +1 -0
- package/dist/verified-autofix/repo-fingerprint.js +396 -0
- package/dist/verified-autofix/workspace.d.ts +83 -0
- package/dist/verified-autofix/workspace.d.ts.map +1 -0
- package/dist/verified-autofix/workspace.js +454 -0
- package/dist/verified-autofix.d.ts +182 -0
- package/dist/verified-autofix.d.ts.map +1 -0
- package/dist/verified-autofix.js +1021 -0
- package/dist/visualization/dependency-graph.d.ts +79 -0
- package/dist/visualization/dependency-graph.d.ts.map +1 -0
- package/dist/visualization/dependency-graph.js +399 -0
- package/dist/visualization/index.d.ts +5 -0
- package/dist/visualization/index.d.ts.map +1 -0
- package/dist/visualization/index.js +20 -0
- package/package.json +29 -0
- package/src/__tests__/autopilot.test.ts +196 -0
- package/src/__tests__/tier-config.test.ts +289 -0
- package/src/__tests__/utils/hash-inline.test.ts +76 -0
- package/src/__tests__/utils/hash.test.ts +119 -0
- package/src/__tests__/utils/simple.test.ts +10 -0
- package/src/__tests__/utils/utils-simple.test.ts +5 -0
- package/src/__tests__/utils/utils.test.ts +203 -0
- package/src/autopilot/autopilot-runner.ts +503 -0
- package/src/autopilot/index.ts +6 -0
- package/src/autopilot/types.ts +119 -0
- package/src/cache/index.ts +7 -0
- package/src/cache/redis-cache.d.ts +155 -0
- package/src/cache/redis-cache.d.ts.map +1 -0
- package/src/cache/redis-cache.ts +517 -0
- package/src/ci/github-actions.ts +335 -0
- package/src/ci/index.ts +12 -0
- package/src/ci/pre-commit.ts +338 -0
- package/src/db/usage-schema.prisma +114 -0
- package/src/entitlements.ts +570 -0
- package/src/env.d.ts +68 -0
- package/src/env.d.ts.map +1 -0
- package/src/env.ts +247 -0
- package/src/fix-packs/__tests__/generate-fix-packs.test.ts +317 -0
- package/src/fix-packs/generate-fix-packs.ts +577 -0
- package/src/fix-packs/index.ts +8 -0
- package/src/fix-packs/types.ts +206 -0
- package/src/index.d.ts +7 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.ts +12 -0
- package/src/metrics/prometheus.d.ts +104 -0
- package/src/metrics/prometheus.d.ts.map +1 -0
- package/src/metrics/prometheus.ts +446 -0
- package/src/quota-ledger.ts +548 -0
- package/src/rbac/__tests__/permissions.test.ts +446 -0
- package/src/rbac/index.ts +46 -0
- package/src/rbac/permissions.ts +301 -0
- package/src/rbac/types.ts +298 -0
- package/src/tier-config.json +157 -0
- package/src/tier-config.ts +815 -0
- package/src/types.d.ts +365 -0
- package/src/types.d.ts.map +1 -0
- package/src/types.ts +441 -0
- package/src/utils.d.ts +36 -0
- package/src/utils.d.ts.map +1 -0
- package/src/utils.ts +140 -0
- package/src/verified-autofix/__tests__/format-validator.test.ts +335 -0
- package/src/verified-autofix/__tests__/pipeline.test.ts +419 -0
- package/src/verified-autofix/__tests__/repo-fingerprint.test.ts +241 -0
- package/src/verified-autofix/__tests__/workspace.test.ts +373 -0
- package/src/verified-autofix/format-validator.ts +517 -0
- package/src/verified-autofix/index.ts +63 -0
- package/src/verified-autofix/pipeline.ts +403 -0
- package/src/verified-autofix/repo-fingerprint.ts +459 -0
- package/src/verified-autofix/workspace.ts +531 -0
- package/src/verified-autofix.ts +1187 -0
- package/src/visualization/dependency-graph.d.ts +85 -0
- package/src/visualization/dependency-graph.d.ts.map +1 -0
- package/src/visualization/dependency-graph.ts +495 -0
- package/src/visualization/index.ts +5 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RBAC Permission Checker
|
|
3
|
+
*
|
|
4
|
+
* Core permission checking logic for role-based access control.
|
|
5
|
+
* Provides functions to verify user permissions against required permissions.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Tier, TIER_ORDER } from '../tier-config';
|
|
9
|
+
import {
|
|
10
|
+
Permission,
|
|
11
|
+
PERMISSIONS,
|
|
12
|
+
PermissionCheck,
|
|
13
|
+
PermissionMatrix,
|
|
14
|
+
RBACContext,
|
|
15
|
+
Role,
|
|
16
|
+
ROLE_HIERARCHY,
|
|
17
|
+
ROLE_PERMISSIONS,
|
|
18
|
+
ROLES,
|
|
19
|
+
} from './types';
|
|
20
|
+
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// PERMISSION CHECKING
|
|
23
|
+
// ============================================================================
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Check if a role has a specific permission
|
|
27
|
+
*/
|
|
28
|
+
export function roleHasPermission(role: Role, permission: Permission): boolean {
|
|
29
|
+
const permissions = ROLE_PERMISSIONS[role];
|
|
30
|
+
return permissions.includes(permission);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Check if a user has a specific permission based on their role
|
|
35
|
+
*/
|
|
36
|
+
export function hasPermission(
|
|
37
|
+
context: RBACContext,
|
|
38
|
+
permission: Permission
|
|
39
|
+
): PermissionCheck {
|
|
40
|
+
if (!context.role || !ROLES.includes(context.role)) {
|
|
41
|
+
return {
|
|
42
|
+
allowed: false,
|
|
43
|
+
reason: 'Invalid or missing role',
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const hasAccess = roleHasPermission(context.role, permission);
|
|
48
|
+
|
|
49
|
+
if (!hasAccess) {
|
|
50
|
+
const requiredRole = getMinimumRoleForPermission(permission);
|
|
51
|
+
return {
|
|
52
|
+
allowed: false,
|
|
53
|
+
reason: `Permission '${permission}' requires at least '${requiredRole}' role`,
|
|
54
|
+
requiredRole,
|
|
55
|
+
requiredPermissions: [permission],
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return { allowed: true };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Check if a user has ALL of the specified permissions
|
|
64
|
+
*/
|
|
65
|
+
export function hasAllPermissions(
|
|
66
|
+
context: RBACContext,
|
|
67
|
+
permissions: Permission[]
|
|
68
|
+
): PermissionCheck {
|
|
69
|
+
const missingPermissions: Permission[] = [];
|
|
70
|
+
|
|
71
|
+
for (const permission of permissions) {
|
|
72
|
+
if (!roleHasPermission(context.role, permission)) {
|
|
73
|
+
missingPermissions.push(permission);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (missingPermissions.length > 0) {
|
|
78
|
+
return {
|
|
79
|
+
allowed: false,
|
|
80
|
+
reason: `Missing required permissions: ${missingPermissions.join(', ')}`,
|
|
81
|
+
requiredPermissions: missingPermissions,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return { allowed: true };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Check if a user has ANY of the specified permissions
|
|
90
|
+
*/
|
|
91
|
+
export function hasAnyPermission(
|
|
92
|
+
context: RBACContext,
|
|
93
|
+
permissions: Permission[]
|
|
94
|
+
): PermissionCheck {
|
|
95
|
+
for (const permission of permissions) {
|
|
96
|
+
if (roleHasPermission(context.role, permission)) {
|
|
97
|
+
return { allowed: true };
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
allowed: false,
|
|
103
|
+
reason: `Requires at least one of: ${permissions.join(', ')}`,
|
|
104
|
+
requiredPermissions: permissions,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ============================================================================
|
|
109
|
+
// ROLE COMPARISON
|
|
110
|
+
// ============================================================================
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Compare two roles and return their relative hierarchy
|
|
114
|
+
* Returns positive if role1 > role2, negative if role1 < role2, 0 if equal
|
|
115
|
+
*/
|
|
116
|
+
export function compareRoles(role1: Role, role2: Role): number {
|
|
117
|
+
return ROLE_HIERARCHY[role1] - ROLE_HIERARCHY[role2];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Check if role1 is higher than or equal to role2 in the hierarchy
|
|
122
|
+
*/
|
|
123
|
+
export function isRoleAtLeast(role: Role, minimumRole: Role): boolean {
|
|
124
|
+
return ROLE_HIERARCHY[role] >= ROLE_HIERARCHY[minimumRole];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Get the minimum role required for a specific permission
|
|
129
|
+
*/
|
|
130
|
+
export function getMinimumRoleForPermission(permission: Permission): Role {
|
|
131
|
+
// Check roles from lowest to highest
|
|
132
|
+
const orderedRoles: Role[] = ['viewer', 'compliance-auditor', 'dev', 'admin', 'owner'];
|
|
133
|
+
|
|
134
|
+
for (const role of orderedRoles) {
|
|
135
|
+
if (roleHasPermission(role, permission)) {
|
|
136
|
+
return role;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Default to owner if permission not found
|
|
141
|
+
return 'owner';
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Get all permissions for a role (including inherited)
|
|
146
|
+
*/
|
|
147
|
+
export function getEffectivePermissions(role: Role): Permission[] {
|
|
148
|
+
return [...ROLE_PERMISSIONS[role]];
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// ============================================================================
|
|
152
|
+
// TIER-BASED RESTRICTIONS
|
|
153
|
+
// ============================================================================
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Check if a tier allows a specific operation with RBAC
|
|
157
|
+
*/
|
|
158
|
+
export function checkTierAndPermission(
|
|
159
|
+
context: RBACContext,
|
|
160
|
+
permission: Permission,
|
|
161
|
+
requiredTier: Tier
|
|
162
|
+
): PermissionCheck {
|
|
163
|
+
// First check permission
|
|
164
|
+
const permissionCheck = hasPermission(context, permission);
|
|
165
|
+
if (!permissionCheck.allowed) {
|
|
166
|
+
return permissionCheck;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Then check tier if provided
|
|
170
|
+
if (context.tier) {
|
|
171
|
+
const userTierIndex = TIER_ORDER.indexOf(context.tier as Tier);
|
|
172
|
+
const requiredTierIndex = TIER_ORDER.indexOf(requiredTier);
|
|
173
|
+
|
|
174
|
+
if (userTierIndex < requiredTierIndex) {
|
|
175
|
+
return {
|
|
176
|
+
allowed: false,
|
|
177
|
+
reason: `This feature requires ${requiredTier} tier or higher`,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return { allowed: true };
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// ============================================================================
|
|
186
|
+
// PERMISSION MATRIX
|
|
187
|
+
// ============================================================================
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Generate a permission matrix for UI display
|
|
191
|
+
*/
|
|
192
|
+
export function generatePermissionMatrix(): PermissionMatrix {
|
|
193
|
+
const matrix: Record<Role, Record<Permission, boolean>> = {} as Record<Role, Record<Permission, boolean>>;
|
|
194
|
+
|
|
195
|
+
for (const role of ROLES) {
|
|
196
|
+
matrix[role] = {} as Record<Permission, boolean>;
|
|
197
|
+
for (const permission of PERMISSIONS) {
|
|
198
|
+
matrix[role][permission] = roleHasPermission(role, permission);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return {
|
|
203
|
+
roles: [...ROLES],
|
|
204
|
+
permissions: [...PERMISSIONS],
|
|
205
|
+
matrix,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// ============================================================================
|
|
210
|
+
// ROLE ASSIGNMENT VALIDATION
|
|
211
|
+
// ============================================================================
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Check if a user can assign a specific role to another user
|
|
215
|
+
* Users can only assign roles lower than their own
|
|
216
|
+
*/
|
|
217
|
+
export function canAssignRole(
|
|
218
|
+
assignerRole: Role,
|
|
219
|
+
targetRole: Role
|
|
220
|
+
): PermissionCheck {
|
|
221
|
+
// Must have assign_roles permission
|
|
222
|
+
if (!roleHasPermission(assignerRole, 'assign_roles')) {
|
|
223
|
+
return {
|
|
224
|
+
allowed: false,
|
|
225
|
+
reason: 'You do not have permission to assign roles',
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Cannot assign a role equal to or higher than your own (except owner can assign admin)
|
|
230
|
+
if (assignerRole === 'owner') {
|
|
231
|
+
return { allowed: true };
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (ROLE_HIERARCHY[targetRole] >= ROLE_HIERARCHY[assignerRole]) {
|
|
235
|
+
return {
|
|
236
|
+
allowed: false,
|
|
237
|
+
reason: `Cannot assign role '${targetRole}' - must be lower than your role '${assignerRole}'`,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return { allowed: true };
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Check if a user can remove another user from the team
|
|
246
|
+
*/
|
|
247
|
+
export function canRemoveMember(
|
|
248
|
+
removerRole: Role,
|
|
249
|
+
targetRole: Role
|
|
250
|
+
): PermissionCheck {
|
|
251
|
+
// Must have remove_members permission
|
|
252
|
+
if (!roleHasPermission(removerRole, 'remove_members')) {
|
|
253
|
+
return {
|
|
254
|
+
allowed: false,
|
|
255
|
+
reason: 'You do not have permission to remove members',
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Cannot remove owner
|
|
260
|
+
if (targetRole === 'owner') {
|
|
261
|
+
return {
|
|
262
|
+
allowed: false,
|
|
263
|
+
reason: 'Cannot remove the team owner',
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Cannot remove someone with equal or higher role (unless owner)
|
|
268
|
+
if (removerRole !== 'owner' && ROLE_HIERARCHY[targetRole] >= ROLE_HIERARCHY[removerRole]) {
|
|
269
|
+
return {
|
|
270
|
+
allowed: false,
|
|
271
|
+
reason: `Cannot remove a member with role '${targetRole}' - must have a lower role than yours`,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return { allowed: true };
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// ============================================================================
|
|
279
|
+
// VALIDATION UTILITIES
|
|
280
|
+
// ============================================================================
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Validate if a string is a valid role
|
|
284
|
+
*/
|
|
285
|
+
export function isValidRole(role: string): role is Role {
|
|
286
|
+
return ROLES.includes(role as Role);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Validate if a string is a valid permission
|
|
291
|
+
*/
|
|
292
|
+
export function isValidPermission(permission: string): permission is Permission {
|
|
293
|
+
return PERMISSIONS.includes(permission as Permission);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Get role from string with validation
|
|
298
|
+
*/
|
|
299
|
+
export function parseRole(role: string): Role | null {
|
|
300
|
+
return isValidRole(role) ? role : null;
|
|
301
|
+
}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RBAC Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Core types for Role-Based Access Control system.
|
|
5
|
+
* Defines roles, permissions, and related interfaces.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// ROLES
|
|
10
|
+
// ============================================================================
|
|
11
|
+
|
|
12
|
+
export const ROLES = ['owner', 'admin', 'dev', 'viewer', 'compliance-auditor'] as const;
|
|
13
|
+
export type Role = typeof ROLES[number];
|
|
14
|
+
|
|
15
|
+
/** Role hierarchy for permission inheritance (higher index = more permissions) */
|
|
16
|
+
export const ROLE_HIERARCHY: Record<Role, number> = {
|
|
17
|
+
'viewer': 0,
|
|
18
|
+
'compliance-auditor': 1,
|
|
19
|
+
'dev': 2,
|
|
20
|
+
'admin': 3,
|
|
21
|
+
'owner': 4,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// PERMISSIONS
|
|
26
|
+
// ============================================================================
|
|
27
|
+
|
|
28
|
+
export const PERMISSIONS = [
|
|
29
|
+
// Team Management
|
|
30
|
+
'manage_team',
|
|
31
|
+
'invite_members',
|
|
32
|
+
'remove_members',
|
|
33
|
+
'assign_roles',
|
|
34
|
+
|
|
35
|
+
// Audit & Compliance
|
|
36
|
+
'view_audit',
|
|
37
|
+
'export_audit',
|
|
38
|
+
'manage_compliance',
|
|
39
|
+
'view_compliance',
|
|
40
|
+
|
|
41
|
+
// Reports
|
|
42
|
+
'view_reports',
|
|
43
|
+
'export_reports',
|
|
44
|
+
'create_reports',
|
|
45
|
+
|
|
46
|
+
// Operations
|
|
47
|
+
'run_scan',
|
|
48
|
+
'run_reality',
|
|
49
|
+
'run_autopilot',
|
|
50
|
+
'run_fix',
|
|
51
|
+
'run_gate',
|
|
52
|
+
|
|
53
|
+
// Policies
|
|
54
|
+
'view_policies',
|
|
55
|
+
'manage_policies',
|
|
56
|
+
'create_policies',
|
|
57
|
+
|
|
58
|
+
// Projects
|
|
59
|
+
'view_projects',
|
|
60
|
+
'create_projects',
|
|
61
|
+
'delete_projects',
|
|
62
|
+
'manage_project_settings',
|
|
63
|
+
|
|
64
|
+
// API & Integrations
|
|
65
|
+
'manage_api_keys',
|
|
66
|
+
'view_api_keys',
|
|
67
|
+
'manage_webhooks',
|
|
68
|
+
'manage_integrations',
|
|
69
|
+
|
|
70
|
+
// Billing
|
|
71
|
+
'view_billing',
|
|
72
|
+
'manage_billing',
|
|
73
|
+
|
|
74
|
+
// Admin
|
|
75
|
+
'view_dashboard',
|
|
76
|
+
'admin_settings',
|
|
77
|
+
] as const;
|
|
78
|
+
|
|
79
|
+
export type Permission = typeof PERMISSIONS[number];
|
|
80
|
+
|
|
81
|
+
// ============================================================================
|
|
82
|
+
// ROLE-PERMISSION MAPPING
|
|
83
|
+
// ============================================================================
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Default permissions for each role.
|
|
87
|
+
* Roles inherit permissions from lower roles in the hierarchy.
|
|
88
|
+
*/
|
|
89
|
+
export const ROLE_PERMISSIONS: Record<Role, Permission[]> = {
|
|
90
|
+
'viewer': [
|
|
91
|
+
'view_dashboard',
|
|
92
|
+
'view_projects',
|
|
93
|
+
'view_reports',
|
|
94
|
+
'view_compliance',
|
|
95
|
+
'view_policies',
|
|
96
|
+
],
|
|
97
|
+
|
|
98
|
+
'compliance-auditor': [
|
|
99
|
+
// Inherits viewer permissions
|
|
100
|
+
'view_dashboard',
|
|
101
|
+
'view_projects',
|
|
102
|
+
'view_reports',
|
|
103
|
+
'view_compliance',
|
|
104
|
+
'view_policies',
|
|
105
|
+
// Additional audit permissions
|
|
106
|
+
'view_audit',
|
|
107
|
+
'export_audit',
|
|
108
|
+
'export_reports',
|
|
109
|
+
],
|
|
110
|
+
|
|
111
|
+
'dev': [
|
|
112
|
+
// Inherits viewer permissions
|
|
113
|
+
'view_dashboard',
|
|
114
|
+
'view_projects',
|
|
115
|
+
'view_reports',
|
|
116
|
+
'view_compliance',
|
|
117
|
+
'view_policies',
|
|
118
|
+
// Dev operations
|
|
119
|
+
'run_scan',
|
|
120
|
+
'run_reality',
|
|
121
|
+
'run_fix',
|
|
122
|
+
'run_gate',
|
|
123
|
+
'create_projects',
|
|
124
|
+
'view_api_keys',
|
|
125
|
+
],
|
|
126
|
+
|
|
127
|
+
'admin': [
|
|
128
|
+
// Inherits dev permissions
|
|
129
|
+
'view_dashboard',
|
|
130
|
+
'view_projects',
|
|
131
|
+
'view_reports',
|
|
132
|
+
'view_compliance',
|
|
133
|
+
'view_policies',
|
|
134
|
+
'run_scan',
|
|
135
|
+
'run_reality',
|
|
136
|
+
'run_fix',
|
|
137
|
+
'run_gate',
|
|
138
|
+
'create_projects',
|
|
139
|
+
'view_api_keys',
|
|
140
|
+
// Admin permissions
|
|
141
|
+
'manage_team',
|
|
142
|
+
'invite_members',
|
|
143
|
+
'remove_members',
|
|
144
|
+
'assign_roles',
|
|
145
|
+
'run_autopilot',
|
|
146
|
+
'manage_policies',
|
|
147
|
+
'create_policies',
|
|
148
|
+
'delete_projects',
|
|
149
|
+
'manage_project_settings',
|
|
150
|
+
'manage_api_keys',
|
|
151
|
+
'manage_webhooks',
|
|
152
|
+
'manage_integrations',
|
|
153
|
+
'view_audit',
|
|
154
|
+
'export_audit',
|
|
155
|
+
'export_reports',
|
|
156
|
+
'create_reports',
|
|
157
|
+
'manage_compliance',
|
|
158
|
+
'view_billing',
|
|
159
|
+
],
|
|
160
|
+
|
|
161
|
+
'owner': [
|
|
162
|
+
// All permissions
|
|
163
|
+
'manage_team',
|
|
164
|
+
'invite_members',
|
|
165
|
+
'remove_members',
|
|
166
|
+
'assign_roles',
|
|
167
|
+
'view_audit',
|
|
168
|
+
'export_audit',
|
|
169
|
+
'manage_compliance',
|
|
170
|
+
'view_compliance',
|
|
171
|
+
'view_reports',
|
|
172
|
+
'export_reports',
|
|
173
|
+
'create_reports',
|
|
174
|
+
'run_scan',
|
|
175
|
+
'run_reality',
|
|
176
|
+
'run_autopilot',
|
|
177
|
+
'run_fix',
|
|
178
|
+
'run_gate',
|
|
179
|
+
'view_policies',
|
|
180
|
+
'manage_policies',
|
|
181
|
+
'create_policies',
|
|
182
|
+
'view_projects',
|
|
183
|
+
'create_projects',
|
|
184
|
+
'delete_projects',
|
|
185
|
+
'manage_project_settings',
|
|
186
|
+
'manage_api_keys',
|
|
187
|
+
'view_api_keys',
|
|
188
|
+
'manage_webhooks',
|
|
189
|
+
'manage_integrations',
|
|
190
|
+
'view_billing',
|
|
191
|
+
'manage_billing',
|
|
192
|
+
'view_dashboard',
|
|
193
|
+
'admin_settings',
|
|
194
|
+
],
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
// ============================================================================
|
|
198
|
+
// INTERFACES
|
|
199
|
+
// ============================================================================
|
|
200
|
+
|
|
201
|
+
export interface RoleAssignment {
|
|
202
|
+
userId: string;
|
|
203
|
+
teamId: string;
|
|
204
|
+
role: Role;
|
|
205
|
+
assignedBy: string;
|
|
206
|
+
assignedAt: Date;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export interface PermissionCheck {
|
|
210
|
+
allowed: boolean;
|
|
211
|
+
reason?: string;
|
|
212
|
+
requiredRole?: Role;
|
|
213
|
+
requiredPermissions?: Permission[];
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export interface TeamMemberWithRole {
|
|
217
|
+
id: string;
|
|
218
|
+
userId: string;
|
|
219
|
+
email: string;
|
|
220
|
+
name: string;
|
|
221
|
+
role: Role;
|
|
222
|
+
joinedAt: Date;
|
|
223
|
+
lastActive?: Date;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export interface TeamInvitation {
|
|
227
|
+
id: string;
|
|
228
|
+
teamId: string;
|
|
229
|
+
email: string;
|
|
230
|
+
role: Role;
|
|
231
|
+
invitedBy: string;
|
|
232
|
+
expiresAt: Date;
|
|
233
|
+
status: 'pending' | 'accepted' | 'expired' | 'revoked';
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export interface RBACContext {
|
|
237
|
+
userId: string;
|
|
238
|
+
teamId: string;
|
|
239
|
+
role: Role;
|
|
240
|
+
permissions: Permission[];
|
|
241
|
+
tier?: string;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export interface PermissionMatrix {
|
|
245
|
+
roles: Role[];
|
|
246
|
+
permissions: Permission[];
|
|
247
|
+
matrix: Record<Role, Record<Permission, boolean>>;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// ============================================================================
|
|
251
|
+
// ROLE METADATA
|
|
252
|
+
// ============================================================================
|
|
253
|
+
|
|
254
|
+
export interface RoleMetadata {
|
|
255
|
+
name: Role;
|
|
256
|
+
displayName: string;
|
|
257
|
+
description: string;
|
|
258
|
+
color: string;
|
|
259
|
+
icon: string;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export const ROLE_METADATA: Record<Role, RoleMetadata> = {
|
|
263
|
+
'owner': {
|
|
264
|
+
name: 'owner',
|
|
265
|
+
displayName: 'Owner',
|
|
266
|
+
description: 'Full access to all features including billing and team deletion',
|
|
267
|
+
color: '#8B5CF6', // purple
|
|
268
|
+
icon: 'crown',
|
|
269
|
+
},
|
|
270
|
+
'admin': {
|
|
271
|
+
name: 'admin',
|
|
272
|
+
displayName: 'Admin',
|
|
273
|
+
description: 'Manage team members, settings, and run all operations',
|
|
274
|
+
color: '#3B82F6', // blue
|
|
275
|
+
icon: 'shield',
|
|
276
|
+
},
|
|
277
|
+
'dev': {
|
|
278
|
+
name: 'dev',
|
|
279
|
+
displayName: 'Developer',
|
|
280
|
+
description: 'Run scans, fixes, and manage projects',
|
|
281
|
+
color: '#10B981', // green
|
|
282
|
+
icon: 'code',
|
|
283
|
+
},
|
|
284
|
+
'viewer': {
|
|
285
|
+
name: 'viewer',
|
|
286
|
+
displayName: 'Viewer',
|
|
287
|
+
description: 'View-only access to dashboards and reports',
|
|
288
|
+
color: '#6B7280', // gray
|
|
289
|
+
icon: 'eye',
|
|
290
|
+
},
|
|
291
|
+
'compliance-auditor': {
|
|
292
|
+
name: 'compliance-auditor',
|
|
293
|
+
displayName: 'Compliance Auditor',
|
|
294
|
+
description: 'View and export audit logs and compliance reports',
|
|
295
|
+
color: '#F59E0B', // amber
|
|
296
|
+
icon: 'clipboard-check',
|
|
297
|
+
},
|
|
298
|
+
};
|