Signing FlowsPlatformDemo walkthroughAPI reference

Assurance reference

Versión inicial · En revisión / Initial edition · Under review
Publicación: 15 septiembre 2026. Acceso libre. Contenido inicial en español; se actualiza con cada revisión. Estar publicado no significa estar verificado.

Lo que el producto garantiza

Ésta es la única fuente. Cualquier otro documento, pantalla o texto comercial que afirme algo sobre firmas, sellos, evidencia o validez cita esta página en vez de reescribirla.

No es una decisión de estilo. El 14-09-2026 el producto afirmaba lo mismo en tres lugares y no decía lo mismo en los tres: la landing en inglés, la landing en castellano y la propia aplicación. Reescribir una garantía con otras palabras crea una versión más que nadie sabe que hay que actualizar.

Revisada el 15-09-2026 con las siete observaciones de Codex sobre la versión 289a635. Las siete se aceptaron. El patrón era uno solo y vale la pena decirlo acá arriba: una página escrita para no exagerar lo que el producto hace, exageraba lo que sus propias mediciones probaban. Lo que se midió con un lector pasó a ser propiedad de todos los lectores; lo que se midió con un motor, propiedad de todo validador. Las respuestas están en respuesta-revision-garantias.md.

Cómo se lee cada garantía

Cada una tiene tres campos, y los tres son obligatorios:

CampoQué es
Qué se garantizaUna frase, sin adjetivos
Bajo qué condicionesEl campo que faltaba en todos lados. Es el que convierte una mentira en una verdad
Cómo se comprobóArchivo, medición o commit. Si no hay, dice que no hay

Una garantía sin condiciones escritas no es más fuerte: es menos honesta.

⚠⚠ Y un cuarto que la revisión del 15-09 obligó a agregar: CON QUÉ se comprobó. Un resultado de laboratorio lleva lector o motor, versión, política y corpus. Sin eso, una medición correcta se lee como una ley general, y esta página se pasó al otro lado justamente por eso.

A · Sobre el documento firmado

A1. Cada firma cubre una revisión del PDF

Qué se garantiza. Cada firma digital cubre el estado del documento en el momento de firmar. Un cambio posterior no altera lo que esa firma cubrió.

Bajo qué condiciones. Siempre. Es propiedad del formato, no nuestra.

Lo que NO se sigue de esto: que el documento no pueda cambiar después. Cambios posteriores permitidos conviven con firmas anteriores válidas. Quien quiera saber qué cambió, mira el historial de revisiones en el lector.

Cómo se comprobó. Laboratorio q0q4, laboratorio-prepared.md.

A2. ⛔ El cierre duro NO se ofrece

Qué se garantiza. Nada. El producto no ofrece cierre duro, y eso es una decisión tomada, no una función pendiente.

Acá hay tres cosas distintas que antes estaban en una sola frase, y la revisión del 15-09 tuvo razón en separarlas:

1. Lo medido, con su alcance. En Acrobat Reader de escritorio, sobre los archivos q1q4 del laboratorio, el 14-09-2026: /Lock /All no impidió ninguna firma posterior, con el campo pre-declarado y sin él. Eso es lo que se observó, en ese lector y sobre esos archivos.

2. El razonamiento, que es otra cosa y hay que rotularlo como tal. Agregar /V a un campo de firma es modificar un campo de formulario, así que un candado sobre todos los campos se rompe a sí mismo en cuanto alguien firma. Es un argumento sobre el mecanismo y explica bien lo observado — pero un argumento no es una medición, y no basta para afirmar cómo se comporta cualquier lector.

3. La decisión de producto. No se ofrece cierre duro. Esa decisión no depende de resolver la pregunta normativa, que sigue abierta.

Lo que NO se puede decir, y antes decía esta página: «no sobrevive a ninguna firma posterior», sin nombrar lector ni corpus. Tampoco se puede deducir de acá qué hace un validador independiente: ver D1.

Y lo que sí sigue en pie: cualquier texto que prometa que un documento queda cerrado y no se puede tocar más está prometiendo algo que el producto no ofrece hoy.

Cómo se comprobó. q1q4, Acrobat Reader de escritorio, 14-09-2026, laboratorio-prepared.md.

A3. ⛔ Un campo de firma vacío es firmable por cualquiera

Qué se garantiza. Nada, y hay que decirlo al revés: es un riesgo abierto.

Lo medido. Un /FT /Sig vacío lo firma cualquiera que tenga el archivo. La firma del tercero aparece como par de las legítimas, con el mismo tilde verde, y el aviso «Please fill out the following form» desaparece.

⚠ Y una apariencia /AP vacía no oculta el campo: el lector decide cómo marca lo que es firmable, no nosotros.

Cómo se comprobó. q1, Acrobat Reader de escritorio, 14-09-2026. ⚠ No se midió qué muestran otros lectores.

