Claude Platform Docs
AdministrationAccess Transparency

Vérifier les événements Access Transparency avec le journal de transparence

Utilisez les checkpoints signés et les preuves de Merkle de la Compliance API pour vérifier qu'aucun événement Access Transparency n'a été supprimé ou modifié après avoir été enregistré dans le journal.

Découvrez comment vérifier cryptographiquement qu'aucun événement Access Transparency n'a été supprimé ou modifié après avoir été enregistré dans le journal de transparence de votre organisation.

Fonctionnement du journal de transparence

Un « transparency log » (journal de transparence) est une technique qui rend détectable toute altération d'un registre. Les entrées ne sont jamais qu'ajoutées. Chaque fois que le journal s'agrandit, son opérateur signe une courte déclaration, appelée « checkpoint » (point de contrôle), qui s'engage sur toutes les entrées jusqu'à ce point au moyen d'un hachage d'arbre de Merkle. Toute personne qui conserve un checkpoint peut ensuite exiger la preuve que le journal actuel contient toujours tout ce que ce checkpoint couvrait, sans modification et dans le même ordre. La suppression ou la réécriture d'une entrée ne peut donc pas passer inaperçue auprès d'un vérificateur ayant conservé un checkpoint couvrant cette entrée. Certificate Transparency et la base de données de sommes de contrôle des modules Go reposent sur la même technique. C2SP tlog-tiles est une spécification ouverte permettant de servir un tel journal sous forme de checkpoints signés et de tuiles statiques de hachages et d'entrées, pouvant être mises en cache, afin que les clients puissent récupérer les hachages et calculer eux-mêmes chaque preuve.

