Spaces:
Sleeping
Sleeping
| -- File: lean/AuthSpec.lean | |
| -- RBAC Authorization Algebra | |
| -- Agents migrate Python source to TypeScript. | |
| -- This spec is the ground truth — their code is tested against it. | |
| namespace AuthSpec | |
| -- Core types | |
| structure Permission where | |
| resource : String | |
| action : String | |
| deriving BEq, Repr, DecidableEq | |
| structure Role where | |
| name : String | |
| permissions : List Permission | |
| inherits : List String -- role names this role inherits from | |
| deriving Repr, DecidableEq | |
| -- Flattened role map for lookup | |
| abbrev RoleMap := List Role | |
| -- Look up a role by name | |
| def findRole (roles : RoleMap) (name : String) : Option Role := | |
| roles.find? (fun r => r.name == name) | |
| -- Check direct permission (no inheritance) | |
| def hasDirectPermission (role : Role) (resource action : String) : Bool := | |
| role.permissions.any (fun p => p.resource == resource && p.action == action) | |
| -- Internal: depth-limited access check (structural recursion on Nat avoids optParam issues) | |
| def canAccessAux (roles : RoleMap) (roleName resource action : String) : Nat → Bool | |
| | 0 => false | |
| | n + 1 => | |
| match findRole roles roleName with | |
| | none => false | |
| | some role => | |
| hasDirectPermission role resource action || | |
| role.inherits.any (fun parentName => | |
| canAccessAux roles parentName resource action n) | |
| -- Public API: check permission with inheritance (depth-5 bound is more than enough) | |
| def canAccess (roles : RoleMap) (roleName resource action : String) : Bool := | |
| canAccessAux roles roleName resource action 5 | |
| -- Key invariants agents' code must satisfy | |
| -- If the role is not in the map, access is always denied | |
| theorem deny_if_no_role (roles : RoleMap) (roleName resource action : String) | |
| (h : findRole roles roleName = none) : | |
| canAccess roles roleName resource action = false := by | |
| simp [canAccess, canAccessAux, h] | |
| -- Direct permission grants access | |
| theorem direct_permission_grants_access | |
| (roles : RoleMap) (r : Role) (resource action : String) | |
| (hfound : findRole roles r.name = some r) | |
| (hperm : hasDirectPermission r resource action = true) : | |
| canAccess roles r.name resource action = true := by | |
| simp [canAccess, canAccessAux, hfound, hperm] | |
| end AuthSpec | |