Scrydon

Agent Control Standard (ACS)

Contrôle signé et fail-closed des cycles de vie des agents Scrydon.

Scrydon implémente le contrat de fil (wire contract) v0.1.0 de l'Agent Control Standard (ACS). ACS distingue un Agent Observé (Observed Agent), qui signale une étape avant d'agir, d'un Agent Gardien (Guardian Agent), qui répond allow, deny, modify, ask ou defer.

Dans le déploiement par défaut, Agentic est l'Agent Observé et API Platform est le Gardien. Leur trafic est scopé par organisation, signé, protégé contre le rejeu, et persisté via Dapr, de sorte qu'un workflow peut reprendre sur une autre réplique sans démarrer une seconde session de contrôle.

Profils de conformité actifs

Les profils sont négociés pour chaque session. Scrydon ne déclare un profil que lorsque la composition en cours dispose des méthodes, algorithmes et sinks requis.

ProfilAgentic (Agent Observé)API Platform (Gardien)
acs-coreNon revendiqué par la session lifecycle-onlyActif
acs-auditActifActif
acs-inspectNon émisNon activé par défaut ; nécessite une surface d'inventaire AgBOM composée et activement maintenue (la projection canonique, pas un export CycloneDX — aucun n'existe)
acs-inspect-dynamicNon émisNon activé par défaut ; nécessite aussi la surface de changement en direct
acs-provenanceNon déclaréActif par défaut ; accepté uniquement depuis des producteurs déterministes
acs-traceNon activé par défautDéclaré uniquement lorsqu'un sink OTel/OCSF est installé ; il n'existe pas de composant Dapr acs-trace
acs-cryptoNon déclaré ; la référence HMAC-SHA256 est utiliséeNon déclaré ; la référence HMAC-SHA256 est utilisée

Le package ACS contient des primitives Trace, AgBOM canonique et provenance pour les compositions qui installent ces capacités. Il ne fournit qu'une seule implémentation de signature, HMAC-SHA256, donc acs-crypto est refusé à la construction de la politique plutôt qu'offert. Le support du package seul n'est pas une revendication de conformité au niveau du déploiement.

Cycle de vie Agentic gouverné

Une exécution de bloc Agent correspond à une session ACS durable. Agentic émet aujourd'hui ces méthodes signées :

MéthodePoint de contrôle
handshake/helloNégocie les méthodes, profils, transport et posture d'échec exacts
steps/sessionStartOuvre la session scopée à l'exécution
steps/agentTriggerEnregistre comment l'agent a été activé
steps/turnStartContrôle chaque tour fournisseur/boucle d'outils avant qu'il ne s'exécute
steps/agentResponseContrôle la sortie du tour terminé avant que le workflow ne la reçoive
steps/turnEndEnregistre le résultat terminal du tour
steps/sessionEndFerme la session et valide la tête de chaîne finale

La session lifecycle ne revendique délibérément pas acs-core : Core exige des hooks de requête et de résultat d'outil, alors que Scrydon gouverne ces opérations dans la session d'exécution séparée d'API Platform. Sa liste methods_implemented ne contient donc que les méthodes que cette session peut réellement émettre. Le Gardien exige toujours acs-audit, donc le cycle de vie reste signé, chaîné et fail-closed.

Les opérations modèle, récupération, mémoire et outils de la Platform sont également gouvernées au point de passage obligé (chokepoint) de l'extension-runtime d'API Platform. Ce chemin utilise le même instantané de guardrails d'organisation ordonné et le même vocabulaire d'étapes ACS, sans ajouter une seconde passe de politique : le hook ACS in-process enregistre le verdict déjà atteint par le pipeline de guardrails du kernel dans la chaîne de session durable — il ne réévalue pas une seconde fois. L'ingress Gardien pour les agents que Scrydon n'héberge pas (voir plus bas) résout ce même instantané de guardrails, mais l'évalue via sa propre couche de politique déterministe, et non via le runner du kernel.

Posture d'échec et de rejeu