Lorsqu'Access Transparency est activé, Anthropic maintient un journal de transparence pour votre organisation. Il s'agit d'un registre en ajout seul, signé cryptographiquement, des événements Access Transparency (anthropic_access et cmek_preserve). Chacun de ces événements enregistré pour votre organisation après la création du journal y est ajouté. Le journal suit le format C2SP tlog-tiles, de sorte que les outils conçus pour cette norme comprennent ses checkpoints, ses tuiles et ses preuves.

  • Un journal par organisation. Le journal de chaque organisation possède une chaîne d'origine fixe : axt.anthropic.com/<your organization UUID>. L'origine ne change jamais pendant toute la durée de vie de l'organisation.
  • Chaque nouvel événement devient une feuille. Lorsqu'un événement Access Transparency devient éligible pour apparaître sur votre Activity Feed, il est d'abord ajouté à votre journal en tant que « leaf » (feuille), et seulement ensuite servi sur le flux. Une feuille est une sérialisation déterministe des champs documentés de l'événement. L'événement sur votre flux porte transparency_log_leaf_index, sa position (à partir de zéro) dans votre journal.
  • Les checkpoints s'engagent sur tout l'historique. Le journal est un arbre de Merkle. Chaque fois qu'il s'agrandit, Anthropic publie un checkpoint signé : un court document texte indiquant l'origine du journal, sa taille actuelle et le hachage racine qui s'engage sur chaque feuille. Chaque checkpoint porte exactement une signature de la clé de signature du journal.
  • Deux preuves en découlent. Une « inclusion proof » (preuve d'inclusion) montre qu'un événement spécifique est présent à sa position sous un checkpoint. Une « consistency proof » (preuve de cohérence) montre qu'un checkpoint ultérieur est une extension en ajout seul d'un checkpoint antérieur que vous avez enregistré, de sorte que rien entre les deux n'a été supprimé ou modifié.
  • Les clés de vérification sont servies dans le même canal. Le point de terminaison des clés de vérification renvoie les clés publiques qui signent les checkpoints. Lors d'une rotation de clé planifiée, la nouvelle clé est ajoutée à cette liste avant de commencer à signer, et les clés antérieures restent listées. Les checkpoints que vous détenez déjà continuent donc d'être vérifiables.

Ce que prouve le journal de transparence

  • Les champs de feuille d'un événement que vous détenez (listés dans Comment un événement devient une feuille) sont, octet pour octet, ce qu'Anthropic a enregistré dans le journal.
  • Le journal de votre organisation ne fait que s'agrandir. La vérification par rapport à un checkpoint que vous détenez échoue si un événement enregistré dans le journal y est ensuite supprimé ou réécrit. Elle échoue également si l'on vous sert un historique différent de celui qui vous a été servi auparavant.
  • Les nouvelles entrées ne peuvent qu'être ajoutées à la fin. Un événement ne peut pas être inséré dans un historique que vous avez déjà vérifié.

Ce qu'il ne prouve pas ou ne modifie pas

  • Il ne prouve pas que chaque accès a été enregistré, ni qu'un événement enregistré décrit fidèlement l'accès. Il prouve seulement que ce qu'Anthropic a enregistré dans le journal n'a pas changé depuis.
  • Il ne modifie pas ce que couvre Access Transparency ni le moment où les événements arrivent.
  • Les champs servis en dehors de la feuille, tels que workspace_uuid et tout champ ajouté ultérieurement, ne sont pas couverts par la preuve.
  • Une preuve d'inclusion porte sur un événement qui vous a été servi. Elle ne prouve pas à elle seule que le flux a listé chaque feuille que contient le journal. Les lots d'entrées du journal contiennent chaque feuille, vous pouvez donc lire directement l'ensemble complet des événements enregistrés lorsque vous en avez besoin.
  • La présence de transparency_log_leaf_index sur un événement est un pointeur, pas une preuve. Vérifiez toujours l'inclusion avant de considérer un événement comme enregistré dans le journal.
  • La protection contre un historique réécrit provient des checkpoints que vous conservez. La signature d'un checkpoint par une clé listée dans Empreintes de clés publiées prouve qu'il provient du journal d'Anthropic. Une preuve de cohérence à partir du checkpoint que vous avez enregistré la dernière fois prouve que l'historique que vous avez déjà observé n'a fait que s'agrandir.

Avant de commencer

Vous avez besoin de :

  • Une Compliance Access Key avec la portée read:compliance_activities, la même clé et la même portée que celles que vous utilisez pour l'Activity Feed. Une clé d'organisation parente peut lire le journal de chaque organisation enfant inscrite en nommant l'organisation enfant dans chaque requête.
  • L'UUID de votre organisation. Vous le trouverez dans la Claude Console sous Settings > Organization. Il s'agit de la même valeur que celle que l'Activity Feed sert en tant que organization_uuid, mais prenez-la depuis la Console. C'est cette valeur qui fait qu'un checkpoint est le vôtre, elle ne doit donc pas provenir de l'API que vous vérifiez. Vous en dérivez l'origine de votre journal sous la forme axt.anthropic.com/<organization UUID>. Dérivez cette chaîne vous-même. Ne la lisez pas depuis une réponse de l'API.
  • Un emplacement durable pour conserver le dernier checkpoint que vous avez vérifié. Ce checkpoint enregistré est ce qui transforme « le journal est cohérent aujourd'hui » en « le journal est cohérent depuis que vous avez commencé à le surveiller ».

Délais

  • Événements : les événements Access Transparency apparaissent sur votre Activity Feed dans un délai de deux jours ouvrés après l'accès. Un événement n'entre dans le journal qu'une fois qu'il est éligible pour être servi, de sorte que le journal ne révèle jamais un événement de manière anticipée. Comme le journal est écrit avant que le flux ne serve l'événement, une entrée peut brièvement apparaître dans le journal avant que son événement n'apparaisse sur votre flux. Cet écart n'est pas une anomalie.
  • Checkpoints : un nouveau checkpoint est publié chaque fois que votre journal s'agrandit.
  • Preuves d'inclusion : une preuve pour un événement nouvellement servi est disponible dès qu'un checkpoint couvrant la position de l'événement est publié, normalement très peu de temps après l'apparition de l'événement. Si vous en demandez une plus tôt, vous recevez un 404 et réessayez après un court délai.
  • Fréquence de vérification : exécutez votre vérification au moins une fois par jour. Une fréquence horaire est raisonnable.
  • Désinscription : si votre organisation cesse d'utiliser Access Transparency, rien n'est supprimé. Votre journal reste lisible via les mêmes points de terminaison. Si Access Transparency est réactivé ultérieurement, le même journal se poursuit.

Conservation et suppression

  • Journal de transparence : Anthropic ne supprime pas d'entrées de votre journal, et le journal n'a pas d'expiration. Il est conservé si votre organisation cesse d'utiliser Access Transparency et après la suppression de votre organisation, car la suppression d'entrées est précisément le changement que le journal a vocation à détecter. Les lots d'entrées contiennent les champs de feuille de chaque événement, ces champs sont donc conservés aussi longtemps que le journal.
  • Activity Feed : les événements Access Transparency sur l'Activity Feed suivent la durée de conservation du flux. Les activités sont conservées pendant 6 ans. Consultez Interroger le flux d'activité.
  • Aucune suppression de votre part : les points de terminaison du journal de transparence sont en lecture seule. Il n'existe aucun moyen de supprimer ou de modifier une entrée.

Points de terminaison du journal de transparence

Six points de terminaison en lecture seule sont servis sous https://api.anthropic.com/v1/compliance/transparency_log/ :

Point de terminaisonRenvoie
GET /checkpointLe dernier checkpoint signé
GET /keysL'ensemble des clés de vérification
GET /inclusionUne preuve d'inclusion pour un événement
GET /consistencyUne preuve de cohérence d'un checkpoint que vous détenez vers le plus récent
GET /tile/{level}/{index}Une tuile de hachages de Merkle
GET /tile/entries/{index}Un lot d'entrées d'octets de feuilles

Les checkpoints, les tuiles et les lots d'entrées suivent exactement le format de transmission C2SP tlog-tiles. Les deux points de terminaison de preuve sont des commodités : chaque preuve peut également être calculée à partir des tuiles, vous n'avez donc jamais à faire confiance à la sortie d'un point de terminaison de preuve. Vous vérifiez les hachages qu'il renvoie par rapport à un checkpoint signé.

Authentification et portée

Envoyez votre Compliance Access Key dans l'en-tête x-api-key ainsi que l'en-tête anthropic-version, comme pour toute requête à la Compliance API (consultez Gestion des versions). La Compliance API doit être activée pour votre organisation.

Il n'existe pas d'autorisation distincte pour le journal de transparence. Toute clé capable de lire l'Activity Feed de votre organisation, pour votre organisation ou son organisation parente, peut lire l'intégralité de votre journal, y compris les champs d'événements de ses lots d'entrées.

Chaque requête lit exactement le journal d'une seule organisation :

  • Une clé de niveau organisation lit le journal de sa propre organisation. Le paramètre de requête organization_id est facultatif. S'il est présent, il doit nommer la propre organisation de la clé.
  • Une clé de niveau organisation parente doit transmettre organization_id, en nommant une organisation enfant.
  • organization_id accepte l'ID balisé org_... ou l'UUID de l'organisation.

Un 404 signifie qu'il n'existe aucun journal que cette clé peut lire. Une organisation hors de la portée de la clé, une organisation inexistante et une organisation dont le journal n'a pas encore été créé sont délibérément indiscernables. Le journal d'une organisation qui a depuis cessé d'utiliser Access Transparency ne relève pas de ce cas : il continue d'être servi.

Erreurs

Les erreurs utilisent l'enveloppe d'erreur JSON standard de la Compliance API sur chaque point de terminaison, y compris les points de terminaison texte et binaires. Consultez Erreurs pour l'enveloppe et les types d'erreurs partagés.

StatutSignification sur cette surface
400organization_id est mal formé ou est omis avec une clé d'organisation parente, la Compliance API n'est pas activée, un paramètre de requête est inconnu, ou une validation propre au point de terminaison a échoué
401La clé API est manquante ou non valide
403La clé ne dispose pas de la portée requise
404Aucun journal lisible par cette clé, ou les cas « non couvert » et « au-delà de l'arbre » propres au point de terminaison
429Limite de débit atteinte. Ces points de terminaison partagent la limite de débit par organisation parente de la Compliance API. Respectez retry-after
503Le journal est temporairement indisponible. Réessayez avec un délai d'attente progressif

Mise en cache

Les réponses ne peuvent être mises en cache que par le client qui effectue la requête. Cache-Control inclut toujours private, et les réponses portent Vary: x-api-key. Ne placez pas de cache partagé devant ces points de terminaison. Les tuiles complètes et les lots d'entrées complets ne changent jamais et sont servis avec Cache-Control: private, max-age=604800, immutable. Tout le reste, y compris les checkpoints, les preuves, les clés, les tuiles partielles et les erreurs, est servi avec Cache-Control: private, no-store.

Lire le dernier checkpoint

GET /v1/compliance/transparency_log/checkpoint

curl --fail-with-body -sS \
  "https://api.anthropic.com/v1/compliance/transparency_log/checkpoint" \
  --header "x-api-key: $ANTHROPIC_COMPLIANCE_ACCESS_KEY" \
  --header "anthropic-version: 2023-06-01"

La réponse est en text/plain : une note signée C2SP. Les lignes du corps sont l'origine, la taille de l'arbre en décimal et le hachage racine en base64. Une ligne vide suit, puis la ligne de signature, qui commence par un tiret cadratin (U+2014), nomme l'origine et se termine par une valeur en base64. Les valeurs ci-dessous sont données à titre d'illustration :

axt.anthropic.com/25f6429a-3293-49bf-afed-cb312911554b
1207
C6C4HzGRqDNlbu54LWCvpDX0NcB5DRTmLcjM4u5vWUI=

— axt.anthropic.com/25f6429a-3293-49bf-afed-cb312911554b q83vATBFAiEAvL8m…(base64)…
  • Les quatre premiers octets de la valeur de signature décodée sont le key_hash de la clé de signature, qui vous indique avec quelle entrée de l'ensemble des clés de vérification effectuer la vérification. Les octets restants sont une signature ECDSA P-256 ASN.1 DER sur le SHA-256 du corps de la note : chaque octet avant la ligne vide, y compris le saut de ligne final du corps.
  • Un checkpoint peut porter des lignes supplémentaires après le hachage racine. Ignorez les lignes que vous ne comprenez pas. Elles sont couvertes par la signature.
  • Ignorez une ligne de signature dont le nom n'est pas votre origine ou dont vous ne détenez pas le hachage de clé.
  • Ne mettez jamais un checkpoint en cache. Un checkpoint obsolète masque la taille actuelle du journal, de sorte que les événements nouvellement servis semblent non couverts.

Lire les clés de vérification

GET /v1/compliance/transparency_log/keys

curl --fail-with-body -sS \
  "https://api.anthropic.com/v1/compliance/transparency_log/keys" \
  --header "x-api-key: $ANTHROPIC_COMPLIANCE_ACCESS_KEY" \
  --header "anthropic-version: 2023-06-01"
{
  "type": "transparency_log_keys",
  "origin": "axt.anthropic.com/25f6429a-3293-49bf-afed-cb312911554b",
  "log_keys": [
    {
      "verifier_key": "axt.anthropic.com/25f6429a-3293-49bf-afed-cb312911554b+<key_hash>+<base64 key>",
      "key_hash": "<8 lowercase hex digits>",
      "fingerprint": "<64 lowercase hex digits>",
      "algorithm": "ecdsa_p256_sha256",
      "public_key": "<base64 DER SubjectPublicKeyInfo>"
    }
  ]
}
ChampTypeDescription
typestringToujours transparency_log_keys
originstringLa ligne d'origine que porte chaque checkpoint de ce journal. À titre informatif : comparez les checkpoints à l'origine que vous dérivez vous-même, et non à ce champ
log_keysarrayLa clé qui signe les nouveaux checkpoints en premier, puis toutes les autres clés que le journal sert, de la plus récente à la plus ancienne. Jamais vide
log_keys[].verifier_keystringLa clé sous forme de chaîne note-verifier C2SP, <origin>+<key_hash>+<base64 key>, acceptée par les outils tlog-tiles qui prennent en charge les clés de note ECDSA (par exemple, le module Go github.com/transparency-dev/formats). La partie base64 se décode en l'octet d'algorithme 0x02 suivi de la clé publique encodée en DER
log_keys[].key_hashstringHuit chiffres hexadécimaux en minuscules. Le sélecteur de 4 octets qui associe cette clé à la ligne de signature d'un checkpoint. Il s'agit des quatre premiers octets de fingerprint et ce n'est pas une identité
log_keys[].fingerprintstring64 chiffres hexadécimaux en minuscules : le SHA-256 du SubjectPublicKeyInfo DER
log_keys[].algorithmstringLe type de clé, actuellement ecdsa_p256_sha256. Des valeurs peuvent être ajoutées. Ignorez une clé dont vous ne prenez pas en charge l'algorithme
log_keys[].public_keystringLa clé publique sous forme de SubjectPublicKeyInfo DER en base64

Le key_hash ne couvre que les octets de la clé : il s'agit des quatre premiers octets du SHA-256 sur le SubjectPublicKeyInfo DER, qui est la règle qu'utilise l'encodage note-verifier ECDSA. Ce n'est pas l'ID de clé dépendant du nom que le format de note signée de base définit pour les clés Ed25519, il ne change donc pas avec l'origine. Une signature valide par une clé listée dans Empreintes de clés publiées prouve que le checkpoint provient du service de journal de transparence d'Anthropic. C'est la ligne d'origine à l'intérieur du checkpoint signé qui le lie à votre organisation. C'est pourquoi vous comparez cette ligne à l'origine que vous dérivez vous-même.

Les clés peuvent faire l'objet d'une rotation :

  • Une rotation est une bascule. À partir d'un certain checkpoint, les nouveaux checkpoints sont signés par la nouvelle clé.
  • Lors d'une rotation planifiée, la nouvelle clé apparaît dans log_keys avant de signer quoi que ce soit, et les clés antérieures restent listées. Un checkpoint que vous avez enregistré avant la rotation continue donc d'être vérifiable.
  • Un vérificateur peut récupérer l'ensemble des clés à chaque exécution ou le conserver localement. Un vérificateur qui le conserve localement relit ce point de terminaison lorsqu'il rencontre une signature dont il ne détient pas le key_hash.

Empreintes de clés publiées

Anthropic publie ici, en dehors de l'API, l'empreinte de chaque clé qui signe des checkpoints. Cela vous permet de vérifier une clé que vous détenez localement par rapport à une source que le chemin de service ne peut pas altérer. La clé que vous détenez peut provenir d'une réponse antérieure de GET /keys ou d'un outil qui épingle la clé.

Hachage de cléEmpreinte SHA-256AlgorithmeSigne depuisStatut
1dff5fe41dff5fe420d49743fe444a04fc17f818eea856699dec2ebbc24df15602c74a58ecdsa_p256_sha2562026-08-17Clé de signature actuelle

Une rotation planifiée est annoncée sur cette page au moins 30 jours avant que la nouvelle clé ne signe son premier checkpoint. Pendant cette période de préavis, la nouvelle clé est listée dans log_keys et dans ce tableau avec sa date de bascule. Les clés retirées restent listées avec leurs dates de service. Une clé qui n'apparaît pas dans ce tableau n'est pas légitime, quoi que renvoie GET /keys. Traitez un checkpoint qui ne se vérifie sous aucune clé listée comme un échec de vérification, et signalez-le à votre représentant de compte Anthropic ou au support Anthropic.

axt-verify intègre la clé actuelle dans chaque version et ne lit jamais de clé depuis l'API. Chaque version intègre exactement une clé. À la date de bascule, Anthropic commence à signer avec la nouvelle clé et publie la version d'axt-verify qui l'intègre. À la même date, Anthropic réémet le dernier checkpoint de chaque organisation sous la nouvelle clé, même pour un journal qui ne s'est pas agrandi. Effectuez la mise à niveau à la date de bascule. L'exécution de l'ancienne version après la bascule échoue avec le code de sortie 1, tout comme l'exécution de la nouvelle version avant celle-ci. L'un ou l'autre échec disparaît dès que vous exécutez la version correspondante. Un vérificateur que vous maintenez vous-même nécessite que la nouvelle empreinte, avec sa date de bascule, soit ajoutée avant cette date.

Récupérer une preuve d'inclusion

GET /v1/compliance/transparency_log/inclusion?leaf_index={index}

ParamètreTypeDescription
leaf_indexinteger, obligatoireLa position de l'événement dans le journal : le transparency_log_leaf_index que l'Activity Feed a servi sur l'événement. Doit être supérieur ou égal à zéro
organization_idstring, facultatifConsultez Authentification et portée
curl --fail-with-body -sS -G \
  "https://api.anthropic.com/v1/compliance/transparency_log/inclusion" \
  --data-urlencode "leaf_index=41" \
  --header "x-api-key: $ANTHROPIC_COMPLIANCE_ACCESS_KEY" \
  --header "anthropic-version: 2023-06-01"
{
  "type": "transparency_log_inclusion_proof",
  "leaf_index": 41,
  "hashes": [
    "mUdyOWMp0zXIq0CDMvSYDUSBl9yAvnTZzdm51RwWpUM=",
    "yR6tDHkAhKvdQSLqQATVjXOo4GM3FDyiKF2XCKTtMUI=",
    "..."
  ],
  "checkpoint": "axt.anthropic.com/25f6429a-3293-49bf-afed-cb312911554b\n42\nCsRlS31ITFHrX9GR5XjyPw8n0MkfrB8Yh2UDHl3Lr3E=\n\n— axt.anthropic.com/25f6429a-3293-49bf-afed-cb312911554b q83vATBEAiB0…(base64)…\n"
}
ChampTypeDescription
typestringToujours transparency_log_inclusion_proof
leaf_indexintegerLa position de l'événement dans le journal, reprise de la requête
hashesarray of stringsLes hachages frères en base64 du chemin d'audit, ordonnés de la feuille jusqu'à la racine
checkpointstringLe dernier checkpoint signé, celui par rapport auquel la preuve se vérifie. Il porte la taille de l'arbre

Il n'existe pas de recherche par ID d'activité. Vous détenez toujours l'index, car il arrive avec l'événement, et vous vérifiez la preuve par rapport aux octets de l'événement que vous avez récupérés depuis le flux.

Un 404 signifie que le dernier checkpoint publié ne couvre pas la position fournie :

  • Pour un index que vous avez lu sur un événement servi, cette situation est transitoire. Un checkpoint couvrant est publié peu après, réessayez donc après un court délai.
  • Le même 404 répond à toute autre position non couverte, comme un index que le flux n'a jamais servi. Pour une telle position, rien ne garantit qu'un checkpoint couvrant soit un jour publié. La réponse n'indique pas dans quel cas vous vous trouvez.

Un leaf_index manquant ou qui n'est pas un entier non négatif renvoie 400.

Récupérer une preuve de cohérence

GET /v1/compliance/transparency_log/consistency?from={size}

ParamètreTypeDescription
frominteger, obligatoireLa taille de l'arbre du checkpoint antérieur que vous détenez. Doit être au moins égale à 1 et au plus égale à la taille de l'arbre du dernier checkpoint
organization_idstring, facultatifConsultez Authentification et portée
curl --fail-with-body -sS -G \
  "https://api.anthropic.com/v1/compliance/transparency_log/consistency" \
  --data-urlencode "from=1180" \
  --header "x-api-key: $ANTHROPIC_COMPLIANCE_ACCESS_KEY" \
  --header "anthropic-version: 2023-06-01"
{
  "type": "transparency_log_consistency_proof",
  "hashes": [
    "dGw0aPzu2N0pdc4C5ZAvNIbkXF7J6F9ZQLkPpV6v8Vg=",
    "9PSWm1T9RUmhjF6z6YQzB9CW6E2m2n3mK0aVgqf5Qm0=",
    "..."
  ],
  "checkpoint": "axt.anthropic.com/25f6429a-3293-49bf-afed-cb312911554b\n1207\nC6C4HzGRqDNlbu54LWCvpDX0NcB5DRTmLcjM4u5vWUI=\n\n— axt.anthropic.com/25f6429a-3293-49bf-afed-cb312911554b q83vATBFAiEAvL8m…(base64)…\n"
}
ChampTypeDescription
typestringToujours transparency_log_consistency_proof
hashesarray of stringsLes hachages de preuve en base64, dans l'ordre RFC 9162
checkpointstringLe dernier checkpoint signé, celui jusqu'auquel la preuve s'étend. Il porte la taille de l'arbre
  • La preuve s'étend toujours jusqu'au dernier checkpoint publié. Cette API ne sert jamais de checkpoints historiques : vous conservez ceux qui vous sont servis.
  • Un from égal à la taille de l'arbre du dernier checkpoint renvoie la preuve vide.
  • Un checkpoint détenu de taille d'arbre 0 ne nécessite aucune preuve de cohérence, car tout journal étend le journal vide. Adoptez directement le dernier checkpoint dans ce cas.
  • Un from inférieur à 1, ou supérieur à la taille de l'arbre du dernier checkpoint, renvoie 400.
  • Si le journal ne peut plus prouver qu'il étend un checkpoint qu'il a un jour signé pour vous, traitez cela comme un échec de vérification, et non comme une erreur d'utilisation.

Lire une tuile de hachages

GET /v1/compliance/transparency_log/tile/{level}/{index}

Renvoie application/octet-stream : des hachages SHA-256 de 32 octets concaténés, conformément à tlog-tiles. L'adressage des tuiles suit exactement tlog-tiles, y compris la grammaire de chemin {level} et {index}, la forme d'index x001/234 pour les grands arbres et le suffixe de tuile partielle .p/{width}. Les tuiles de hachages sont l'unité à partir de laquelle les clients tlog-tiles calculent eux-mêmes les preuves.

  • Les tuiles complètes sont immuables et sont servies avec Cache-Control: private, max-age=604800, immutable.
  • Les tuiles partielles sont remplacées à mesure que l'arbre s'agrandit et sont servies avec Cache-Control: private, no-store. Une fois qu'une tuile est remplie, une requête pour sa forme partielle antérieure peut renvoyer 404 même si la tuile complète existe. Le repli de la tuile partielle vers la tuile complète incombe au client, comme le spécifie tlog-tiles, et les clients standard le font déjà.
  • Un level, un index ou une largeur de tuile partielle mal formés renvoient 400. Une position de tuile au-delà de la taille actuelle de l'arbre renvoie 404.

Lire un lot d'entrées

GET /v1/compliance/transparency_log/tile/entries/{index}

Renvoie application/octet-stream : des entrées de feuilles consécutives, chacune préfixée par sa longueur en uint16 big-endian, conformément à tlog-tiles. Les lots d'entrées contiennent le texte en clair des événements : les octets canoniques de chaque événement Access Transparency. C'est pourquoi l'ensemble de la surface requiert la portée de l'Activity Feed. L'adressage, la forme partielle, la mise en cache et les erreurs sont identiques à ceux des tuiles de hachages.

Le champ transparency_log_leaf_index sur les événements de l'Activity Feed

Les événements anthropic_access et cmek_preserve sur GET /v1/compliance/activities portent transparency_log_leaf_index, un entier, chaque fois que l'événement possède une feuille. Les autres types d'activités ne le portent jamais.

  • La clé est absente, et non null, lorsque l'événement n'a pas de feuille. Un vérificateur robuste traite une clé absente et une valeur null de la même manière.
  • Un événement n'est servi sans transparency_log_leaf_index que dans deux cas. Le premier est lorsque votre organisation n'est pas inscrite à Access Transparency, c'est-à-dire avant l'inscription ou entre une désinscription et une réinscription. Le second est lorsque l'événement a été enregistré avant la création du journal de votre organisation. Pour une organisation inscrite avant l'introduction du journal de transparence, cela inclut son historique antérieur. Une fois votre journal créé et tant que vous êtes inscrit, chaque événement est ajouté au journal avant que le flux ne le serve. Si une défaillance empêche le flux de connaître l'index, le flux retarde l'événement plutôt que de le servir sans index. L'événement n'est pas perdu : il est déjà dans le journal et apparaît sur le flux, index compris, une fois la défaillance corrigée. Un événement sans index n'est pas attendu lorsqu'il est daté d'après la création de votre journal et se situe dans une période pendant laquelle vous étiez inscrit.
  • Un index présent est un pointeur, pas une preuve. Vérifiez l'inclusion avant de considérer l'événement comme enregistré dans le journal. L'anomalie qui mérite d'être remontée est un index présent dont la preuve d'inclusion ne peut toujours pas être récupérée longtemps après qu'un checkpoint couvrant aurait dû être publié.
  • L'index est attribué lorsque l'événement est ajouté au journal et ne fait pas partie des champs qui composent la feuille.

Comment un événement devient une feuille

Une entrée de feuille est l'octet de version de schéma 0x01 suivi du JSON canonique de 11 champs. Le JSON suit la RFC 8785 (JSON Canonicalization Scheme), et les champs sont pris de l'événement exactement tel que l'Activity Feed le sert :

  • id, type, created_at, accessed_at, organization_id, organization_uuid, workspace_id, accessor_department et reason_code
  • actor, avec ses champs imbriqués type et email_address
  • resource_details, avec ses champs imbriqués type, id et parent

Les règles :

  • Les champs servis en dehors de cet ensemble, tels que workspace_uuid et transparency_log_leaf_index lui-même, sont ignorés.
  • Un champ documenté que l'événement servi omet entre dans la feuille en tant que null. Une chaîne vide est distincte de null.
  • actor et resource_details sont des objets comportant exactement leurs clés documentées lorsque l'événement servi les porte. Sous la version 0x01, actor.email_address et resource_details.parent sont toujours null. Lorsque l'événement servi omet l'un de ces objets ou le sert en tant que null, la valeur entière est null dans la feuille, et non un objet de champs null. De nombreux événements d'accès ne portent pas de resource_details.
  • Les valeurs de chaîne, y compris les deux horodatages et reason_code, sont prises octet pour octet telles que servies. Si vous redérivez un horodatage à partir d'une autre représentation, reproduisez exactement le rendu servi :
    • RFC 3339 UTC avec un suffixe Z.
    • created_at n'a aucun chiffre fractionnaire lorsque ses microsecondes sont nulles, et exactement six sinon.
    • accessed_at a zéro, trois, six ou neuf chiffres fractionnaires, le plus petit nombre qui préserve exactement ses nanosecondes.
  • Le JSON canonique signifie des clés d'objet triées, aucun espace blanc non significatif et un échappement de chaîne minimal. Aucun nombre n'apparaît nulle part dans la feuille.
  • Le hachage de feuille est le SHA-256(0x00 || entry) de la RFC 6962. Les nœuds internes sont hachés sous la forme SHA-256(0x01 || left || right).
  • Un vérificateur rejette un octet de version inconnu, ainsi qu'une feuille 0x01 dont le type n'est pas l'un des deux types Access Transparency. Les nouveaux types d'événements ou les modifications de règles sont livrés sous un nouvel octet de version. Les feuilles existantes ne sont jamais rehachées.

Par exemple, cet événement d'accès tel que l'Activity Feed le sert :

{
  "id": "activity_01GPXmAhizavrUuoXNn3tzeA",
  "type": "anthropic_access",
  "created_at": "2025-07-08T18:40:00Z",
  "accessed_at": "2025-07-08T18:39:58Z",
  "organization_id": "org_015gtSHLz269eTwgrH8NX5yk",
  "organization_uuid": "25f6429a-3293-49bf-afed-cb312911554b",
  "workspace_id": "wrkspc_01PaGUP2rbg1XDh7Z9W1CEpd",
  "workspace_uuid": "b6ce2143-1083-d4a7-247c-17530f55a076",
  "accessor_department": "Trust & Safety",
  "reason_code": "safety_review",
  "actor": { "type": "anthropic_actor", "email_address": null },
  "resource_details": { "type": "message", "id": "msg_01HXAMPLE12345678" },
  "transparency_log_leaf_index": 17
}

devient ce JSON canonique. Il comporte exactement les 11 clés documentées, triées, sur une seule ligne. workspace_uuid et transparency_log_leaf_index disparaissent, et resource_details.parent, absent de l'événement servi, entre en tant que null :

{"accessed_at":"2025-07-08T18:39:58Z","accessor_department":"Trust & Safety","actor":{"email_address":null,"type":"anthropic_actor"},"created_at":"2025-07-08T18:40:00Z","id":"activity_01GPXmAhizavrUuoXNn3tzeA","organization_id":"org_015gtSHLz269eTwgrH8NX5yk","organization_uuid":"25f6429a-3293-49bf-afed-cb312911554b","reason_code":"safety_review","resource_details":{"id":"msg_01HXAMPLE12345678","parent":null,"type":"message"},"type":"anthropic_access","workspace_id":"wrkspc_01PaGUP2rbg1XDh7Z9W1CEpd"}

L'entrée de feuille est l'octet 0x01 suivi de ces octets UTF-8. Son hachage de feuille, SHA-256(0x00 || entry), est 6ro7vTcFq+sYDZiiGvZaFetUIoMSLig3DGDrCKK1HFU= en base64. Utilisez cet exemple comme vecteur de test pour votre propre code de canonicalisation.

Vérifier votre journal

La vérification s'exécute sur votre propre infrastructure. Tout ce que renvoie l'API n'est pas fiable tant que cela n'a pas été vérifié par rapport à deux éléments que vous détenez vous-même. Le premier est l'origine que vous dérivez de l'UUID de votre organisation. Le second est le checkpoint que vous avez enregistré lors de votre dernière exécution. Une exécution de vérification complète effectue les opérations suivantes, dans l'ordre :

  1. Récupérez l'ensemble des clés de vérification. Calculez vous-même l'empreinte de chaque clé en tant que SHA-256 de sa public_key décodée depuis le base64. Ne conservez que les clés dont l'empreinte apparaît dans Empreintes de clés publiées, ainsi que le statut de chaque clé qui y figure. Ne vérifiez un checkpoint nouvellement récupéré que sous une clé que ce tableau liste comme actuelle à cette date. N'acceptez une clé retirée que pour un checkpoint que vous avez enregistré avant sa date de retrait.
  2. Établissez le dernier checkpoint. Lors de la première exécution, récupérez-le depuis le point de terminaison de checkpoint. Lors de chaque exécution ultérieure, demandez une preuve de cohérence à partir de la taille d'arbre que vous avez enregistrée. La réponse porte le dernier checkpoint avec la preuve.
  3. Vérifiez d'abord la ligne d'origine du checkpoint. Comparez sa première ligne, octet pour octet, avec l'origine que vous avez dérivée. Rejetez tout checkpoint dont l'origine diffère, avant toute autre opération.
  4. Vérifiez la signature du checkpoint. Trouvez la ligne de signature nommée d'après votre origine dont les quatre premiers octets décodés sont égaux au key_hash d'une clé actuellement valide que vous avez conservée. Vérifiez les octets restants en tant que signature ECDSA P-256 sur le SHA-256 du corps de la note, en utilisant la public_key de cette clé. Si aucune ligne de signature ne correspond à une telle clé, ou si la signature ne se vérifie pas, rejetez le checkpoint.
  5. Prouvez l'ajout seul. Si la nouvelle taille d'arbre est inférieure à celle que vous avez enregistrée, la vérification échoue. Si elle est égale, les hachages racines doivent correspondre. Si elle est supérieure, vérifiez la preuve de cohérence RFC 9162 de votre taille et de votre hachage racine enregistrés vers la nouvelle taille et le nouveau hachage racine.
  6. Prouvez que chaque événement est inclus. Lisez chaque événement Access Transparency que sert l'Activity Feed. Pour chaque nouvel événement, reconstruisez sa feuille, hachez-la et récupérez sa preuve d'inclusion. Parcourez le chemin d'audit depuis votre hachage de feuille à l'index de l'événement jusqu'au hachage racine du checkpoint. Une non-correspondance signifie que l'événement qui vous a été servi n'est pas l'événement que le journal a enregistré. La réponse de preuve peut porter un checkpoint différent de celui que vous détenez. Reliez-le à votre historique avec une preuve de cohérence avant de vérifier quoi que ce soit par rapport à lui.
  7. Revérifiez ce que vous avez vu auparavant. Chaque fois que vous relisez un événement, il doit être servi avec le même index et les mêmes octets de feuille que lorsque vous l'avez vérifié. Aucun événement ne peut perdre l'index qu'il avait, et tant que vous êtes inscrit, aucun événement ne peut nouvellement apparaître sans index. Les événements servis sans index lors de votre première exécution constituent votre historique antérieur au journal. Une exécution qui ne relit que les événements récents ne revérifie que ceux-ci. Pour revérifier les plus anciens, vérifiez à nouveau les copies que vous avez conservées (étape 8).
  8. Enregistrez le checkpoint que vous avez vérifié et un enregistrement de chaque événement que vous avez vérifié. Ils constituent votre preuve et votre point de départ pour la prochaine exécution.

Vérifier avec axt-verify

axt-verify est le vérificateur open source d'Anthropic pour ce journal. Il s'agit d'un binaire Go unique que vous exécutez sur votre propre infrastructure. Chaque version intègre exactement une clé de signature du journal issue de Empreintes de clés publiées, de sorte qu'il ne demande jamais à l'API à quelle clé faire confiance. Lorsqu'Anthropic effectue une rotation de la clé, vous passez à la version qui intègre la nouvelle clé à la date de bascule. axt-verify dérive votre origine de l'UUID d'organisation que vous transmettez avec --org, qui est celui que vous avez pris depuis la Console dans Avant de commencer. Il rejette tout checkpoint dont la ligne d'origine diffère.

Installez-le avec Go 1.26 ou une version plus récente. Il lit votre Compliance Access Key depuis la variable d'environnement ANTHROPIC_COMPLIANCE_ACCESS_KEY, jamais depuis un indicateur ou un fichier. La commande run est celle à planifier :

go install github.com/anthropics/axt-verify/cmd/axt-verify@latest

export ANTHROPIC_COMPLIANCE_ACCESS_KEY="<your Compliance Access Key>"
axt-verify --org 25f6429a-3293-49bf-afed-cb312911554b \
  --state /var/lib/axt-verify/25f6429a-3293-49bf-afed-cb312911554b.state \
  run

Chaque run récupère le dernier checkpoint et vérifie sa signature et sa ligne d'origine. Il prouve ensuite que le journal est une extension en ajout seul du checkpoint que l'exécution précédente a enregistré. Puis il parcourt page par page les événements Access Transparency de votre Activity Feed. Il commence sept jours (selon created_at) avant l'événement le plus récent que l'exécution précédente a lu, afin que les événements listés tardivement ou dans le désordre soient tout de même pris en compte. Il reconstruit la feuille de chaque événement, vérifie une preuve d'inclusion pour celle-ci et compare tout événement qu'il a vérifié auparavant avec ce qu'il avait alors enregistré. Enfin, il enregistre le nouveau checkpoint et sa progression dans le fichier --state, à partir duquel démarre l'exécution suivante. Exécutez-le au moins une fois par jour. Une fréquence horaire est raisonnable. Avec une clé d'organisation parente, exécutez une copie par organisation enfant, chacune avec son propre --org et son propre fichier --state. L'UUID de chaque organisation enfant provient également de la Claude Console, et non des réponses de la Compliance API que vous vérifiez. Vous le trouverez sur la page Settings > Organization de l'organisation enfant ou dans la liste des organisations de votre organisation parente dans la Console. axt-verify checkpoint n'effectue que les étapes de checkpoint et d'ajout seul. axt-verify events FILE vérifie les événements que vous détenez déjà, comme l'échantillon d'un auditeur ou votre propre export. Il prouve que chaque événement du fichier est toujours enregistré dans le journal sous le checkpoint actuel. Il ne lit pas le flux et ne touche pas au fichier d'état.

Une limite découle de cette fenêtre : run ne relit que les sept derniers jours d'événements, il ne revérifie donc que les événements récemment servis (étape 7), et non l'intégralité de votre historique. Conservez les événements que vous exportez (consultez Conserver votre propre archive de checkpoints). axt-verify events FILE prouve à toute date ultérieure que ces copies sont toujours enregistrées dans le journal, mais il ne relit pas le flux. Pour détecter un événement plus ancien supprimé du flux ou réécrit sur celui-ci, réexportez cette plage depuis l'Activity Feed et comparez-la avec les copies que vous avez conservées. Vous pouvez également vérifier le réexport lui-même avec axt-verify events FILE. Le chevauchement de sept jours est plus long que le délai de livraison de deux jours ouvrés du flux, de sorte qu'un événement arrivé tardivement tombe tout de même dans la fenêtre d'une exécution ultérieure. --overlap modifie la durée si nécessaire.

Si vous avez plutôt besoin de votre propre implémentation, suivez la liste de contrôle précédente avec une bibliothèque tlog-tiles qui prend en charge les clés de note ECDSA.

Interpréter le résultat

axt-verify affiche votre origine, la taille de l'arbre et le hachage racine du checkpoint qu'il a vérifié, la taille de l'arbre à partir de laquelle la vérification d'ajout seul a commencé, ainsi qu'un décompte des événements par résultat. Passez --json pour obtenir le même rapport sous la forme d'un objet JSON par ligne. Chaque événement a l'un des quatre résultats suivants :

  • Vérifié : la feuille reconstruite à partir de l'événement servi est enregistrée à l'index de l'événement dans le journal signé.
  • En attente : l'index de l'événement se situe au-delà du dernier checkpoint publié. C'est normal pendant un court laps de temps après l'apparition d'un événement. Dans run, axt-verify mémorise l'événement, le vérifie lors d'une exécution ultérieure une fois qu'un checkpoint le couvre, et le fait échouer si cela prend plus de 24 heures. events FILE n'a pas d'exécution ultérieure pour le régler, il attend donc jusqu'à une minute qu'un checkpoint couvrant soit publié. Si aucun n'arrive, il signale l'événement comme non encore couvert et se termine avec le code de sortie 3. Exécutez-le à nouveau plus tard. Si events FILE signale le même événement comme non encore couvert lors de deux exécutions espacées d'au moins un jour, traitez-le comme un échec de vérification et faites remonter le problème comme pour le code de sortie 1.
  • Non journalisé : l'événement a été servi sans index. Un événement est servi sans transparency_log_leaf_index uniquement tant que votre organisation n'est pas inscrite à Access Transparency, ou lorsqu'il a été enregistré avant la création du journal de votre organisation (voir Le champ transparency_log_leaf_index sur les événements de l'Activity Feed). axt-verify signale ces événements comme non journalisés et ne fait pas échouer l'exécution à cause d'eux. Un événement sans index n'est pas attendu lorsqu'il est daté d'après la création de votre journal et tombe dans une période pendant laquelle vous étiez inscrit. Examinez la liste des événements non journalisés dans le résumé de l'exécution ou dans la sortie --json plutôt que de vous fier uniquement au code de sortie.
  • Échec : voir le code de sortie 1.

