Claude ahora adjunta metadatos de procedencia C2PA firmados a los archivos que genera. También lo hacen los modelos de imagen de OpenAI, y también Gemini. Esto significa que una señal de procedencia real está llegando a su endpoint de carga por primera vez, y hay una buena probabilidad de que su pipeline la esté eliminando antes de que alguien la vea.
No de forma maliciosa: ocurre por defecto. sharp().resize() genera un archivo limpio sin metadatos, salvo que indique lo contrario. Lo mismo sucede con ImageMagick, Pillow y la mayoría de los CDN de imágenes. El manifiesto entra, sale un JPEG más pequeño y sus registros no informan nada.
Este es un fallo comprobable. En este artículo verá cómo identificar dónde se pierden los metadatos, cómo probar su pipeline de extremo a extremo y cómo añadir una verificación permanente en CI. Apidog orquesta el flujo HTTP; c2patool verifica el archivo a nivel de bytes.
Qué se destruye realmente
Un manifiesto C2PA es un bloque firmado criptográficamente e incrustado en el contenedor del archivo. Registra quién firmó el activo y qué se afirmó sobre él. Como está firmado, cambiar los bytes sin volver a firmar invalida la firma de una forma detectable por cualquier verificador.
La clave está en el contenedor: si lo reescribe, el manifiesto puede desaparecer.
| Operación | ¿El manifiesto sobrevive por defecto? |
|---|---|
| Copia o movimiento byte a byte | Sí |
sharp().resize().toBuffer() |
No |
ImageMagick convert / magick
|
No |
Pillow Image.save()
|
No |
| PNG a WebP, JPEG a AVIF | No |
| Autooptimización de CDN de imágenes | Usualmente no |
| Captura de pantalla | No |
| Volver a guardar desde un editor de imágenes | No |
| Subida a S3 sin transformación | Sí |
Todo lo que aparece como “No” es habitual en una aplicación web: miniaturas, variantes responsivas, negociación de formato o limpieza de EXIF por privacidad. Cada operación es razonable de forma aislada, pero puede terminar silenciosamente la cadena de procedencia.
También hay un conflicto práctico: -strip suele utilizarse para eliminar coordenadas GPS y números de serie de cámaras presentes en EXIF. Sin embargo, eliminar todos los metadatos también elimina el manifiesto C2PA. La solución es eliminar de forma selectiva los bloques que no quiere conservar, en lugar de borrar todos los metadatos.
Pruébelo en dos minutos
Antes de cambiar el pipeline, confirme el problema. Necesita un archivo con un manifiesto válido: puede usar una imagen generada por Claude o una muestra firmada de la Content Authenticity Initiative.
Instale la CLI de referencia:
cargo install c2patool
Compruebe que el fixture está firmado:
c2patool fixtures/signed-sample.png
Debería recibir un informe JSON con el generador de la reclamación y el estado de validación de la firma.
Ahora envíe el archivo por su pipeline real y recupérelo usando la misma URL que consume su frontend:
# Subir a través de su endpoint real
curl -sS -X POST https://api.example.com/v1/assets \
-H "Authorization: Bearer $API_TOKEN" \
-F "file=@fixtures/signed-sample.png" \
-o /tmp/upload.json
# Recuperarlo a través de la URL que usaría su frontend
ASSET_URL=$(jq -r '.url' /tmp/upload.json)
curl -sS "$ASSET_URL" -o /tmp/roundtrip.png
# ¿Sobrevivió el manifiesto?
c2patool /tmp/roundtrip.png
Interprete el resultado:
- Informe válido: el manifiesto sobrevivió.
- Manifiesto no encontrado: alguna etapa del pipeline lo eliminó.
- Error de validación: el manifiesto existe, pero la firma ya no coincide con los bytes.
El tercer caso es especialmente importante. Normalmente indica que una biblioteca preservó el bloque de metadatos mientras modificaba los píxeles. Para cualquier verificador posterior, eso parece una alteración del archivo.
Encuentre la etapa que lo elimina
Si la prueba de extremo a extremo falla, no adivine. Divida el pipeline y ejecute c2patool inmediatamente después de cada etapa:
- Después de recibir la carga.
- Después del redimensionamiento.
- Después de convertir el formato.
- Después de almacenar en el origen.
- Después de recuperar desde el CDN.
Los sospechosos habituales son los siguientes.
1. Redimensionamiento o generación de miniaturas
Es el caso más probable. En sharp, los metadatos se eliminan salvo que los conserve explícitamente:
// Elimina el manifiesto C2PA
await sharp(input).resize(1200).toFile(output);
// Conserva el bloque de metadatos
await sharp(input).resize(1200).keepMetadata().toFile(output);
Conservar el bloque es necesario, pero no suficiente. Los píxeles cambiaron, por lo que la firma original ya no será válida para los bytes nuevos.
Para mantener una cadena de procedencia funcional:
- Conserve los metadatos necesarios.
- Aplique la transformación.
- Vuelva a firmar la salida.
- Registre la transformación como una aserción de acción, normalmente
c2pa.resized.
Las bibliotecas c2pa para Rust, Python, JavaScript y C permiten implementar este flujo.
2. Conversión de formato
Servir AVIF o WebP crea un contenedor nuevo. La regla es la misma: preserve y vuelva a firmar, o acepte explícitamente que la cadena de procedencia termina en esa transformación.
3. CDN de imágenes
Muchos CDN reescriben imágenes en el momento de la entrega. Algunos preservan y vuelven a firmar Credenciales de Contenido de forma nativa; históricamente, la mayoría las eliminaban.
Pruebe siempre la URL de entrega real que visitan sus usuarios, no solo el archivo de origen. Una prueba contra el origen puede pasar aunque el CDN elimine el manifiesto.
4. Normalización durante la carga
Los servicios que recodifican archivos al recibirlos para estandarizar formatos suelen pasar desapercibidos. Con frecuencia, esta lógica vive en un repositorio de infraestructura separado del backend principal.
Conviértalo en una prueba permanente
Un único curl valida el estado actual, pero no evita que alguien introduzca una transformación en el próximo sprint. La verificación debe formar parte de CI.
Divida la prueba en dos capas:
- Orquestación HTTP de ida y vuelta.
- Verificación criptográfica del archivo recuperado.
Capa uno: viaje de ida y vuelta en Apidog
La orquestación es un escenario de API encadenado:
- Subir un fixture firmado.
- Extraer la URL devuelta.
- Recuperar el activo por la ruta de entrega real.
- Comprobar estado, tipo de contenido y tamaño.
En Apidog, cree un escenario con dos pasos.
Paso 1: POST /v1/assets
- Cuerpo:
multipart/form-datacon el fixture firmado. - Aserciones: estado
201y respuesta válida según su esquema. - Script posrespuesta para guardar la URL:
const body = pm.response.json();
pm.environment.set("ASSET_URL", body.url);
pm.test("upload returns a delivery URL", function () {
pm.expect(body.url).to.be.a("string").and.to.include("https://");
});
La mecánica de carga es la misma que en la prueba de APIs de carga de archivos.
Paso 2: GET {{ASSET_URL}}
- Aserciones: estado
200,Content-Typeesperado y tamaño de respuesta cercano al archivo original. - Una caída importante de tamaño es una señal útil de recodificación.
const uploadedBytes = Number(pm.environment.get("FIXTURE_BYTES"));
const returnedBytes = pm.response.responseSize;
pm.test("asset was not silently re-encoded", function () {
pm.expect(returnedBytes).to.be.above(uploadedBytes * 0.9);
});
El tamaño es una heurística, no una prueba criptográfica. Es útil para detectar fallos obvios de forma económica dentro de la misma suite HTTP. Consulte más patrones en aserción de APIs.
Capa dos: verificación a nivel de bytes en CI
Validar una firma exige analizar el contenedor del archivo. Ese trabajo corresponde a c2patool, no a un cliente HTTP.
Ejecute c2patool contra el archivo descargado por el escenario de ida y vuelta:
# .github/workflows/provenance.yml
name: provenance
on: [pull_request]
jobs:
c2pa-round-trip:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Instalar c2patool
run: cargo install c2patool
- name: Instalar Apidog CLI
run: npm install -g apidog-cli
- name: Ejecutar el escenario de ida y vuelta
run: |
apidog run --access-token "$APIDOG_ACCESS_TOKEN" \
-t "$SCENARIO_ID" \
-e "$ENV_ID" \
-r cli,html \
--out-dir ./apidog-reports
env:
APIDOG_ACCESS_TOKEN: ${{ secrets.APIDOG_ACCESS_TOKEN }}
SCENARIO_ID: ${{ vars.PROVENANCE_SCENARIO_ID }}
ENV_ID: ${{ vars.APIDOG_ENV_ID }}
- name: Verificar que el manifiesto sobrevivió
run: |
set -euo pipefail
curl -sS "$ASSET_URL" -o /tmp/roundtrip.png
c2patool /tmp/roundtrip.png > /tmp/report.json
jq -e '.validation_status == null or (.validation_status | length) == 0' /tmp/report.json
set -euo pipefail es importante. Sin esta instrucción, un fallo de c2patool ante un archivo sin metadatos puede convertirse en una advertencia y dejar la compilación en verde: exactamente el fallo que esta prueba pretende evitar.
Para configurar escenarios en un pipeline, consulte la automatización de pruebas de API en GitHub Actions.
Capa tres opcional: endpoint de verificación
Si la procedencia es una característica de producto y no solo un control interno, añada un endpoint propio que ejecute una biblioteca c2pa y devuelva un resultado estructurado.
Así puede probarlo como JSON normal y el frontend recibe un estado explícito:
{
"asset_id": "img_9f2c41",
"provenance": {
"status": "verified",
"standard": "c2pa",
"signer": "Anthropic",
"signature_valid": true,
"checked_at": "2026-08-11T09:14:22Z",
"tool": "c2patool/0.9"
}
}
Mantenga al menos tres estados:
-
verified: hay un manifiesto y la firma es válida. -
absent: no se encontró ningún manifiesto. -
invalid: existe un manifiesto, pero la firma no coincide con los bytes.
No reduzca absent e invalid a un booleano. Representan situaciones distintas y invalid es una señal mucho más relevante. Si el verificador puede no estar disponible, añada unchecked para no confundir una interrupción con un resultado limpio.
Documente esta respuesta en OpenAPI y valídela para evitar que los campos desaparezcan durante una refactorización. Consulte Cómo validar especificaciones OpenAPI.
Los cuatro fixtures que debe conservar
Una suite de procedencia necesita casos deliberadamente defectuosos, no solo un camino feliz.
Archivo firmado válido
Resultado esperado:verified. Detecta eliminación excesiva de metadatos.Archivo sin metadatos
Use la misma imagen, pero elimine el manifiesto conexiftool -all=.
Resultado esperado:absent, no un error y nuncaverified.Archivo manipulado
Use un archivo firmado y altere un byte después de la firma.
Resultado esperado:invalid. Este caso demuestra que valida la firma y no solo la existencia de un bloque de metadatos.Formato no compatible
Use un formato sin soporte de manifiestos.
Resultado esperado:absentde forma limpia, no un error500.
Guarde los cuatro fixtures en el repositorio junto al escenario de prueba. Son pequeños, no deberían cambiar y convierten una prueba que “pasa” en una prueba que realmente valida el comportamiento esperado.
Por qué merece la pena
Hay tres motivos principales.
La afirmación de su producto. Si su interfaz muestra un distintivo de procedencia, pero el pipeline elimina manifiestos durante el redimensionamiento, ese distintivo será incorrecto para todos los activos transformados.
Cumplimiento. Si depende de C2PA para requisitos relacionados con el Artículo 50, un manifiesto eliminado significa que su control no funciona. La separación entre proveedor y desplegador se explica en el Artículo 50 de la Ley de IA de la UE para desarrolladores de API.
La señal de procedencia. C2PA solo aporta valor cuando la cadena se mantiene de extremo a extremo. Cada pipeline que elimina manifiestos silenciosamente reduce la utilidad del ecosistema, incluso cuando necesita verificar un activo usted mismo.
Descargue Apidog para crear el escenario de ida y vuelta contra sus endpoints y añada después la verificación con c2patool en CI.
Preguntas frecuentes
¿El redimensionamiento de una imagen elimina los metadatos C2PA?
Sí, por defecto en las bibliotecas más comunes. Conservar el bloque requiere una opción explícita y mantener una firma válida requiere volver a firmar la salida transformada.¿Cómo verifico si un archivo tiene metadatos C2PA?
Ejecutec2patool <file>desde la línea de comandos o arrastre el archivo a la página de verificación de Content Credentials.¿Puedo mantener los metadatos C2PA al redimensionar?
Sí, pero no basta con conservarlos. Debe preservar el bloque, volver a firmar la salida y registrar la transformación mediante una aserción de acción comoc2pa.resized.¿Los CDN eliminan las Credenciales de Contenido?
Muchos las eliminan cuando autooptimizan imágenes. Algunos las preservan y vuelven a firmar de forma nativa. Pruebe la URL de entrega real, no solo el origen.¿Cuál es la diferencia entre un manifiesto eliminado y uno inválido?
absentsignifica que no hay manifiesto.invalidsignifica que existe, pero su firma no coincide con los bytes, lo que indica que el archivo cambió después de firmarse.¿Puede Apidog verificar directamente una firma C2PA?
Apidog orquesta el viaje de ida y vuelta y puede validar respuestas HTTP o JSON de un endpoint de verificación. El análisis criptográfico de la firma corresponde ac2patool, ejecutado en CI o dentro de su propio servicio.¿Debo eliminar EXIF por privacidad y conservar C2PA?
Sí. El enfoque correcto es selectivo: elimine los bloques EXIF específicos que no desea conservar y mantenga el manifiesto C2PA. Un-stripgeneral elimina ambos.
La conclusión
Los metadatos de procedencia suelen llegar intactos a su API y perderse durante una transformación posterior sin que sus métricas lo detecten.
La implementación mínima es clara:
- Añada un fixture firmado.
- Súbalo por su endpoint real.
- Descárguelo desde la URL de entrega real.
- Verifíquelo con
c2patool. - Haga fallar CI cuando el manifiesto esté ausente o sea inválido.
Con una configuración breve, convierte un distintivo de procedencia en su interfaz en una garantía que su pipeline aplica de verdad.
Top comments (0)