Scrydon négocie on_decision_failure: deny, et cette posture est un plancher que la contrepartie ne peut pas abaisser : le Gardien renvoie toujours sa propre posture configurée dans le ServerHello négocié, quelle que soit la demande du client — un pair ne peut donc pas négocier proceed. Un délai dépassé, une signature invalide, une réponse malformée, un sidecar Dapr manquant, ou une écriture d'état non confirmée arrêtent donc l'action. Un résultat unguarded est enregistré distinctement et n'est jamais traité comme une permission.

Chaque requête possède une identité unique, un horodatage et un nonce. Le Gardien rejette les identifiants de requête dupliqués, les nonces dupliqués, les requêtes hors de la fenêtre de tolérance (skew) négociée, et les têtes de chaîne client qui divergent de son état de session durable.

Les points de contrôle utilisent des lectures fortes et une concurrence optimiste, mais Agentic et le Gardien ne partagent pas le même espace de clés. L'état de cycle de vie propre à Agentic reste dans le store Dapr exec-security-state. L'état de session du Gardien — le handshake négocié, la garde anti-rejeu, et la chaîne d'audit à partir de laquelle ses verdicts sont calculés — vit dans son propre composant, acs-guardian-state, réservé à API Platform seule et scellé au repos en AES-256-GCM sous une clé que seule API Platform détient : la charge de travail qu'un Gardien juge ne doit pas pouvoir forger les lignes qui décident de ses propres verdicts. Dans le chart livré, ce store réside encore dans la base de données d'Agentic ; un rôle de base de données dédié est suivi comme travail à venir, et d'ici là une session supprimée au niveau SQL échoue de manière fermée plutôt que d'être rejouée. Si la livraison réussit mais que le client ne peut pas confirmer son point de contrôle, la session échoue de manière fermée plutôt que de rejouer une requête dont l'issue est incertaine.

Signatures

Le déploiement par défaut dérive une clé de session HMAC-SHA256 distincte à partir du secret partagé ACS_GUARDIAN_HMAC_SECRET, de l'organisation, du workflow et des identifiants de session. Les requêtes et réponses sont signées sur l'enveloppe canonique ; le secret racine ne transite jamais sur le fil.

Comme chaque appelant s'authentifie avec ce même secret partagé au niveau du déploiement, cette frontière de contrôle fonctionne uniquement pour les agents hébergés par Scrydon — un agent que votre organisation exploite en dehors du déploiement Scrydon ne peut pas détenir en toute sécurité la même clé racine partagée. Étendre le contrôle signé à un agent hébergé de manière indépendante par le client nécessite une signature asymétrique, que ce déploiement n'offre pas encore.

Configurez une seule clé (ACS_GUARDIAN_HMAC_SECRET, au moins 32 caractères) pour API Platform et Agentic. Le chart Helm génère et préserve une clé à la première installation. Sous global.requireExplicitSecrets: true — le mode pour le rendu GitOps/sans lookup (helm template, ArgoCD, manifestes air-gap hors ligne), où un repli de type « génère au rendu » ferait tourner le secret en silence à chaque synchronisation — le chart échoue le rendu à la place et nomme la valeur que l'opérateur doit définir explicitement : auth.secrets.ACS_GUARDIAN_HMAC_SECRET. La même règle s'applique à la clé de scellement propre au store du Gardien, auth.secrets.ACS_GUARDIAN_STATE_ENCRYPTION_KEY.

Variables d'environnement