Le code de sortie indique à votre planificateur ce qui s'est passé :

  • 0 : Rien n'a échoué. Les événements non journalisés sont signalés, pas mis en échec, tout comme les événements en attente dans run.

  • 1 : Un échec de vérification. Il s'agit d'une constatation de sécurité, et non d'une erreur transitoire. Conservez le fichier d'état et la sortie, et signalez-le à votre représentant de compte Anthropic ou au support Anthropic. Les causes sont :

    • Un checkpoint avec une mauvaise origine, ou une signature qui ne se vérifie pas avec la clé intégrée à votre version d'axt-verify. Comparez le key_hash sur la ligne de signature du checkpoint en échec avec les Empreintes de clés publiées. Une clé qui y figure avec une date de bascule pour laquelle vous n'avez pas effectué la mise à niveau signifie que vous avez besoin de la version correspondante. Une clé qui n'y figure pas constitue une constatation de sécurité, quelle que soit la version que vous exécutez. En cas d'échec de ce type, axt-verify affiche le hachage de clé de chaque signature sur le checkpoint servi ainsi que le hachage de la clé à laquelle il fait confiance, sous forme de huit chiffres hexadécimaux chacun. Cette sortie suffit pour effectuer la comparaison.
    • Un checkpoint qui n'est pas une note signée bien formée, par exemple un checkpoint dont le hachage racine ne fait pas 32 octets.
    • Un journal qui a rétréci, ou qui ne peut pas prouver qu'il prolonge le checkpoint que vous avez enregistré. La sortie contient alors les deux checkpoints et la preuve, de sorte que les éléments de preuve se suffisent à eux-mêmes.
    • Deux checkpoints signés pour la même taille d'arbre avec des hachages racine différents. La sortie contient les deux checkpoints.
    • Un fichier de checkpoint passé avec --from dont la signature ne se vérifie pas avec la clé intégrée à votre version d'axt-verify, ou un fichier --from ou --from-trusted dont l'origine n'est pas la vôtre. Pour une archive signée avant une rotation de clé, consultez Conserver votre propre archive de checkpoints.
    • Une preuve d'inclusion qui ne reproduit pas le hachage racine signé pour l'événement qui vous a été servi.
    • Un événement situé dans la fenêtre de l'exécution servi différemment de la manière dont une exécution antérieure l'a enregistré : octets de feuille différents, index différent, ou absence d'index là où il en avait un.
    • Un événement toujours en attente 24 heures après que l'exécution l'a vu pour la première fois.
    • Une preuve d'inclusion refusée (400, 401 ou 403) pour un événement que le flux vous a servi.
    • Une preuve d'inclusion renvoyée pour un leaf_index différent de celui demandé.
    • Dans events FILE, un événement à un index que le dernier checkpoint couvrait déjà au début de la vérification, pour lequel aucune preuve d'inclusion n'est servie avant la fin de l'attente.
    • Un événement dont l'organization_uuid n'est pas l'UUID d'organisation que vous avez passé avec --org. Lorsqu'une organisation parente exécute events FILE sur un export qui couvre plusieurs organisations enfants, chaque événement des autres organisations échoue de cette manière ; divisez donc d'abord l'export par organisation et vérifiez chaque partie avec son propre --org.
    • Le même id d'activité à deux index différents, ou deux fois au même index avec un contenu différent, au sein d'une même exécution ou d'une même entrée events FILE.
    • Un événement dont la feuille ne peut pas être reconstruite : par exemple, un champ documenté qui n'est pas une chaîne, un nom de champ qui apparaît deux fois, ou un type manquant ou constituant une variante non reconnue d'un type Access Transparency. events FILE ignore les lignes d'autres types d'activité et ne les fait pas échouer.
  • 2 : Une erreur d'utilisation ou de configuration. Les causes sont :

    • Un indicateur manquant ou mal formé.
    • Absence de ANTHROPIC_COMPLIANCE_ACCESS_KEY.
    • Une clé que l'API rejette (401 ou 403) avant qu'un checkpoint n'ait été vérifié.
    • Un fichier d'état qui ne peut pas être lu ou qui appartient à une autre origine.
  • 3 : L'exécution n'a pas pu se terminer. Dans run, ce qui avait déjà été vérifié est enregistré dans le fichier d'état. Exécutez à nouveau. Les causes sont :

    • Un événement dans events FILE dont l'index n'a été couvert par aucun checkpoint publié pendant l'attente. Pour un tel événement, le résultat En attente indique quand cesser de relancer et faire remonter le problème.
    • Des erreurs réseau, une limitation de débit ou des erreurs serveur qui ont persisté au-delà des nouvelles tentatives.
    • Une réponse inattendue.
    • Un fichier d'état ou --save qui n'a pas pu être écrit.

    Un code de sortie 3 avec des réponses 404 est attendu tant qu'Anthropic n'a pas enregistré un premier événement Access Transparency pour votre organisation, car chaque point de terminaison du journal de transparence renvoie 404 jusqu'à ce que cet événement crée le journal. Faites remonter le problème si les points de terminaison du journal de transparence renvoient toujours 404 plus de quelques jours après que votre Activity Feed a affiché pour la première fois un événement Access Transparency, que cet événement comporte ou non un transparency_log_leaf_index. Cette combinaison n'est pas attendue. Une fois qu'une exécution a réussi, faites remonter tout code de sortie 3 qui persiste.

