Composer avec les pannes
Que devrait-il se passer lorsque votre code appelle check() et qu'Agreely ne peut
être joint? La réponse d'Agreely est refuser, par défaut, partout. Ce guide
explique pourquoi, et comment faire une exception étroite et auditée lorsque vous en
avez réellement besoin.
Le refus par défaut est la valeur par défaut
Lorsqu'Agreely est injoignable (un 503, un délai d'expiration ou une erreur
réseau) :
check()renvoiefalse(refus);checkDetailed()lèveAgreelyUnavailableError;- la CLI sort avec
4(distinct du10d'un refus).
Un véritable refus 200 n'est jamais touché par tout cela. Une panne n'est pas un
refus, mais la valeur par défaut sûre lors d'une panne est de se comporter comme
si c'était refusé, de sorte qu'un problème d'infrastructure ne puisse jamais
accorder l'accès aux données en silence.
Distinguez la panne du refus
Utilisez checkDetailed() (ou le code de sortie de la CLI) lorsque vous devez distinguer les deux. Un refus est une réponse faisant autorité que vous devez honorer; une panne est une défaillance transitoire que vous pouvez réessayer, signaler par une alerte, ou, pour une catégorie choisie, dégrader. check() ramène les deux à false à dessein, de sorte que l'intégration la plus simple est toujours sûre.
L'exception d'ouverture en cas de panne
Certaines catégories sont à risque assez faible pour que les refuser pendant une panne soit pire que les autoriser (par exemple, un signal d'analytique non sensible). Les SDK vous laissent fonctionner en ouverture pour de telles catégories, mais seulement à travers des barrières indépendantes, afin que cela ne puisse jamais se produire par accident et soit toujours audité.
TypeScript : trois barrières
const agreely = new Agreely({
apiKey,
degradeOnOutage: {
mode: "fail-open", // gate 1a: the explicit word
categories: ["Browsing/usage"], // gate 1b: ONLY these may ever degrade
maxOutageWindow: "5m", // refuse to degrade past this
onDegrade: (ctx) => audit.log(ctx) // MANDATORY, without it, the constructor throws
},
});
// gate 2: the call must ALSO opt in. Effective only because the category is
// allow-listed. Without the config, this per-call opt-in still denies.
await agreely.check("cust_8812", "Browsing/usage", "Analytics", { onOutage: "allow" });
// gate 3 (operator): break-glass, for an active incident.
agreely.breakGlass.engage({ reason: "incident-4471", ttl: "30m", scope: ["Browsing/usage"] });
PHP : deux barrières
PHP livre la même liste d'autorisation de configuration + l'adhésion par appel. Il omet le bris de glace en v1, parce qu'un runtime à portée de requête ne peut détenir honnêtement un état « engagé » à l'échelle du parc (voir le SDK PHP).
$agreely = new Agreely([
'apiKey' => $key,
'degradeOnOutage' => [
'mode' => 'fail-open',
'categories' => ['Browsing/usage'],
'maxOutageWindow' => '5m',
'onDegrade' => fn ($ctx) => $audit->log($ctx), // MANDATORY
],
]);
$agreely->check('cust_8812', 'Browsing/usage', 'Analytics', ['onOutage' => 'allow']);
Les garde-fous
Ce que l'ouverture en cas de panne ne vous laissera pas faire
- Aucune dégradation silencieuse.
onDegradeest obligatoire; sans collecteur d'audit, le constructeur lève une exception. Chaque autorisation dégradée émet un enregistrement de preuve, et chaque autorisation accordée par bris de glace émet son propre événement. - Aucune fenêtre non bornée. Le
ttlet lemaxOutageWindowsont tous deux plafonnés à 24 h; au-delà du plafond, lèveAgreelyConfigError. - Aucune mémoire-cache d'autorisations. Il n'y a aucune mémoire-cache des décisions d'autorisation; l'ouverture en cas de panne est calculée par appel pendant une panne, jamais rejouée à partir d'une autorisation stockée.
- Aucune adhésion accidentelle. Une
onOutage: "allow"par appel sans catégorie correspondante inscrite n'a aucun effet (la vérification refuse toujours) et consigne un avertissement unique.
Régler les 429, pas les pannes
Une limite de débit (429) n'est pas une panne : c'est un signal de ralentir.
Deux options du constructeur la règlent, sans jamais toucher à la politique de
refus par défaut. maxRetries (défaut 0) ajoute des tentatives supplémentaires
sur un 429 seulement et uniquement pour les appels idempotents
(GET et check); un appel mutant ne ré-essaie jamais. respectRetryAfter
(défaut true) honore l'en-tête Retry-After du serveur. Une panne, elle, n'est
jamais ré-essayée en silence : elle refuse (ou lève AgreelyUnavailableError) et
vous laisse décider.
Recommandation
Gardez la valeur par défaut. Le refus par défaut est correct pour tout ce qui
touche à des données sensibles ou porte une obligation de conformité, soit la
plupart de ce que vous protégerez. Réservez l'ouverture en cas de panne à une
catégorie précise et à faible risque où la disponibilité l'emporte réellement sur
l'application stricte, et câblez son collecteur onDegrade dans la même piste
d'audit que vous montreriez à un régulateur.
Ensuite
- La référence de dégradation des SDK TypeScript et SDK PHP.
- Notions de base sur pourquoi la vérification fonctionne en refus par défaut par conception.