⚠⚠ Importa hoy, no en un modo futuro: las plantillas que suben los clientes pueden traer campos de firma vacíos, y se conservan en el documento entregado — verificado en src/firma/apariencia.ts, que arma el AcroForm con camposViejos incluidos.

Decidido el 15-09-2026 por Walter: detectarlos al preparar y que el emisor asigne o quite. Ver laboratorio-prepared.md.

A4. La certificación (DocMDP) no está disponible

Qué se garantiza. Nada todavía. No certificamos documentos.

Por qué. Certificar exige un certificado de sello que no tenemos.

Corregido el 15-09-2026. Esta sección decía que la certificación es «la única señal que le permite a un validador independiente distinguir nuestro documento legítimo de uno con un candado roto», y que sin /DocMDP un validador «no tiene con qué». Las dos cosas son falsas como están escritas, y el propio informe que las respaldaba las contradice.

Lo que de verdad se midió, con DSS 6.5, política predeterminada, sobre el corpus del laboratorio:

  • DSS sí lee los controles del candado. Sus comprobaciones BBB_FC_ISVAFMDPD

(FieldMDP) y BBB_FC_ISVASFLD (SigFieldLock) existen y se ejecutan.

  • El problema no es que le falte señal: es que **esas comprobaciones dieron OK

tanto en el caso legítimo como en el violado. Un control que aprueba los dos no discrimina — que es exactamente lo que dice D1**.

Lo que NO se sigue: que /DocMDP sea la única señal posible para cualquier validador, ni que ningún otro motor o política pueda distinguirlos. No se probó, y afirmarlo era pasar de «este motor con esta política» a «cualquier validador independiente».

⚠ Y una separación que la revisión pidió con razón: que este despliegue necesite un certificado no lo convierte en un requisito del formato.

Cómo se comprobó. T54.6 abierto; DSS 6.5 local, 14-09-2026, segundo-motor-dss.md y su reproducción 80d237f.

B · Sobre la evidencia

B1. La cadena detecta alteración parcial

Qué se garantiza. Cada evento queda ligado al anterior por hash (hash_contenido, hash_anterior, hash_propio). Alterar un evento sin recalcular el resto de la cadena se detecta.

Bajo qué condiciones. Dentro de una instancia, y contra quien no pueda reescribir la cadena entera.

Tres límites, y ninguno es menor:

  • La cadena es por instancia, no global. Es deliberado: una cadena global

serializaría todas las escrituras y mataría el envío masivo.

  • ⚠⚠ No hay ancla externa mantenida por la plataforma. El comentario de la

migración dice que el orden entre instancias «lo resuelve el Merkle diario». El Merkle aparece en un solo lugar de todo el repositorio: ese comentario. No hay implementación.

  • El sello de tiempo sobre la evidencia es opcional. sello_tiempo_id es

anulable, y hay un índice hecho a propósito para encontrar los eventos sin sellar.

La plataforma no mantiene ninguna copia de los hashes fuera de su base de datos. Quien pueda escribir en la base reescribe la cadena de punta a punta, y la plataforma no tiene nada afuera que lo contradiga.

Corregido el 15-09-2026. Antes decía «nada fuera de la base de datos guarda copia de ningún hash», y es falso: el paquete de entrega exporta hash_propio y hash_anterior de cada evento (src/services/paquete.ts). O sea que un receptor que haya descargado un paquete tiene copia de esos hashes, y una copia vieja en sus manos sí contradiría una cadena reescrita después.

Eso no es un ancla, y la diferencia importa: no es automático, no está bajo nuestro control, y depende de que alguien haya descargado y conservado el paquete. Pero no se puede seguir afirmando que no existe.

Cómo se comprobó. migrations/020_evidencia.sql, leída el 14-09-2026; src/services/paquete.ts, leído el 15-09-2026.

Lo que NO se puede decir: «imposible de editar», «inalterable», «immutable». Lo que hay es detección de alteración parcial, que es real y es útil, y no es lo mismo.

B2. El sello de tiempo, cuando está configurado

Qué se garantiza. Un sello de tiempo de una autoridad externa da prueba de tiempo que no depende de nuestro reloj.

Bajo qué condiciones.Sólo si el servicio está habilitado y disponible para esa instalación. No es automático, y no siempre está.

Corregido el 15-09-2026. La evidencia anterior —una columna anulable y una entrada en el catálogo de conectores— acreditaba que la función está prevista, no que un sello se produzca y se verifique. La observación era correcta: una entrada de catálogo no es una prueba.

Lo que sí se midió, el 15-09-2026, y es mejor evidencia:

El producto produce un sello de tiempoEl circuito completo deja «PAdES B-T — *a document timestamp*»
DSS lo reconoce como talClasifica el documento como PAdES-BASELINE-T, que exige un sello de tiempo de firma
El contenido se compruebaleerTokenDeSello() verifica que el *imprint* del token sea el resumen de los bytes que su ByteRange cubre

Lo que sigue SIN comprobarse, y hay que decirlo: en esa corrida la cadena del sello de tiempo no resultó confiable — DSS devolvió BBB_XCV_CCCBB_TSP_ANS: the certificate chain for time-stamp is not trusted. Es esperable, porque a esa corrida se le dio como ancla sólo el sello de desarrollo. Pero mientras no se haga con un ancla completa, la confianza de la cadena del sello no está demostrada.

Cómo se comprobó. sello_tiempo_id anulable en 020_evidencia.sql y motor TSA_RFC3161 en el catálogo *(estructura)*; corrida de DSS 6.5 local sobre un documento producido por el circuito el 15-09-2026 *(contenido)*.

C · Sobre las claves y la identidad

C1. ⚠ La clave privada: depende del motor, y la respuesta no es una sola

Qué se garantiza. Con motores remotosREMOTE_TRUSTEDX, IDP_NATIVO— la clave del firmante vive en el prestador de servicios de confianza y nosotros no la tenemos nunca.

⚠⚠ Y la excepción, que hay que decir siempre junto con lo anterior: con el motor LOCAL_P12 la plataforma firma con una clave propia, guardada en un archivo PKCS#12. El catálogo del producto lo dice con todas las letras: *«A key in a file, held by the platform.»* Y es el motor por omisión cuando no hay otro configurado.

Cómo se comprobó. src/firma/cms_cades.ts:255 carga la clave de un .p12; db/sello-dev.p12 y db/tsp-test.p12 existen en disco; catalogo_conectores.ts:481 lo usa como valor por omisión.

La frase «nunca guardamos claves privadas de firma, ni siquiera las nuestras» —que está hoy en la landing en castellano— es falsa. Está anotada para corrección.

C2. No somos un prestador de servicios de confianza

Qué se garantiza. Consumimos un TSP; no lo somos. La confianza del certificado, su acreditación y su revocación son del prestador, no nuestras.

Bajo qué condiciones. Siempre. Es lo que somos, no una limitación temporal.

⚠ Y de ahí se sigue algo que conviene no confundir: identidad y firma son dos servicios distintos. Que alguien se identifique con un IdP no dice nada sobre con qué clave firma.

D · Sobre lo que dice un validador

D1. ⚠⚠ «El validador dice válido» no es una afirmación sobre manipulación

Lo medido, y es incómodo. DSS 6.5 —motor de la Comisión Europea, con su política predeterminada— le da TOTAL_PASSED a un archivo donde está probado byte a byte que un campo bloqueado fue reescrito después del candado. Esa política trata eso como advertencia, no como falla.

Y los controles específicos del candado dan OK en los dos casos, el legítimo y el violado. Un control que dice OK en ambos no distingue nada.

Cómo se comprobó. DSS 6.5, política predeterminada, corpus del laboratorio. segundo-motor-dss.md, reproducido de forma independiente el 14-09-2026, commit 80d237f.

Lo que NO se sigue: que otro motor, u otra política sobre este mismo motor, se comporte igual. No se probó.

D2. ⚠ Las advertencias que aparecen en nuestros documentos

Qué hay que saber. En el corpus ensayado, nuestros documentos con más de una firma produjeron siempre dos advertencias: *visual difference* y *undefined object modifications*. La explicación es que la segunda firma agrega apariencia sobre la revisión de la primera.

Corregido el 15-09-2026. Antes decía que esas advertencias son «inherentes a firmar en secuencia», o sea inevitables y universales. Lo medido es más chico: coinciden en los archivos ensayados, con DSS 6.5 y su política predeterminada. No se probó que aparezcan en todo PDF con varias firmas, ni que sean inevitables.

⚠⚠ Y el corolario, que no depende de esa universalidad y sigue valiendo entero: si le enseñamos a un perito o a un cliente que esas advertencias son normales y se ignoran, le estamos enseñando a ignorarlas en un documento manipulado, donde salen iguales.

Cómo se comprobó. DSS 6.5, política predeterminada, informes de la rama codex/validador-etsi (a01d135) y su reproducción 80d237f.

D3. La validación a largo plazo depende del material de revocación

Qué se garantiza. Un documento con material de validación embebido (PAdES-BASELINE-LT o LTA) se verificó después, en las condiciones de abajo.

Bajo qué condiciones.Que el certificado tenga revocación publicada y alcanzable, y que quien valide confíe en la cadena.

Corregido el 15-09-2026, en dos cosas:

1. No son la misma compra. Antes decía «destrabarlo no es trabajo técnico: es una compra», y mezclaba dos necesidades distintas:

