Aller au contenu principal

Politiques

Une politique décide si un acteur peut invoquer une action. Chaque action du graphe possède exactement une politique. Le runtime l'évalue avant que la moindre donnée ne soit touchée.

Le contrat Policy

interface Policy
{
public function evaluate(
Actor $actor,
string $actionFqn,
?Subject $subject,
Context $context,
): Decision;
}

Une politique retourne une valeur de l'enum Decision :

DecisionSignification
Permitl'action est autorisée
Denyl'action est refusée
Abstainla politique ne prend aucune décision

Refus par défaut, défaillance en mode fermé

Le PolicyEngine applique deux règles de sécurité lorsqu'il évalue une politique :

  • Abstain devient Deny. Si une politique retourne Abstain, le moteur la traite comme Deny. Il n'y a pas de « autoriser parce que rien ne s'y est opposé ».
  • Une exception devient Deny. Si une politique lève une exception, le moteur l'intercepte et retourne Deny. Une politique défectueuse défaille en mode fermé, jamais ouvert.

Si la décision est autre chose que Permit, le runtime lève PolicyDenied et l'invocation s'arrête avant l'ouverture de la transaction.

La politique intégrée : RoleRequired

La v0.1.0 livre une seule implémentation de politique : RoleRequired. Elle autorise l'action si l'acteur détient un rôle nommé.

Vous l'attachez via le DSL avec ->requireRole() :

'issue' => Action::transition('status', from: 'DRAFT', to: 'ISSUED')
->requireRole('invoice.issuer'),

Le compilateur crée un PolicyNode pour l'action qui construit une politique RoleRequired avec role: 'invoice.issuer'. Au moment de l'invocation, le moteur vérifie le rôle par rapport à la liste de rôles de l'acteur.

Acteurs

Un acteur est celui qui réalise l'action. Le contrat Actor expose une référence, une liste de rôles, une liste de permissions et un roleHash() canonique.

La v0.1.0 livre StubActor — un acteur fixe en mémoire :

use Ausus\{StubActor, ActorRef};

$actor = new StubActor(
new ActorRef('user', 'user42', 'acme'),
['invoice.creator', 'invoice.issuer', 'invoice.canceler', 'invoice.viewer'],
);

L'API HTTP construit un StubActor à partir des en-têtes de la requête (X-Actor-Id, X-Actor-Roles) — voir L'API HTTP.

Limites actuelles de la v0.1.0

  • RoleRequired est la seule implémentation de politique. Il n'existe ni politique basée sur les attributs, ni politique basée sur les permissions, ni combinaison de politiques (all-of / any-of) en v0.1.0.
  • Il n'y a aucune authentification. StubActor est une identité de confiance, fournie par l'appelant. Tout ce qui expose le runtime — y compris l'API HTTP — doit placer une véritable couche d'authentification devant lui. Le paquet réservé ausus/auth-bridge est l'emplacement prévu pour cela et ne livre aucun code en v0.1.0.
  • Les politiques de visibilité au niveau du champ et de la projection sont conçues mais ne sont pas appliquées en v0.1.0.