Verificar eventos de Access Transparency con el registro de transparencia
Usa checkpoints firmados y pruebas de Merkle de la Compliance API para verificar que ningún evento de Access Transparency se eliminó ni se alteró después de confirmarse en el registro.
Aprende a verificar criptográficamente que ningún evento de Access Transparency se eliminó ni se alteró después de confirmarse en el registro de transparencia de tu organización.
Cómo funciona el registro de transparencia
Un "transparency log" (registro de transparencia) es una técnica para que cualquier manipulación de un registro sea detectable. Las entradas solo se agregan al final. Cada vez que el registro crece, su operador firma una declaración breve, llamada "checkpoint" (punto de control), que se compromete con todas las entradas hasta ese momento mediante un hash de "Merkle tree" (árbol de Merkle). Cualquiera que conserve un checkpoint puede exigir más adelante una prueba de que el registro actual todavía contiene todo lo que ese checkpoint cubría, sin cambios y en el mismo orden. Por lo tanto, eliminar o reescribir una entrada no puede pasar desapercibido para un verificador que haya conservado un checkpoint que cubría esa entrada. Certificate Transparency y la base de datos de sumas de verificación de módulos de Go se basan en la misma técnica. C2SP tlog-tiles es una especificación abierta para servir un registro de este tipo como checkpoints firmados más "tiles" (teselas) estáticas y almacenables en caché de hashes y entradas, de modo que los clientes puedan obtener los hashes y calcular cada prueba por sí mismos.
Cuando Access Transparency está habilitado, Anthropic mantiene un registro de transparencia para tu organización. Es un registro de solo anexado y firmado criptográficamente de los eventos de Access Transparency (anthropic_access y cmek_preserve). Cada uno de estos eventos registrado para tu organización después de que se creó el registro se agrega a él. El registro sigue el formato C2SP tlog-tiles, por lo que las herramientas creadas para ese estándar entienden sus checkpoints, tiles y pruebas.
- Un registro por organización. El registro de cada organización tiene una cadena de origen fija:
axt.anthropic.com/<your organization UUID>. El origen nunca cambia durante la vida de la organización. - Cada evento nuevo se convierte en una hoja. Cuando un evento de Access Transparency pasa a ser elegible para aparecer en tu Activity Feed, primero se agrega a tu registro como una "leaf" (hoja), y solo entonces se sirve en el feed. Una hoja es una serialización determinista de los campos documentados del evento. El evento en tu feed incluye
transparency_log_leaf_index, su posición basada en cero en tu registro. - Los checkpoints se comprometen con todo el historial. El registro es un árbol de Merkle. Cada vez que crece, Anthropic publica un checkpoint firmado: un documento de texto breve que indica el origen del registro, su tamaño actual y el hash raíz que se compromete con cada hoja. Cada checkpoint lleva exactamente una firma de la clave de firma del registro.
- Se derivan dos pruebas. Una "inclusion proof" (prueba de inclusión) muestra que un evento específico está presente en su posición bajo un checkpoint. Una "consistency proof" (prueba de consistencia) muestra que un checkpoint posterior es una extensión de solo anexado de uno anterior que guardaste, por lo que nada entre ellos se eliminó ni se modificó.
- Las claves de verificación se sirven dentro de banda. El endpoint de claves del verificador devuelve las claves públicas que firman los checkpoints. En una rotación de claves planificada, la nueva clave se agrega a esa lista antes de empezar a firmar, y las claves anteriores permanecen en la lista. Por lo tanto, los checkpoints que ya tienes siguen verificándose.
Qué demuestra el registro de transparencia
- Los campos de hoja de un evento que tienes (enumerados en Cómo un evento se convierte en una hoja) son, byte por byte, lo que Anthropic confirmó en el registro.
- El registro de tu organización solo crece. La verificación contra un checkpoint que tienes falla si un evento confirmado en el registro se elimina o se reescribe allí más adelante. También falla si se te sirve un historial diferente del que se te sirvió antes.
- Las entradas nuevas solo se pueden agregar al final. No se puede insertar un evento en un historial que ya verificaste.
Qué no demuestra ni cambia
- No demuestra que cada acceso se haya registrado, ni que un evento registrado describa con precisión el acceso. Solo demuestra que lo que Anthropic confirmó en el registro no ha cambiado desde entonces.
- No cambia lo que cubre Access Transparency ni cuándo llegan los eventos.
- Los campos servidos fuera de la hoja, como
workspace_uuidy cualquier campo agregado más adelante, no están cubiertos por la prueba. - Una prueba de inclusión responde por un evento que se te sirvió. Por sí sola, no demuestra que el feed haya listado todas las hojas que contiene el registro. Los paquetes de entradas del registro contienen todas las hojas, por lo que puedes leer directamente el conjunto completo de eventos confirmados cuando lo necesites.
- La presencia de
transparency_log_leaf_indexen un evento es un puntero, no una prueba. Verifica siempre la inclusión antes de tratar un evento como confirmado en el registro. - La protección contra un historial reescrito proviene de los checkpoints que conservas. La firma de un checkpoint con una clave listada en Huellas digitales de claves publicadas demuestra que proviene del registro de Anthropic. Una prueba de consistencia desde el checkpoint que guardaste la última vez demuestra que el historial que ya observaste solo creció.
Antes de comenzar
Necesitas:
- Una Compliance Access Key con el alcance
read:compliance_activities, la misma clave y el mismo alcance que usas para el Activity Feed. Una clave de organización principal puede leer el registro de cada organización secundaria inscrita indicando la organización secundaria en cada solicitud. - El UUID de tu organización. Encuéntralo en la Claude Console en Settings > Organization. Es el mismo valor que el Activity Feed sirve como
organization_uuid, pero tómalo de la Console. Este valor es lo que hace que un checkpoint sea tuyo, por lo que no debe provenir de la API que estás verificando. A partir de él derivas el origen de tu registro comoaxt.anthropic.com/<organization UUID>. Deriva esta cadena tú mismo. No la leas de una respuesta de la API. - Un lugar duradero donde guardar el último checkpoint que verificaste. Ese checkpoint guardado es lo que convierte "el registro es consistente hoy" en "el registro ha sido consistente desde que empezaste a observarlo".
Tiempos
- Eventos: Los eventos de Access Transparency aparecen en tu Activity Feed dentro de los dos días hábiles posteriores al acceso. Un evento entra en el registro solo cuando es elegible para servirse, por lo que el registro nunca revela un evento antes de tiempo. Como el registro se escribe antes de que el feed sirva el evento, una entrada puede aparecer brevemente en el registro antes de que su evento aparezca en tu feed. Esa diferencia no es una discrepancia.
- Checkpoints: Se publica un nuevo checkpoint cada vez que tu registro crece.
- Pruebas de inclusión: Una prueba para un evento recién servido está disponible una vez que se publica un checkpoint que cubre la posición del evento, normalmente muy poco después de que aparece el evento. Si solicitas una antes, recibes un
404y vuelves a intentarlo tras una breve espera. - Frecuencia de verificación: Ejecuta tu verificación al menos una vez al día. Cada hora es razonable.
- Cancelación de la inscripción: Si tu organización deja de usar Access Transparency, no se elimina nada. Tu registro sigue siendo legible a través de los mismos endpoints. Si Access Transparency se vuelve a habilitar más adelante, continúa el mismo registro.
Retención y eliminación
- Registro de transparencia: Anthropic no elimina entradas de tu registro, y el registro no tiene vencimiento. Se conserva si tu organización deja de usar Access Transparency y después de que se elimine tu organización, porque eliminar entradas es precisamente el cambio que el registro existe para detectar. Los paquetes de entradas contienen los campos de hoja de cada evento, por lo que esos campos se conservan mientras se conserve el registro.
- Activity Feed: Los eventos de Access Transparency en el Activity Feed siguen la retención del feed. Las actividades se conservan durante 6 años. Consulta Consultar el Activity Feed.
- Sin eliminación por tu parte: Los endpoints del registro de transparencia son de solo lectura. No hay forma de eliminar ni modificar una entrada.
Endpoints del registro de transparencia
Se sirven seis endpoints de solo lectura bajo https://api.anthropic.com/v1/compliance/transparency_log/:
| Endpoint | Devuelve |
|---|---|
GET /checkpoint | El checkpoint firmado más reciente |
GET /keys | El conjunto de claves del verificador |
GET /inclusion | Una prueba de inclusión para un evento |
GET /consistency | Una prueba de consistencia desde un checkpoint que tienes hasta el más reciente |
GET /tile/{level}/{index} | Una tile de hashes de Merkle |
GET /tile/entries/{index} | Un paquete de entradas con bytes de hojas |
Los checkpoints, las tiles y los paquetes de entradas siguen exactamente el formato de transmisión de C2SP tlog-tiles. Los dos endpoints de pruebas son una comodidad: cada prueba también se puede calcular a partir de las tiles, por lo que nunca tienes que confiar en la salida de un endpoint de pruebas. Verificas los hashes que devuelve contra un checkpoint firmado.
Autenticación y alcance
Envía tu Compliance Access Key en el encabezado x-api-key y el encabezado anthropic-version, como en toda solicitud a la Compliance API (consulta Control de versiones). La Compliance API debe estar habilitada para tu organización.
No existe un permiso separado para el registro de transparencia. Cualquier clave que pueda leer el Activity Feed de tu organización, ya sea de tu organización o de su organización principal, puede leer todo tu registro, incluidos los campos de eventos en sus paquetes de entradas.
Cada solicitud lee exactamente el registro de una organización:
- Una clave de nivel de organización lee el registro de su propia organización. El parámetro de consulta
organization_ides opcional. Si está presente, debe indicar la propia organización de la clave. - Una clave de nivel de organización principal debe pasar
organization_id, indicando una organización secundaria. organization_idacepta el ID etiquetadoorg_...o el UUID de la organización.
Un 404 significa que no hay ningún registro que esta clave pueda leer. Una organización fuera del alcance de la clave, una organización inexistente y una organización cuyo registro aún no se ha creado son deliberadamente indistinguibles. El registro de una organización que desde entonces dejó de usar Access Transparency no es este caso: se sigue sirviendo.
Errores
Los errores usan el sobre de error JSON estándar de la Compliance API en todos los endpoints, incluidos los de texto y binarios. Consulta Errores para ver el sobre y los tipos de error compartidos.
| Estado | Significado en esta superficie |
|---|---|
400 | organization_id tiene un formato incorrecto o se omite con una clave de organización principal, la Compliance API no está habilitada, un parámetro de consulta es desconocido o falló una validación específica del endpoint |
401 | La clave de API falta o no es válida |
403 | La clave no tiene el alcance requerido |
404 | No hay ningún registro legible por esta clave, o los casos específicos del endpoint de "no cubierto" y "más allá del árbol" |
429 | Límite de velocidad alcanzado. Estos endpoints comparten el límite de velocidad por organización principal de la Compliance API. Respeta retry-after |
503 | El registro no está disponible temporalmente. Vuelve a intentarlo con retroceso |
Almacenamiento en caché
Las respuestas solo pueden almacenarse en caché por el cliente que realiza la solicitud. Cache-Control siempre incluye private, y las respuestas llevan Vary: x-api-key. No coloques una caché compartida delante de estos endpoints. Las tiles completas y los paquetes de entradas completos nunca cambian y se sirven con Cache-Control: private, max-age=604800, immutable. Todo lo demás, incluidos checkpoints, pruebas, claves, tiles parciales y errores, se sirve con Cache-Control: private, no-store.
Lee el checkpoint más reciente
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 respuesta es text/plain: una nota firmada de C2SP. Las líneas del cuerpo son el origen, el tamaño del árbol en decimal y el hash raíz en base64. Sigue una línea en blanco y luego la línea de firma, que comienza con una raya (U+2014), indica el origen y termina con un valor en base64. Los valores aquí son ilustrativos:
axt.anthropic.com/25f6429a-3293-49bf-afed-cb312911554b
1207
C6C4HzGRqDNlbu54LWCvpDX0NcB5DRTmLcjM4u5vWUI=
— axt.anthropic.com/25f6429a-3293-49bf-afed-cb312911554b q83vATBFAiEAvL8m…(base64)…- Los primeros cuatro bytes del valor de firma decodificado son el
key_hashde la clave de firma, que te indica con qué entrada del conjunto de claves del verificador debes verificar. Los bytes restantes son una firma ECDSA P-256 en ASN.1 DER sobre el SHA-256 del cuerpo de la nota: todos los bytes antes de la línea en blanco, incluido el salto de línea final del cuerpo. - Un checkpoint puede llevar líneas adicionales después del hash raíz. Ignora las líneas que no entiendas. Están cubiertas por la firma.
- Ignora una línea de firma cuyo nombre no sea tu origen o cuyo hash de clave no tengas.
- Nunca almacenes en caché un checkpoint. Uno obsoleto oculta el tamaño actual del registro, por lo que los eventos recién servidos parecen no estar cubiertos.
Lee las claves del verificador
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>"
}
]
}| Campo | Tipo | Descripción |
|---|---|---|
type | string | Siempre transparency_log_keys |
origin | string | La línea de origen que lleva cada checkpoint de este registro. Informativo: compara los checkpoints con el origen que derivas tú mismo, no con este campo |
log_keys | array | Primero la clave que firma los nuevos checkpoints, luego todas las demás claves que sirve el registro, de la más reciente a la más antigua. Nunca está vacío |
log_keys[].verifier_key | string | La clave como cadena note-verifier de C2SP, <origin>+<key_hash>+<base64 key>, aceptada por las herramientas de tlog-tiles que admiten claves de nota ECDSA (por ejemplo, el módulo de Go github.com/transparency-dev/formats). La parte en base64 se decodifica como el byte de algoritmo 0x02 seguido de la clave pública codificada en DER |
log_keys[].key_hash | string | Ocho dígitos hexadecimales en minúsculas. El selector de 4 bytes que asocia esta clave con la línea de firma de un checkpoint. Son los primeros cuatro bytes de fingerprint y no es una identidad |
log_keys[].fingerprint | string | 64 dígitos hexadecimales en minúsculas: el SHA-256 del SubjectPublicKeyInfo en DER |
log_keys[].algorithm | string | El tipo de clave, actualmente ecdsa_p256_sha256. Se pueden agregar valores. Omite una clave cuyo algoritmo no admitas |
log_keys[].public_key | string | La clave pública como SubjectPublicKeyInfo en DER codificado en base64 |
El key_hash cubre solo los bytes de la clave: son los primeros cuatro bytes del SHA-256 sobre el SubjectPublicKeyInfo en DER, que es la regla que usa la codificación note-verifier de ECDSA. No es el ID de clave dependiente del nombre que el formato base de nota firmada define para las claves Ed25519, por lo que no cambia con el origen. Una firma válida con una clave listada en Huellas digitales de claves publicadas demuestra que el checkpoint proviene del servicio de registro de transparencia de Anthropic. La línea de origen dentro del checkpoint firmado es lo que lo vincula a tu organización. Por eso comparas esa línea con el origen que derivas tú mismo.
Las claves pueden rotar:
- Una rotación es un cambio puntual. A partir de cierto checkpoint, los nuevos checkpoints se firman con la nueva clave.
- En una rotación planificada, la nueva clave aparece en
log_keysantes de firmar nada, y las claves anteriores permanecen en la lista. Por lo tanto, un checkpoint que guardaste antes de la rotación sigue verificándose. - Un verificador puede obtener el conjunto de claves en cada ejecución o conservarlo localmente. Un verificador que lo conserva localmente vuelve a leer este endpoint cuando encuentra una firma cuyo
key_hashno tiene.
Huellas digitales de claves publicadas
Anthropic publica aquí, fuera de la API, la huella digital de cada clave que firma checkpoints. Esto te permite comprobar una clave que conservas localmente contra una fuente que la ruta de servicio no puede alterar. La clave que conservas puede provenir de una respuesta anterior de GET /keys o de herramientas que fijan la clave.
| Hash de clave | Huella digital SHA-256 | Algoritmo | Firmando desde | Estado |
|---|---|---|---|---|
1dff5fe4 | 1dff5fe420d49743fe444a04fc17f818eea856699dec2ebbc24df15602c74a58 | ecdsa_p256_sha256 | 2026-08-17 | Clave de firma actual |
Una rotación planificada se anuncia en esta página al menos 30 días antes de que la nueva clave firme su primer checkpoint. Durante ese período de aviso, la nueva clave aparece en log_keys y en esta tabla con su fecha de cambio. Las claves retiradas permanecen en la lista con sus fechas de servicio. Una clave que no aparece en esta tabla no es legítima, independientemente de lo que devuelva GET /keys. Trata un checkpoint que no se verifica con ninguna clave listada como un fallo de verificación, e infórmalo a tu representante de cuenta de Anthropic o al soporte de Anthropic.
axt-verify incluye la clave actual en cada versión y nunca lee una clave de la API. Cada versión incluye exactamente una clave. En la fecha de cambio, Anthropic empieza a firmar con la nueva clave y publica la versión de axt-verify que la incluye. En esa misma fecha, Anthropic vuelve a emitir el checkpoint más reciente de cada organización con la nueva clave, incluso para un registro que no ha crecido. Actualiza en la fecha de cambio. Ejecutar la versión anterior después del cambio falla con el estado de salida 1, y lo mismo ocurre al ejecutar la nueva versión antes del cambio. Cualquiera de los dos fallos desaparece una vez que ejecutas la versión correspondiente. Un verificador que mantengas tú mismo necesita que se agregue la nueva huella digital, con su fecha de cambio, antes de esa fecha.
Obtén una prueba de inclusión
GET /v1/compliance/transparency_log/inclusion?leaf_index={index}
| Parámetro | Tipo | Descripción |
|---|---|---|
leaf_index | integer, obligatorio | La posición del evento en el registro: el transparency_log_leaf_index que el Activity Feed sirvió en el evento. Debe ser cero o mayor |
organization_id | string, opcional | Consulta Autenticación y alcance |
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"
}| Campo | Tipo | Descripción |
|---|---|---|
type | string | Siempre transparency_log_inclusion_proof |
leaf_index | integer | La posición del evento en el registro, repetida de la solicitud |
hashes | array de strings | Los hashes hermanos en base64 de la ruta de auditoría, ordenados desde la hoja hasta la raíz |
checkpoint | string | El checkpoint firmado más reciente, contra el que se verifica la prueba. Incluye el tamaño del árbol |
No hay búsqueda por ID de actividad. Siempre tienes el índice, porque llega con el evento, y compruebas la prueba contra los bytes del evento que obtuviste del feed.
Un 404 significa que el checkpoint publicado más reciente no cubre la posición proporcionada:
- Para un índice que leíste de un evento servido, esto es transitorio. En breve se publica un checkpoint que lo cubre, así que vuelve a intentarlo tras una breve espera.
- El mismo
404responde a cualquier otra posición no cubierta, como un índice que el feed nunca sirvió. Para una posición así, no hay garantía de que alguna vez se publique un checkpoint que la cubra. La respuesta no indica en qué caso te encuentras.
Un leaf_index que falta o que no es un entero no negativo devuelve 400.
Obtén una prueba de consistencia
GET /v1/compliance/transparency_log/consistency?from={size}
| Parámetro | Tipo | Descripción |
|---|---|---|
from | integer, obligatorio | El tamaño del árbol del checkpoint anterior que tienes. Debe ser al menos 1 y como máximo el tamaño del árbol del checkpoint más reciente |
organization_id | string, opcional | Consulta Autenticación y alcance |
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"
}| Campo | Tipo | Descripción |
|---|---|---|
type | string | Siempre transparency_log_consistency_proof |
hashes | array de strings | Los hashes de la prueba en base64, en el orden de RFC 9162 |
checkpoint | string | El checkpoint firmado más reciente, hasta el que se extiende la prueba. Incluye el tamaño del árbol |
- La prueba siempre se extiende hasta el checkpoint publicado más reciente. Esta API nunca sirve checkpoints históricos: tú conservas los que se te sirven.
- Un
fromigual al tamaño del árbol del checkpoint más reciente devuelve la prueba vacía. - Un checkpoint conservado con tamaño de árbol 0 no necesita prueba de consistencia, porque todo registro extiende el registro vacío. En ese caso, adopta directamente el checkpoint más reciente.
- Un
frommenor que 1, o mayor que el tamaño del árbol del checkpoint más reciente, devuelve400. - Si el registro ya no puede demostrar que extiende un checkpoint que alguna vez firmó para ti, trátalo como un fallo de verificación, no como un error de uso.
Lee una tile de hashes
GET /v1/compliance/transparency_log/tile/{level}/{index}
Devuelve application/octet-stream: hashes SHA-256 de 32 bytes concatenados, según tlog-tiles. El direccionamiento de tiles sigue exactamente tlog-tiles, incluida la gramática de ruta {level} e {index}, la forma de índice x001/234 para árboles grandes y el sufijo de tile parcial .p/{width}. Las tiles de hashes son la unidad a partir de la cual los clientes de tlog-tiles calculan las pruebas por sí mismos.
- Las tiles completas son inmutables y se sirven con
Cache-Control: private, max-age=604800, immutable. - Las tiles parciales quedan reemplazadas a medida que crece el árbol y se sirven con
Cache-Control: private, no-store. Una vez que una tile se llena, una solicitud de su forma parcial anterior puede devolver404aunque exista la tile completa. Recurrir a la tile completa en lugar de la parcial es tarea del cliente, como especifica tlog-tiles, y los clientes estándar ya lo hacen. - Un
level,indexo ancho de tile parcial con formato incorrecto devuelve400. Una posición de tile más allá del tamaño actual del árbol devuelve404.
Lee un paquete de entradas
GET /v1/compliance/transparency_log/tile/entries/{index}
Devuelve application/octet-stream: entradas de hoja consecutivas, cada una precedida por su longitud uint16 en big-endian, según tlog-tiles. Los "entry bundles" (paquetes de entradas) contienen el texto sin cifrar de los eventos: los bytes canónicos de cada evento de Access Transparency. Por eso toda la superficie requiere el alcance del Activity Feed. El direccionamiento, la forma parcial, el almacenamiento en caché y los errores son idénticos a los de las tiles de hashes.
El campo transparency_log_leaf_index en los eventos del Activity Feed
Los eventos anthropic_access y cmek_preserve en GET /v1/compliance/activities incluyen transparency_log_leaf_index, un entero, siempre que el evento tenga una hoja. Los demás tipos de actividad nunca lo incluyen.
- La clave está ausente, no es
null, cuando el evento no tiene hoja. Un verificador robusto trata una clave ausente y un valornullde la misma manera. - Un evento se sirve sin
transparency_log_leaf_indexsolo en dos casos. El primero es mientras tu organización no está inscrita en Access Transparency, es decir, antes de la inscripción o entre una cancelación de la inscripción y una nueva inscripción. El segundo es cuando el evento se registró antes de que se creara el registro de tu organización. Para una organización inscrita antes de que se introdujera el registro de transparencia, eso incluye su historial anterior. Una vez que tu registro existe y mientras estés inscrito, cada evento se agrega al registro antes de que el feed lo sirva. Si un fallo impide que el feed conozca el índice, el feed retrasa el evento en lugar de servirlo sin él. El evento no se pierde: ya está en el registro y aparece en el feed, con el índice incluido, una vez que se corrige el fallo. No se espera un evento sin índice cuando tiene fecha posterior a la creación de tu registro y cae dentro de un período en el que estabas inscrito. - Un índice presente es un puntero, no una prueba. Verifica la inclusión antes de tratar el evento como confirmado en el registro. La anomalía que vale la pena escalar es un índice presente cuya prueba de inclusión todavía no se puede obtener mucho después de que debería haberse publicado un checkpoint que lo cubra.
- El índice se asigna cuando el evento se agrega al registro y no es uno de los campos que componen la hoja.
Cómo un evento se convierte en una hoja
Una entrada de hoja es el byte de versión de esquema 0x01 seguido del JSON canónico de 11 campos. El JSON sigue RFC 8785 (JSON Canonicalization Scheme), y los campos se toman del evento exactamente como lo sirve el Activity Feed:
id,type,created_at,accessed_at,organization_id,organization_uuid,workspace_id,accessor_departmentyreason_codeactor, con sus campos anidadostypeyemail_addressresource_details, con sus campos anidadostype,idyparent
Las reglas:
- Los campos servidos fuera de ese conjunto, como
workspace_uuidy el propiotransparency_log_leaf_index, se ignoran. - Un campo documentado que el evento servido omite entra en la hoja como
null. Una cadena vacía es distinta denull. actoryresource_detailsson objetos con exactamente sus claves documentadas cuando el evento servido los incluye. En la versión0x01,actor.email_addressyresource_details.parentson siemprenull. Cuando el evento servido omite uno de estos objetos o lo sirve comonull, el valor completo esnullen la hoja, no un objeto con camposnull. Muchos eventos de acceso no incluyenresource_details.- Los valores de cadena, incluidas ambas marcas de tiempo y
reason_code, se toman byte por byte tal como se sirven. Si vuelves a derivar una marca de tiempo a partir de otra representación, reproduce exactamente la representación servida:- RFC 3339 en UTC con sufijo
Z. created_atno tiene dígitos fraccionarios cuando sus microsegundos son cero, y exactamente seis en caso contrario.accessed_attiene cero, tres, seis o nueve dígitos fraccionarios, la cantidad más corta que conserva exactamente sus nanosegundos.
- RFC 3339 en UTC con sufijo
- JSON canónico significa claves de objeto ordenadas, sin espacios en blanco no significativos y con escape mínimo de cadenas. No aparecen números en ninguna parte de la hoja.
- El hash de hoja es el
SHA-256(0x00 || entry)de RFC 6962. Los nodos internos se calculan comoSHA-256(0x01 || left || right). - Un verificador rechaza un byte de versión desconocido y una hoja
0x01cuyotypeno sea uno de los dos tipos de Access Transparency. Los nuevos tipos de eventos o cambios de reglas se publican con un nuevo byte de versión. Las hojas existentes nunca se vuelven a calcular.
Por ejemplo, este evento de acceso tal como lo sirve el Activity Feed:
{
"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
}se convierte en este JSON canónico. Tiene exactamente las 11 claves documentadas, ordenadas, en una sola línea. workspace_uuid y transparency_log_leaf_index se descartan, y resource_details.parent, ausente del evento servido, entra como 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"}La entrada de hoja es el byte 0x01 seguido de esos bytes UTF-8. Su hash de hoja, SHA-256(0x00 || entry), es 6ro7vTcFq+sYDZiiGvZaFetUIoMSLig3DGDrCKK1HFU= en base64. Usa este ejemplo como vector de prueba para tu propio código de canonicalización.
Verifica tu registro
La verificación se ejecuta en tu propia infraestructura. Todo lo que devuelve la API no es de confianza hasta que se verifica contra dos cosas que tú mismo conservas. La primera es el origen que derivas del UUID de tu organización. La segunda es el checkpoint que guardaste en tu última ejecución. Una ejecución de verificación completa hace lo siguiente, en orden:
- Obtén el conjunto de claves del verificador. Calcula tú mismo la huella digital de cada clave como el SHA-256 de su
public_keydecodificado de base64. Conserva solo las claves cuya huella digital aparece en Huellas digitales de claves publicadas, junto con el estado de cada clave allí. Verifica un checkpoint recién obtenido solo con una clave que esa tabla indique como actual en esa fecha. Acepta una clave retirada solo para un checkpoint que guardaste antes de su fecha de retiro. - Establece el checkpoint más reciente. En la primera ejecución, obtenlo del endpoint de checkpoint. En cada ejecución posterior, solicita una prueba de consistencia desde el tamaño de árbol que guardaste. La respuesta incluye el checkpoint más reciente junto con la prueba.
- Comprueba primero la línea de origen del checkpoint. Compara su primera línea, byte por byte, con el origen que derivaste. Rechaza cualquier checkpoint cuyo origen sea diferente, antes de hacer cualquier otra cosa.
- Verifica la firma del checkpoint. Busca la línea de firma con el nombre de tu origen cuyos primeros cuatro bytes decodificados sean iguales al
key_hashde una clave actualmente válida que conservaste. Verifica los bytes restantes como una firma ECDSA P-256 sobre el SHA-256 del cuerpo de la nota, usando lapublic_keyde esa clave. Si ninguna línea de firma coincide con una clave así, o la firma no se verifica, rechaza el checkpoint. - Demuestra que es de solo anexado. Si el nuevo tamaño del árbol es menor que el que guardaste, falla. Si es igual, los hashes raíz deben coincidir. Si es mayor, verifica la prueba de consistencia de RFC 9162 desde tu tamaño y hash raíz guardados hasta el nuevo tamaño y hash raíz.
- Demuestra que cada evento está incluido. Lee todos los eventos de Access Transparency que sirve el Activity Feed. Para cada uno nuevo, reconstruye su hoja, calcula su hash y obtén su prueba de inclusión. Recorre la ruta de auditoría desde tu hash de hoja en el índice del evento hasta el hash raíz del checkpoint. Una discrepancia significa que el evento que se te sirvió no es el evento que el registro confirmó. La respuesta de la prueba puede incluir un checkpoint diferente del que tienes. Vincúlalo a tu historial con una prueba de consistencia antes de verificar nada contra él.
- Vuelve a comprobar lo que viste antes. Cada vez que vuelvas a leer un evento, debe servirse con el mismo índice y los mismos bytes de hoja que cuando lo verificaste. Ningún evento puede perder el índice que tenía y, mientras estés inscrito, ningún evento puede aparecer de nuevo sin uno. Los eventos servidos sin índice en tu primera ejecución son tu historial previo al registro. Una ejecución que vuelve a leer solo los eventos recientes vuelve a comprobar solo esos. Para volver a comprobar los más antiguos, verifica de nuevo las copias que conservaste (paso 8).
- Guarda el checkpoint que verificaste y una constancia de cada evento que verificaste. Son tu evidencia y tu punto de partida para la siguiente ejecución.
Verifica con axt-verify
axt-verify es el verificador de código abierto de Anthropic para este registro. Es un único binario de Go que ejecutas en tu propia infraestructura. Cada versión tiene integrada exactamente una clave de firma del registro de Huellas digitales de claves publicadas, por lo que nunca le pregunta a la API en qué clave confiar. Cuando Anthropic rota la clave, actualizas a la versión que incluye la nueva en la fecha de cambio. axt-verify deriva tu origen del UUID de organización que pasas con --org, que es el que tomaste de la Console en Antes de comenzar. Rechaza cualquier checkpoint cuya línea de origen sea diferente.
Instálalo con Go 1.26 o posterior. Lee tu Compliance Access Key de la variable de entorno ANTHROPIC_COMPLIANCE_ACCESS_KEY, nunca de una opción ni de un archivo. El comando run es el que debes programar:
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 \
runCada run obtiene el checkpoint más reciente y verifica su firma y su línea de origen. Luego demuestra que el registro es una extensión de solo anexado del checkpoint que guardó la ejecución anterior. A continuación, recorre página por página los eventos de Access Transparency en tu Activity Feed. Comienza siete días (según created_at) antes del evento más reciente que leyó la ejecución anterior, de modo que los eventos listados tarde o fuera de orden se sigan recogiendo. Reconstruye la hoja de cada evento, verifica una prueba de inclusión para ella y compara cualquier evento que haya verificado antes con lo que registró entonces. Por último, guarda el nuevo checkpoint y su progreso en el archivo --state, desde el que comienza la siguiente ejecución. Ejecútalo al menos una vez al día. Cada hora es razonable. Con una clave de organización principal, ejecuta una copia por cada organización secundaria, cada una con su propio --org y su propio archivo --state. El UUID de cada organización secundaria también proviene de la Claude Console, no de las respuestas de la Compliance API que estás verificando. Encuéntralo en la página Settings > Organization de la organización secundaria o en la lista de organizaciones de tu organización principal en la Console. axt-verify checkpoint realiza solo los pasos del checkpoint y de solo anexado. axt-verify events FILE verifica eventos que ya tienes, como una muestra de un auditor o tu propia exportación. Demuestra que cada evento del archivo sigue confirmado en el registro bajo el checkpoint actual. No lee el feed ni modifica el archivo de estado.
De esa ventana se deriva un límite: run vuelve a leer solo los últimos siete días de eventos, por lo que vuelve a comprobar los eventos servidos recientemente (paso 7), no todo tu historial. Conserva los eventos que exportas (consulta Mantén tu propio archivo de checkpoints). axt-verify events FILE demuestra en cualquier fecha posterior que esas copias siguen confirmadas en el registro, pero no vuelve a leer el feed. Para detectar un evento más antiguo eliminado o reescrito en el feed, vuelve a exportar ese rango desde el Activity Feed y compáralo con las copias que conservaste. También puedes verificar la propia reexportación con axt-verify events FILE. La superposición de siete días es más larga que el tiempo de entrega de dos días hábiles del feed, por lo que un evento que llega tarde sigue cayendo dentro de la ventana de una ejecución posterior. --overlap cambia la duración si lo necesitas.
Si en cambio necesitas tu propia implementación, sigue la lista de comprobación anterior con una biblioteca de tlog-tiles que admita claves de nota ECDSA.
Interpreta el resultado
axt-verify imprime tu origen, el tamaño del árbol y el hash raíz del checkpoint que verificó, el tamaño del árbol desde el que comenzó la comprobación de solo anexado, y un recuento de eventos por resultado. Pasa --json para obtener el mismo informe como un objeto JSON por línea. Cada evento tiene uno de cuatro resultados:
- Verificado: la hoja reconstruida a partir del evento servido está confirmada en el índice del evento en el registro firmado.
- Pendiente: el índice del evento está más allá del último checkpoint publicado. Esto es normal durante un breve tiempo después de que aparece un evento. En
run,axt-verifyrecuerda el evento, lo verifica en una ejecución posterior una vez que un checkpoint lo cubre, y lo marca como fallido si eso tarda más de 24 horas.events FILEno tiene una ejecución posterior para resolverlo, así que espera hasta un minuto a que se publique un checkpoint que lo cubra. Si no llega ninguno, informa el evento como aún no cubierto y termina con el estado de salida3. Vuelve a ejecutarlo más tarde. Sievents FILEinforma el mismo evento como aún no cubierto en dos ejecuciones separadas por al menos un día, trátalo como un fallo de verificación y escálalo como en el caso del estado de salida1. - No registrado: el evento se sirvió sin un índice. Un evento se sirve sin
transparency_log_leaf_indexsolo mientras tu organización no está inscrita en Access Transparency, o cuando se registró antes de que se creara el registro de tu organización (consulta El campotransparency_log_leaf_indexen los eventos del Activity Feed).axt-verifyinforma esos eventos como no registrados y no hace fallar la ejecución por ellos. No se espera un evento sin índice cuando tiene fecha posterior a la creación de tu registro y cae dentro de un período en el que estabas inscrito. Revisa la lista de eventos no registrados en el resumen de la ejecución o en la salida--jsonen lugar de depender solo del estado de salida. - Fallido: consulta el estado de salida
1.
El estado de salida le indica a tu programador de tareas lo que ocurrió:
-
0: Nada falló. Los eventos no registrados se informan, no se marcan como fallidos, y lo mismo ocurre con los eventos pendientes enrun. -
1: Un fallo de verificación. Este es un hallazgo de seguridad, no un error transitorio. Conserva el archivo de estado y la salida, e infórmalo a tu representante de cuenta de Anthropic o al soporte de Anthropic. Las causas son:- Un checkpoint con el origen incorrecto, o una firma que no se verifica con la clave incorporada en tu versión de
axt-verify. Compara elkey_hashen la línea de firma del checkpoint fallido con las Huellas digitales de claves publicadas. Una clave listada allí con una fecha de cambio para la que no has actualizado significa que necesitas la versión correspondiente. Una clave que no aparece allí es un hallazgo de seguridad, sin importar qué versión ejecutes. Ante este fallo,axt-verifyimprime el hash de clave de cada firma en el checkpoint servido y el hash de clave de la clave en la que confía, cada uno como ocho dígitos hexadecimales. Esa salida es suficiente para hacer la comparación. - Un checkpoint que no es una nota firmada bien formada, por ejemplo, uno cuyo hash raíz no tiene 32 bytes.
- Un registro que se redujo, o que no puede demostrar que extiende el checkpoint que guardaste. En ese caso, la salida incluye ambos checkpoints y la prueba, de modo que la evidencia se sostiene por sí sola.
- Dos checkpoints firmados para el mismo tamaño de árbol con hashes raíz diferentes. La salida incluye ambos checkpoints.
- Un archivo de checkpoint pasado con
--fromcuya firma no se verifica con la clave incorporada en tu versión deaxt-verify, o un archivo--fromo--from-trustedcuyo origen no es el tuyo. Para un archivo firmado antes de una rotación de clave, consulta Mantén tu propio archivo de checkpoints. - Una prueba de inclusión que no reproduce el hash raíz firmado para el evento que se te sirvió.
- Un evento dentro de la ventana de la ejecución servido de forma diferente a como lo registró una ejecución anterior: bytes de hoja diferentes, un índice diferente, o sin índice cuando antes tenía uno.
- Un evento que sigue pendiente 24 horas después de que la ejecución lo vio por primera vez.
- Una prueba de inclusión rechazada (
400,401o403) para un evento que el feed te sirvió. - Una prueba de inclusión devuelta para un
leaf_indexdiferente del solicitado. - En
events FILE, un evento en un índice que el último checkpoint ya cubría cuando comenzó la comprobación, para el cual no se sirve ninguna prueba de inclusión antes de que se agote la espera. - Un evento cuyo
organization_uuidno es el UUID de organización que pasaste con--org. Cuando una organización principal ejecutaevents FILEsobre una exportación que abarca varias organizaciones secundarias, el evento de cada una de las demás organizaciones falla de esta manera, así que primero divide la exportación por organización y verifica cada parte con su propio--org. - El mismo
idde actividad en dos índices diferentes, o dos veces en un mismo índice con contenido diferente, dentro de una ejecución o de una entrada deevents FILE. - Un evento cuya hoja no se puede reconstruir: por ejemplo, un campo documentado que no es una cadena, un nombre de campo que aparece dos veces, o un
typeque falta o es una variante no reconocida de un tipo de Access Transparency.events FILEomite las filas de otros tipos de actividad y no las marca como fallidas.
- Un checkpoint con el origen incorrecto, o una firma que no se verifica con la clave incorporada en tu versión de
-
2: Un error de uso o de configuración. Las causas son:- Una opción faltante o mal formada.
- No hay
ANTHROPIC_COMPLIANCE_ACCESS_KEY. - Una clave que la API rechaza (
401o403) antes de que se haya verificado algún checkpoint. - Un archivo de estado que no se puede leer o que pertenece a otro origen.
-
3: La ejecución no pudo completarse. Enrun, lo que ya se había verificado se guarda en el archivo de estado. Vuelve a ejecutarlo. Las causas son:- Un evento en
events FILEcuyo índice no fue cubierto por ningún checkpoint publicado dentro de la espera. Para un evento así, el resultado Pendiente indica cuándo dejar de volver a ejecutar y escalar. - Errores de red, limitación de velocidad o errores del servidor que persistieron más allá de los reintentos.
- Una respuesta inesperada.
- Un archivo de estado o de
--saveque no se pudo escribir.
Un estado de salida
3con respuestas404es esperable hasta que Anthropic haya registrado un primer evento de Access Transparency para tu organización, porque todos los endpoints del registro de transparencia devuelven404hasta que ese evento crea el registro. Escala el caso si los endpoints del registro de transparencia siguen devolviendo404más de unos pocos días después de que tu Activity Feed muestre por primera vez un evento de Access Transparency, tenga o no ese evento untransparency_log_leaf_index. Esa combinación no es esperable. Una vez que una ejecución haya tenido éxito, escala un estado de salida3que persista. - Un evento en
Mantén tu propio archivo de checkpoints
La evidencia más sólida que puedes tener es tu propia constancia de lo que decía el registro en un día determinado. axt-verify --save FILE escribe textualmente el checkpoint que verificó una ejecución, y --from FILE en una ejecución posterior obliga al registro a demostrar que todavía extiende ese checkpoint. Archiva un checkpoint guardado en un almacenamiento que controles, por ejemplo, a diario. Meses después, una prueba de consistencia desde el tamaño de árbol de ese checkpoint archivado debe seguir conduciendo a cualquier checkpoint que sirva el registro, o la verificación falla. Las claves anteriores siguen listadas en el conjunto de claves del verificador después de una rotación planificada, de modo que un checkpoint archivado sigue verificándose. Con axt-verify, si la clave que firmó un checkpoint archivado ya fue retirada por rotación, pasa ese archivo con --from-trusted en lugar de --from. Conserva también los eventos. Los eventos de Access Transparency que exportas del feed son una entrada válida para axt-verify events FILE, que demuestra en cualquier fecha posterior que esas copias siguen confirmadas en el registro bajo su checkpoint actual. Como events FILE no vuelve a leer el feed, tu exportación conservada es también la referencia con la que comparas una reexportación posterior del mismo rango.
Preguntas frecuentes
No. Anthropic mantiene el registro para tu organización, lo verifique alguien o no. La verificación es la forma de comprobar el registro por ti mismo. Un auditor puede verificar una muestra de eventos que le entregues con los mismos pasos, si dispone de una clave de API con el alcance de Activity Feed.
El evento se sirvió momentos antes de que se publicara un checkpoint que cubriera su posición. Un checkpoint que lo cubra llega poco después, así que vuelve a intentarlo tras una breve espera. Un evento cuya prueba sigue sin estar disponible un día después es la anomalía que debes escalar.
Las rotaciones planificadas se anuncian en Huellas digitales de claves publicadas con al menos 30 días de antelación, junto con una fecha de cambio. En la fecha de cambio, Anthropic comienza a firmar con la nueva clave y publica la versión de axt-verify que la incluye. En esa misma fecha, Anthropic vuelve a emitir el último checkpoint de cada organización con la nueva clave, incluso para un registro que no ha crecido. Cada versión de axt-verify incluye una sola clave, así que actualiza en la fecha de cambio. Ejecutar la versión anterior después del cambio falla con el estado de salida 1, y lo mismo ocurre al ejecutar la nueva versión antes del cambio. Cualquiera de los dos fallos desaparece una vez que ejecutas la versión correspondiente. Los checkpoints que guardaste con la clave anterior siguen siendo puntos de partida válidos, porque la prueba de solo anexado desde un checkpoint guardado hasta uno nuevo no depende de qué clave firmó el anterior. La nueva clave aparece al principio del conjunto de claves del verificador y las claves anteriores siguen listadas. Por lo tanto, los checkpoints que ya verificaste o archivaste siguen verificándose con ese conjunto. Un verificador propio que fije las huellas digitales publicadas necesita que se agregue la nueva huella digital, con su fecha de cambio, antes de esa fecha. Un verificador que mantiene el conjunto de claves localmente lo vuelve a obtener cuando encuentra una firma cuyo hash de clave no tiene. Un checkpoint se compromete con todo el historial. Una vez que un checkpoint firmado con la nueva clave se verifica, y una prueba de consistencia desde tu checkpoint guardado conduce a él, cada entrada anterior queda restablecida también.
Sí. Las tiles de hashes son la interfaz principal, y un cliente tlog-tiles que admita claves de nota ECDSA puede calcular pruebas de inclusión y de consistencia a partir de ellas. Los endpoints de pruebas son una comodidad. Un cliente genérico necesita un envoltorio ligero para enviar el encabezado x-api-key y, en el caso de una clave de organización principal, el parámetro organization_id.
No se elimina nada. Tu registro sigue siendo legible y verificable a través de los mismos endpoints, así que sigue verificándolo como antes. Si tu organización vuelve a habilitar Access Transparency más adelante, el mismo registro continúa, y las pruebas de consistencia abarcan el intervalo.
Sí. Una clave de organización principal lee el registro de cualquier organización secundaria inscrita pasando organization_id. Cada organización secundaria tiene su propio registro, origen y checkpoint guardado. Ejecuta una verificación por cada organización secundaria, cada una con su propio estado.
Recursos relacionados
- Access Transparency
- Consultar el Activity Feed
- Descripción general de la Compliance API
- Errores
- axt-verify, el verificador de código abierto de Anthropic para el registro de transparencia
- C2SP tlog-tiles y C2SP signed note, los formatos de transmisión para tiles, paquetes de entradas y checkpoints
- RFC 9162, los algoritmos de árbol de Merkle, prueba de inclusión y prueba de consistencia
- RFC 8785, el JSON Canonicalization Scheme utilizado para las hojas
Was this page helpful?