--- 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) resource_type := object.get(input.resource, "type", "") subject_issuer := object.get(object.get(input.subject, "attributes", {}), "issuer", "") registration_applicant if { "registration-applicant" in roles subject_issuer == "urn:netkingdom:public-registration" same_tenant startswith(input.action, "registration.") resource_type in {"user-engine:registration", "user-engine:registration-factor"} } 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": "allow", "reason": "registration_applicant"} if { valid_system registration_applicant } 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"})}) } test_registration_applicant_allowed if { portal.decision.reason == "registration_applicant" with input as {"tenant": "tenant:friendly:binky", "subject": {"id": "applicant", "type": "human", "tenant": "tenant:friendly:binky", "attributes": {"roles": ["registration-applicant"], "issuer": "urn:netkingdom:public-registration"}}, "action": "registration.start", "resource": {"id": "new", "type": "user-engine:registration", "system": "user-engine", "tenant": "tenant:friendly:binky"}, "context": {}} } test_registration_applicant_other_action_denied if { portal.decision.effect == "deny" with input as {"tenant": "tenant:friendly:binky", "subject": {"id": "applicant", "type": "human", "tenant": "tenant:friendly:binky", "attributes": {"roles": ["registration-applicant"], "issuer": "urn:netkingdom:public-registration"}}, "action": "membership.write", "resource": {"id": "m1", "type": "user-engine:membership", "system": "user-engine", "tenant": "tenant:friendly:binky"}, "context": {}} } test_registration_applicant_wrong_issuer_denied if { portal.decision.effect == "deny" with input as {"tenant": "tenant:friendly:binky", "subject": {"id": "applicant", "type": "human", "tenant": "tenant:friendly:binky", "attributes": {"roles": ["registration-applicant"], "issuer": "untrusted"}}, "action": "registration.start", "resource": {"id": "new", "type": "user-engine:registration", "system": "user-engine", "tenant": "tenant:friendly:binky"}, "context": {}} } ```