Conserver votre propre archive de checkpoints

La preuve la plus solide que vous puissiez détenir est votre propre enregistrement de ce que le journal indiquait un jour donné. axt-verify --save FILE écrit textuellement le checkpoint qu'une exécution a vérifié, et --from FILE lors d'une exécution ultérieure oblige le journal à prouver qu'il prolonge toujours ce checkpoint. Archivez un checkpoint enregistré dans un stockage que vous contrôlez, par exemple quotidiennement. Des mois plus tard, une preuve de cohérence à partir de la taille d'arbre de ce checkpoint archivé doit toujours mener au checkpoint que le journal sert, faute de quoi la vérification échoue. Les clés antérieures restent répertoriées dans l'ensemble des clés de vérification après une rotation planifiée, de sorte qu'un checkpoint archivé continue de se vérifier. Avec axt-verify, si la clé qui a signé un checkpoint archivé a depuis été retirée par rotation, passez cette archive avec --from-trusted au lieu de --from. Conservez également les événements. Les événements Access Transparency que vous exportez depuis le flux constituent une entrée valide pour axt-verify events FILE, qui prouve à toute date ultérieure que ces copies sont toujours enregistrées dans le journal sous son checkpoint actuel. Comme events FILE ne relit pas le flux, votre export conservé est également la référence à laquelle vous comparez un réexport ultérieur de la même plage.

Questions fréquentes

Was this page helpful?