| id |
name |
namespace |
version |
status |
package |
actions |
owner |
fixtures |
caring |
activation |
metadata |
| user-engine.portal.authorize |
user-engine portal authorization |
user-engine:portal |
v1 |
ready |
flexauth.user_engine.portal |
|
team:platform-security |
|
| profile |
enforce |
canonical_roles |
organization_relations |
scopes |
planes |
capabilities |
exposure_modes |
conditions |
restrictions |
| caring-0.4.0-rc2 |
false |
| Operator |
| Administrator |
| User |
|
|
| level |
id |
tenant |
| Platform |
platform:user-engine |
platform:root |
|
| level |
id |
| Tenant |
tenant:dynamic |
|
|
|
| Read |
| Create |
| Update |
| Delete |
| Grant |
| Audit |
|
|
|
| PrivilegeEscalationBlocked |
| TenantBoundary |
|
|
|
| source |
flex_auth_contract |
| examples/user-engine/policy_package.md |
protected-system-v0 |
|
user-engine portal authorization
The portal supplies verified identity claims. This policy enforces platform,
tenant, and self boundaries and denies unknown role/context combinations.
import future.keywords.if
import future.keywords.in
roles := object.get(object.get(input.subject, "attributes", {}), "roles", [])
subject_tenant := object.get(input.subject, "tenant", "")
resource_tenant := object.get(input.resource, "tenant", input.tenant)
self_request := object.get(input.context, "self", false)
decision := {"effect": "allow", "reason": "platform_operator"} if {
valid_system
"platform-operator" in roles
} else := {"effect": "allow", "reason": "tenant_admin"} if {
valid_system
same_tenant
"tenant-admin" in roles
} else := {"effect": "allow", "reason": "self_service"} if {
valid_system
same_tenant
self_request == true
} else := {"effect": "deny", "reason": first_denial} if { true }
valid_system if { input.resource.system == "user-engine" }
same_tenant if { subject_tenant != ""; subject_tenant == input.tenant; resource_tenant == input.tenant }
default first_denial := "no_matching_role_or_context"
first_denial := "wrong_system" if { not valid_system }
else := "cross_tenant" if { subject_tenant != ""; subject_tenant != input.tenant }
Tests
package flexauth.user_engine.portal_test
import future.keywords.if
import data.flexauth.user_engine.portal
base := {"tenant": "tenant:friendly:binky", "subject": {"id": "u1", "type": "human", "tenant": "tenant:friendly:binky", "attributes": {"roles": []}}, "action": "me.read", "resource": {"id": "u1", "type": "user-engine:me", "system": "user-engine", "tenant": "tenant:friendly:binky"}, "context": {"self": true}}
test_self_allowed if { portal.decision.effect == "allow" with input as base }
test_tenant_admin_allowed if { portal.decision.effect == "allow" with input as object.union(base, {"subject": object.union(base.subject, {"attributes": {"roles": ["tenant-admin"]}}), "context": {}}) }
test_platform_operator_cross_tenant_allowed if { portal.decision.effect == "allow" with input as object.union(base, {"subject": object.union(base.subject, {"tenant": "platform:root", "attributes": {"roles": ["platform-operator"]}}), "context": {}}) }
test_cross_tenant_denied if { portal.decision.reason == "cross_tenant" with input as object.union(base, {"subject": object.union(base.subject, {"tenant": "tenant:family:other"})}) }
test_missing_role_denied if { portal.decision.effect == "deny" with input as {"tenant": "tenant:friendly:binky", "subject": {"id": "u1", "type": "human", "tenant": "tenant:friendly:binky", "attributes": {"roles": []}}, "action": "membership.write", "resource": {"id": "m1", "type": "user-engine:membership", "system": "user-engine", "tenant": "tenant:friendly:binky"}, "context": {}} }
test_wrong_system_denied if { portal.decision.reason == "wrong_system" with input as object.union(base, {"resource": object.union(base.resource, {"system": "other"})}) }