QuéPara quéEstado
Material de revocación de laboratorioQue el laboratorio pueda cerrar sus casos sin depender de una compraSin resolver, y puede que no haya que comprarlo: una CA de prueba con OCSP publicado alcanza
Certificado de sello para el despliegueProducción⏳ Esperando a Walter

2. Un resultado no es una promesa de futuro. q0 y q3 dieron TOTAL_PASSED en una fecha, con el material de esa fecha. Eso no demuestra que el mismo archivo se verifique dentro de diez años: hay condiciones —vigencia de la cadena, disponibilidad del material embebido, política del validador de entonces— que no se ensayaron.

Lo que NO se puede decir: «se comprueba con cualquier lector aunque no existamos más», sin esas condiciones.

Cómo se comprobó. DSS 6.5: q0 y q3 dan TOTAL_PASSED; q4, construido sin material de validación para aislar la variable, da INDETERMINATE / CERTIFICATE_CHAIN_GENERAL_FAILURE.

E · Sobre el acceso

E1. El acceso se decide en la base, no sólo en la aplicación

Qué se garantiza. Los permisos de cuenta y las políticas de acceso a nivel de fila controlan quién ve qué. Un error de programación en la aplicación no alcanza, por sí solo, para que alguien vea lo que no le corresponde.

Bajo qué condiciones. Son dos, y la segunda faltaba:

1. Que la política esté efectivamente aplicada sobre esa tabla. Ya hubo un caso donde el conjunto de anclajes probados volvía vacío en todos los pedidos, y eso se arregló; la lección es que una compuerta hay que probarla en su caso positivo, no sólo en el de rechazo.

2. ⚠⚠ Que la conexión NO use un rol que evada la RLS. Agregado el 15-09-2026 a pedido de la revisión, y es una condición dura: con el superusuario de PostgreSQL las políticas no se aplican y la garantía desaparece entera. El README.md y src/db/pool.ts ya advertían el riesgo; faltaba acá, que es donde se lee la garantía.

Y no es teórico: se vio el 15-09-2026. Consultando la base con el rol de la aplicación, select * from cuenta devolvió cero filas con tres cuentas cargadas — la RLS haciendo su trabajo. Las mismas filas aparecieron con postgres. La diferencia entre las dos consultas es exactamente el tamaño de esta condición.

Cómo se comprobó. src/auth/contexto_pedido.ts y el arreglo de los anclajes probados *(política aplicada)*; src/db/pool.ts y README.md *(el rol)*; comprobación directa contra la base local, 15-09-2026 *(el contraste entre los dos roles)*.

⛔ Resumen: lo que NO se puede afirmar

Para tener al lado de cualquier texto comercial. Ninguna de estas frases es verdadera hoy:

FrasePor qué no
«Imposible de editar» / «inalterable» / «immutable»B1. Hay detección de alteración parcial, sin ancla mantenida por la plataforma
«Una vez firmado no se puede modificar»A1. Cambios posteriores conviven con firmas válidas
«El documento queda cerrado»A2. No se ofrece cierre duro
«Nunca guardamos claves privadas»C1. Con LOCAL_P12, sí
«El sello de tiempo lo pone una autoridad acreditada» *(sin condición)*B2. Sólo si el servicio está habilitado
«Se comprueba con cualquier lector aunque no existamos más» *(sin condición)*D3. Depende del material de revocación y de la política de quien valide
«El validador dice válido, entonces no fue manipulado»D1. Un archivo con el candado roto obtiene TOTAL_PASSED

Y tres que esta página misma afirmaba de más hasta el 15-09-2026, anotadas para que no vuelvan por la ventana:

FrasePor qué no
«/Lock /All no sobrevive a ninguna firma posterior»A2. Medido en Acrobat de escritorio sobre q1q4. El mecanismo lo explica; no lo universaliza
«DocMDP es la única señal para un validador independiente»A4. DSS lee FieldMDP y SigFieldLock. No discriminan bajo su política predeterminada, que es otra cosa
«Nada fuera de la base guarda copia de ningún hash»B1. El paquete de entrega los exporta al receptor

Cómo se mantiene esta página

Una garantía entra acá sólo con los tres campos llenos. Si no se puede escribir *cómo se comprobó*, se escribe «no se comprobó» y se dice así hasta que alguien lo mida.

Y si algo que hay que afirmar no está acá, no se inventa: se pide. «Falta la garantía X» es una observación útil, no una molestia.

⚠⚠ Y lo que enseñó la revisión del 15-09: el campo *cómo se comprobó* no alcanza con nombrar el archivo. Tiene que decir con qué se midió —lector o motor, versión, política, corpus— porque una medición sin esos cuatro datos se lee como una ley general, y así fue como esta página terminó afirmando de más en cuatro secciones distintas.