VariableS'applique àSignification
ACS_REQUIREDAPI Platform, AgenticIndique si un processus incapable de joindre le Gardien peut démarrer. Le chart Helm rend true dans tous les environnements (auth.acs.required) ; un processus brut sans indicateur ne vaut true que lorsque NODE_ENV=production. Désactivé, une entrée manquante désactive ACS avec un avertissement qui la nomme, et les jauges scrydon_acs_guardian_enabled / scrydon_acs_observed_agent_enabled valent 0.
ACS_GUARDIAN_HMAC_SECRETAPI Platform, AgenticClé HMAC racine. Requise tant que ACS_REQUIRED est actif — le démarrage lève une exception et le processus ne démarre pas sans elle, sans un sidecar Dapr joignable, et (API Platform uniquement) sans la clé de scellement ci-dessous.
ACS_GUARDIAN_MAX_CONCURRENTAPI PlatformPlafond global d'évaluations d'ingress ACS signées que ce pod exécute simultanément, tous tenants confondus. Défaut 64. Le plafond par organisation (16) n'est pas un réglage par variable d'environnement — il existe spécifiquement pour qu'un tenant ne puisse pas consommer tout le budget.
ACS_VERDICT_AUDITAPI PlatformQuels verdicts ACS deviennent des lignes du journal d'audit : all (défaut), denials, ou off. Voir Audit et observabilité.
ACS_GUARDIAN_STATE_ENCRYPTION_KEYAPI PlatformClé AES-256-GCM qui scelle les valeurs du store acs-guardian-state du Gardien au repos. Détenue uniquement par API Platform — délibérément distincte de la clé EXEC_SECURITY_STATE_ENCRYPTION_KEY qu'Agentic détient aussi, puisqu'Agentic exécute les agents que ces lignes jugent. Requise tant que ACS_REQUIRED est actif ; il n'existe pas de repli « fonctionner sans scellement ». Valeur base64url non rembourrée de 32 octets (43 caractères) ; le chart en génère et en conserve une.

Audit et observabilité

Les requêtes ACS porteuses de contenu font avancer une chaîne inviolable par session. La chaîne s'engage sur les paramètres canoniques de la requête, y compris le condensé précédent sous forme d'octets bruts, comme l'exige ACS. turnEnd et sessionEnd sont des faits d'audit et ne peuvent pas opposer rétroactivement leur veto à un travail déjà terminé.

L'extension runtime expose un unique plan d'effets (effects plane) avec des contrats de durabilité distincts :

  • les projections d'audit et de facturation restent bloquantes ;
  • ACS Trace est best-effort et ne peut ni changer ni retarder un verdict ;
  • les observations de décision contiennent des métadonnées de corrélation et de politique, jamais le contenu modifié ni les charges utiles privées à la politique.

ACS_VERDICT_AUDIT (défaut all) sélectionne quels verdicts deviennent des lignes du journal d'audit :

  • une ligne de gouvernance (acs.decision.denied), écrite immédiatement pour chaque verdict refusant l'action (deny, ask, defer), portant le Detection Finding OCSF ;
  • une ligne de télémétrie par exécution (acs.decision.recorded), écrite à la fin de l'exécution, contenant la liste complète des décisions de cette exécution — y compris les étapes autorisées. Une réponse en streaming produit un verdict par fenêtre gouvernée et par chunk gouverné ; enregistrer chacun comme sa propre ligne aurait multiplié le volume d'audit d'un appel gouverné par la longueur de sa réponse, d'où cette agrégation.
  • denials n'écrit que la ligne de gouvernance ; off n'écrit aucune des deux — les spans continuent de tracer.

Il n'existe pas de redirecteur OCSF-vers-SIEM séparé : la ligne de gouvernance emprunte la livraison SIEM existante du journal d'audit, signée par HMAC, donc un Log Receiver déjà configuré pour le journal d'audit récupère les refus ACS sans configuration supplémentaire. Il n'existe pas de composant Dapr acs-trace.

Lorsqu'un sink Trace est installé, chaque étape gouvernée utilise le nom de span OpenTelemetry ACS, son verdict est attaché comme un événement de span acs.decision, et la même étape/décision est émise comme un événement OCSF idempotent. Sans sink actif, le handshake ne revendique pas acs-trace.

Streaming

Un intercepteur en mode enforce qui déclare une fenêtre gouvernable (streamWindow) évalue et libère une réponse en streaming par fenêtres, de sorte qu'elle atteint l'appelant au fur et à mesure qu'elle est produite. Cela ne tient que lorsque chaque intercepteur enforçant sur ce flux déclare une fenêtre : si un seul ne le fait pas, tout le flux est retenu et évalué comme un seul bloc avant que le premier octet ne soit libéré — c'est la conception du streaming par fenêtres du pipeline de guardrails, pas une panne. Les intercepteurs audit-only et les intercepteurs à fenêtre observent chaque chunk et chaque fenêtre gouvernés au fil de l'eau.

