Deploy user-engine authorization policy
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

This commit is contained in:
tegwick 2026-08-09 02:21:29 +02:00
parent 5217109103
commit ccf4b509be
5 changed files with 141 additions and 5 deletions

View file

@ -0,0 +1,13 @@
# user-engine policy service
Dynamic human subjects arrive as verified KeyCape claims, so the registry
defines the protected system while the policy evaluates tenant, roles, and
self context from each request. Platform operators may cross tenants;
tenant administrators and self-service users may not.
Validate with:
```bash
flex-auth test-policy -file examples/user-engine/policy_package.md
flex-auth load-registry -file examples/user-engine/registry_snapshot.json
```

View file

@ -0,0 +1,8 @@
[
{"id":"self-allow","request":{"id":"c1","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}},"expect":{"effect":"allow","reason":"self_service"}},
{"id":"tenant-admin-allow","request":{"id":"c2","tenant":"tenant:friendly:binky","subject":{"id":"admin","type":"human","tenant":"tenant:friendly:binky","attributes":{"roles":["tenant-admin"]}},"action":"family_member.invite","resource":{"id":"i1","type":"user-engine:family-invitation","system":"user-engine","tenant":"tenant:friendly:binky"},"context":{}},"expect":{"effect":"allow","reason":"tenant_admin"}},
{"id":"platform-allow","request":{"id":"c3","tenant":"tenant:friendly:binky","subject":{"id":"operator","type":"human","tenant":"platform:root","attributes":{"roles":["platform-operator"]}},"action":"tenant.diagnostics.read","resource":{"id":"tenant:friendly:binky","type":"user-engine:tenant","system":"user-engine","tenant":"tenant:friendly:binky"},"context":{}},"expect":{"effect":"allow","reason":"platform_operator"}},
{"id":"cross-tenant-deny","request":{"id":"c4","tenant":"tenant:friendly:binky","subject":{"id":"admin","type":"human","tenant":"tenant:family:other","attributes":{"roles":["tenant-admin"]}},"action":"membership.write","resource":{"id":"m1","type":"user-engine:membership","system":"user-engine","tenant":"tenant:friendly:binky"},"context":{}},"expect":{"effect":"deny","reason":"cross_tenant"}},
{"id":"missing-role-deny","request":{"id":"c5","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":{}},"expect":{"effect":"deny","reason":"no_matching_role_or_context"}},
{"id":"wrong-system-deny","request":{"id":"c6","tenant":"tenant:friendly:binky","subject":{"id":"operator","type":"human","tenant":"platform:root","attributes":{"roles":["platform-operator"]}},"action":"outbox.replay","resource":{"id":"e1","type":"user-engine:outbox-event","system":"other","tenant":"tenant:friendly:binky"},"context":{}},"expect":{"effect":"deny","reason":"wrong_system"}}
]

View file

@ -0,0 +1,83 @@
---
id: user-engine.portal.authorize
name: user-engine portal authorization
namespace: user-engine:portal
version: v1
status: ready
package: flexauth.user_engine.portal
actions:
- "*"
owner: team:platform-security
fixtures:
- policy_fixtures.yaml
caring:
profile: caring-0.4.0-rc2
enforce: false
canonical_roles: [Operator, Administrator, User]
organization_relations: [ServiceProvider, Customer]
scopes:
- {level: Platform, id: platform:user-engine, tenant: "platform:root"}
- {level: Tenant, id: tenant:dynamic}
planes: [Identity, Policy, Audit]
capabilities: [Read, Create, Update, Delete, Grant, Audit]
exposure_modes: [Metadata]
conditions: [Logged]
restrictions: [PrivilegeEscalationBlocked, TenantBoundary]
activation:
mode: local
metadata:
source: examples/user-engine/policy_package.md
flex_auth_contract: 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.
```rego
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
```rego test
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"})}) }
```

View file

@ -0,0 +1,16 @@
{
"systems": [{
"id": "user-engine",
"name": "User Engine",
"resource_types": [
{"name":"user-engine:user","scope_level":"Resource","planes":["Identity","Audit"]},
{"name":"user-engine:membership","scope_level":"Resource","planes":["Identity","Policy","Audit"]},
{"name":"user-engine:family-invitation","scope_level":"Resource","planes":["Identity","Audit"]},
{"name":"user-engine:tenant","scope_level":"Tenant","planes":["Identity","Audit"]},
{"name":"user-engine:outbox","scope_level":"Platform","planes":["Audit"]}
],
"actions": [],
"metadata": {"flex_auth_contract":"protected-system-v0","dynamic_actions":true}
}],
"resource_manifests": [], "tenants": [], "subjects": [], "groups": [], "relationships": []
}