Oihana PHP Arango

CasbinPolicySyncServiceTrait

Casbin policy synchronization handlers for the `services` collection.

Canonical M2M Casbin sync trait — drives the Service Account (Zitadel Machine User) flow. A wider refacto may split the user / role / policy paths of CasbinPolicySync into their own traits as well (cf. memory/project_casbin_policy_sync_traits_refactor.md).

Subject namespacing : every Service Account row in rbac is keyed on service:{$service->_key}. The middleware CheckJwtAuthentication::process() writes the same service: prefix into ATTR_USER_ID for incoming JWTs so the in-memory keys match end-to-end.

The trait expects the consumer class to expose the following protected properties (already declared on CasbinPolicySync via constructor promotion) :

  • ?Enforcer $enforcer
  • string $domain
  • ?Documents $servicesModel
  • ?Documents $policiesModel
  • ?Documents $permissionsModel
  • ?Edges $serviceHasPolicies
  • ?Edges $serviceHasPermissions
  • ?LoggerInterface $logger

Plus the standalone helpers casbinSafeSubject() and parseKey().

Tags
author

Marc Alcaraz

Table of Contents

Methods

registerServiceDelete()  : void
Registers cleanup of Casbin policies / groupings when a service vertex is deleted.
addServicePermissionPolicy()  : void
Adds a direct permission policy for a service.
addServicePolicyPolicies()  : void
Adds Casbin policies for every permission of a policy attached to a service.
onServiceDelete()  : void
Called when a service vertex is deleted — wipes every Casbin trace.
removeServicePermissionPolicy()  : void
Removes a direct permission policy from a service.
removeServicePolicyPolicies()  : void
Removes Casbin policies for every permission of a policy detached from a service.
resolveServicesForPolicy()  : array<string|int, string>
Returns the list of service `_key`s currently linked to the given policy via the `service_has_policies` edge collection.
resolveServiceSubject()  : string
Resolves the namespaced Casbin subject for a service.

Methods

registerServiceDelete()

Registers cleanup of Casbin policies / groupings when a service vertex is deleted.

public registerServiceDelete(Documents $servicesModel) : void

The cascade edge purge wired on the Services model (service_has_policies, service_has_permissions) removes the edges with a raw AQL REMOVE, which bypasses per-edge afterDelete signals — so the normal edge-level Casbin sync is never triggered for those cascaded deletes and policies would leak. This handler subscribes to the service model's afterDelete signal and calls Enforcer::deleteUser($subject) keyed on the service's namespaced subject (service:{_key}).

Parameters
$servicesModel : Documents

The services vertex model.

addServicePermissionPolicy()

Adds a direct permission policy for a service.

protected addServicePermissionPolicy(string $serviceKey, string $permissionKey) : void
Parameters
$serviceKey : string

The service ArangoDB _key.

$permissionKey : string

The permission ArangoDB _key.

Tags
throws
BindException
ContainerExceptionInterface
ArangoException
NotFoundExceptionInterface
ReflectionException

addServicePolicyPolicies()

Adds Casbin policies for every permission of a policy attached to a service.

protected addServicePolicyPolicies(string $serviceKey, string $policyKey) : void

Subject : namespaced service:{_key} — see the trait header for why the prefix is load-bearing.

Parameters
$serviceKey : string

The service ArangoDB _key.

$policyKey : string

The policy ArangoDB _key.

Tags
throws
BindException
ContainerExceptionInterface
ArangoException
NotFoundExceptionInterface
ReflectionException

onServiceDelete()

Called when a service vertex is deleted — wipes every Casbin trace.

protected onServiceDelete(Payload $payload) : void

The payload data is the OLD document (or list of documents) returned by the ArangoDB REMOVE query, so the service's _key is still accessible even though the vertex is gone.

Enforcer::deleteUser($subject) purges every p, <subject>, <domain>, <object>, <action>, <effect> policy keyed on the service's namespaced subject — covering both service_policy derived policies and service_permission direct policies in a single call.

Parameters
$payload : Payload

removeServicePermissionPolicy()

Removes a direct permission policy from a service.

protected removeServicePermissionPolicy(string $serviceKey, string $permissionKey) : void
Parameters
$serviceKey : string

The service ArangoDB _key.

$permissionKey : string

The permission ArangoDB _key.

Tags
throws
ContainerExceptionInterface
NotFoundExceptionInterface
ReflectionException
ArangoException
BindException

removeServicePolicyPolicies()

Removes Casbin policies for every permission of a policy detached from a service.

protected removeServicePolicyPolicies(string $serviceKey, string $policyKey) : void
Parameters
$serviceKey : string

The service ArangoDB _key.

$policyKey : string

The policy ArangoDB _key.

Tags
throws
BindException
ContainerExceptionInterface
ArangoException
NotFoundExceptionInterface
ReflectionException

resolveServicesForPolicy()

Returns the list of service `_key`s currently linked to the given policy via the `service_has_policies` edge collection.

protected resolveServicesForPolicy(string $policyKey) : array<string|int, string>

Used by the policy-permission propagation handlers when a perm is added to / removed from a policy : every service holding that policy needs its Casbin tuples kept in sync.

Parameters
$policyKey : string

The policy ArangoDB _key.

Return values
array<string|int, string>

Deduplicated service _keys.

resolveServiceSubject()

Resolves the namespaced Casbin subject for a service.

protected resolveServiceSubject(string $serviceKey) : string

The service: prefix partitions Service Account RBAC tuples from raw user identifiers — a security load-bearing invariant since a leaked human token must never match a Service Account's RBAC bundle. The middleware writes the same prefix into ATTR_USER_ID for incoming JWTs (see CheckJwtAuthentication::process()).

Parameters
$serviceKey : string

The service ArangoDB _key.

Return values
string

Casbin-safe subject : service:{_key} (passed through safeSubject for the digit-only quirk).

On this page

Search results