Quel que soit le mode applicable, la chaîne de session ACS elle-même n'est pas multipliée par la longueur du flux : la chaîne enregistre une seule étape de preuve agrégée pour l'opération gouvernée, construite à partir des mêmes fenêtres et chunks observés par le pipeline de guardrails, plutôt qu'une entrée de chaîne par jeton.

Scrydon en tant que Gardien

Des identités de charge de travail authentifiées, scopées par organisation, peuvent soumettre des enveloppes JSON-RPC ACS signées officielles via l'opération Platform agent.control.evaluate. Son scope, agent-control:write, est le seul scope Platform qu'une session utilisateur ou une clé API ne satisfait jamais : seule une charge de travail de service que le registre interne y autorise (Agentic aujourd'hui) peut atteindre le Gardien ou occuper son budget d'admission. API Platform résout la politique DLP, de modération et de classification courante de l'organisation pour chaque requête ; elle ne met jamais en cache la politique d'un tenant pour un autre. L'ingress ACS signé est plafonné par organisation (16 requêtes concurrentes, 64 au global, une attente maximale de 2 secondes) ; une organisation saturée reçoit un HTTP 429 avec reason: rate_limited plutôt que d'affamer le trafic agent de tous les autres tenants.

L'authentification et l'attribution répondent à deux questions différentes. Le Gardien authentifie la charge de travail appelante via l'identité de transport propre à la gateway Platform — jamais une valeur lue dans le corps de la requête — et attribue l'étape à un agent à partir du metadata.agent_id de l'enveloppe signée. Une enveloppe bien formée nomme l'agent workflow réellement observé ; une enveloppe malformée retombe sur l'identité de la charge de travail authentifiée, de sorte que le Gardien renvoie le INVALID_REQUEST propre au protocole plutôt que de faire confiance à une revendication non vérifiée.

Le Gardien par défaut prend en charge la validation déterministe de la provenance, les cinq dispositions, la protection contre le rejeu, et la chaîne d'audit du contenu de la requête. Le kernel ACS peut valider des instantanés et changements AgBOM canoniques, mais le Gardien ne revendique Inspect qu'une fois ces éléments composés en une surface d'inventaire active — le déploiement livré ne la compose pas aujourd'hui. acs-crypto n'est pas non plus offert par la couche enveloppe ACS : ce package ne fournit qu'une seule implémentation de signature fonctionnelle, HMAC-SHA256. Scrydon signe séparément ses points de contrôle (checkpoints) du journal d'audit Better Auth avec ML-DSA-65, mais il s'agit d'un système différent avec une chaîne d'audit différente, et cela ne rend pas vraie la revendication acs-crypto de cette couche enveloppe. Un état de politique malformé ou indisponible échoue de manière fermée.

Visibilité pour les administrateurs

Les administrateurs d'organisation accèdent à ce contrôle via Paramètres → Gouvernance → Agent Control. Le panneau expose la seule limite ACS réellement configurable par un administrateur — maxAgentTurnsPerExecution, le plafond de tours par exécution du Gardien — ainsi qu'un texte en lecture seule décrivant ce que le plan de contrôle applique déjà automatiquement. Ce n'est pas une sonde de handshake ou de posture en direct : le reste d'ACS (audit, DLP, protection contre le rejeu, Trace) est soit appliqué sans bascule de configuration, soit pas encore composé dans ce déploiement — et le panneau le dit, plutôt que d'afficher un badge de statut qui ne reposerait sur rien.

Frontières actuelles

Le déploiement par défaut n'envoie pas les hooks Agentic de Scrydon à un Gardien externe exploité par le client, n'émet pas les hooks de cycle de vie de compaction, de sous-agent, de compétence (skill) ou d'AgBOM d'Agentic, et ne revendique pas acs-inspect, acs-inspect-dynamic, ni acs-crypto. Ces capacités doivent être composées et négociées avant de pouvoir être revendiquées.

Voir aussi

Sur cette page

Sur cette page