Ir al contenido

Keypairs y firma

kovra puede custodiar un keypair asimétrico: genera la clave, sella la mitad privada bajo la master key del vault y nunca escribe la clave privada en disco ni la imprime. Se opera a través de kovra — firmando, verificando, cifrando, descifrando — sin que la clave privada salga jamás del vault.

kovra keygen crea la clave y muestra solo la mitad pública. Elegir ed25519 (firma y cifrado) o rsa (solo firma/SSH):

zsh
~ % kovra keygen secret:dev/ssh/deploy --type ed25519
Generated dev/ssh/deploy (ed25519, Medium).
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDnM/+Nl+/2Y/uEZNK5Q7ZEdQEMmOGXB6PTQg2hWJaSw

La entrada se lista con un modo tipado de keypair:ed25519. Reimprimir la clave pública en cualquier momento — esto es gratis y nunca pide confirmación:

zsh
~ % kovra pubkey secret:dev/ssh/deploy
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDnM/+Nl+/2Y/uEZNK5Q7ZEdQEMmOGXB6PTQg2hWJaSw

kovra sign firma datos desde un archivo o desde stdin; la firma va a stdout. kovra verify la comprueba. Firmar con una clave high/prod pide hacer bioProve; verificar es siempre gratis:

zsh
~ % printf 'release v1.2.3' | kovra sign secret:dev/ssh/deploy > sig.bin
zsh
~ % printf 'release v1.2.3' | kovra verify secret:dev/ssh/deploy --signature sig.bin
OK: signature is valid

La verificación también funciona contra una entrada solo-pública — la clave pública de un par que se almacenó con kovra add --public-key (no contiene mitad privada), de modo que se pueden verificar las firmas de un colega sin su clave privada.

Use --reason para indicar para qué es la firma. Funciona igual con un archivo que con stdin:

zsh
~ % kovra sign secret:dev/ssh/deploy --reason "Manifiesto del release v1.2.3" manifest.md > manifest.sig

El motivo es una línea de 200 caracteres como máximo. kovra lo rechaza con código de salida 2, antes de abrir la clave o de pedirle nada, cuando está vacío, es más largo, o tiene un salto de línea, un carácter de control, de formato, bidi, combinante o invisible, o un espacio que no sea el espacio común; las letras con tilde y la ñ pasan. kovra preflight sign <coord> --reason "<texto>" lo revisa de la misma forma, de modo que un agente sabe de antemano si un motivo se rechazaría.

Toda firma que le pide aprobación —con una clave high, inject-only o de prod— muestra qué se firma, con o sin --reason:

  • Una oración propia de kovra: quién pide, el nombre del archivo (o la entrada estándar), su tamaño y su tipo (texto, PDF o binario), y la clave con su entorno. Los detalles (entorno, proyecto, secreto, quién pide, comando) siguen en gris.
  • El SHA-256 de los bytes exactos que firma la clave, en forma corta: sus seis primeros y seis últimos caracteres, ebbda6 … fb9e9c. Compárelos con shasum -a 256 <archivo> del archivo que usted quería firmar. La ventana del documento y el diálogo de macOS muestran los 64 caracteres.
  • Un aviso de caracteres ocultos (⚠ The document has 2 hidden characters — review it before approving) cuando un texto tiene caracteres que cambian u ocultan cómo se lee: controles bidi, caracteres de ancho cero, caracteres de control, un retorno de carro que no termina una línea. Revise el documento antes de aprobar.
  • El motivo, al final, bajo Reason given by the requester — kovra does not verify it. Lo escribió quien pide, y quien pide puede ser un agente secuestrado: léalo como una afirmación, no como un hecho.

En la Mac, Review document… abre el documento en una ventana aparte de kovra. Muestra los bytes que kovra leyó y va a firmar: el archivo no se vuelve a leer, así que cambiarlo después no cambia nada.

  • Texto (hasta 256 KiB): el código fuente, con números de línea, nunca cortado en el borde. Los caracteres ocultos se muestran como escapes (\u{202e}), y cada uno se lista bajo el encabezado con su línea y lo que hace.
  • Markdown y HTML (un archivo que termina en .md, .markdown, .html o .htm): dos pestañas, Source y Rendered, y la ventana abre en Rendered. Lo que se firma es el código fuente: la vista renderizada puede ocultar contenido (un comentario HTML, el destino real de un enlace, texto oculto), como dice su aviso. Revise Source antes de aprobar.
  • PDF (hasta 8 MiB): renderizado para leerlo; los enlaces, los formularios y los scripts no hacen nada. Un PDF puede mostrar menos de lo que contiene, así que el SHA-256 es la declaración exacta de lo que se firma.
  • Datos binarios, un documento más grande o uno que kovra no puede mostrar (un texto demasiado largo una vez escapado, un PDF que no abre o está cifrado): no se muestra, ni siquiera un fragmento. La ventana dice por qué; compare el SHA-256 en su lugar.

No se puede aprobar mientras la ventana del documento está abierta: el lugar del sensor dice Close the document to approve (sin Touch ID, Approve with Touch ID queda atenuado). Ciérrela con su botón de cerrar, ⌘W o Esc, y la ventana de revisión recupera el foco: el sensor se activa solo después de un momento, sin clic. Si otro programa tomó el foco o cubrió alguna de las dos ventanas mientras usted leía, haga clic primero en la ventana de revisión, como siempre. El tiempo para responder sigue corriendo mientras lee.

En el teléfono vinculado, kovra Mobile muestra el SHA-256 completo, el aviso de caracteres ocultos cuando lo hay y el motivo, e indica que el documento se muestra solo en la Mac: el documento nunca sale de su Mac. Para leerlo, apruebe en la Mac.

Para un keypair ed25519, kovra también puede cifrar hacia la clave pública y descifrar con la clave privada (una caja sellada basada en age). Cifrar es gratis; descifrar con una clave high/prod pide hacer bioProve:

zsh
~ % printf 'a short secret note' | kovra encrypt secret:dev/ssh/deploy > ct.bin
zsh
~ % kovra decrypt secret:dev/ssh/deploy ct.bin
a short secret note

Los keypairs RSA firman y verifican (y funcionan como claves SSH) pero no soportan cifrado — usar ed25519 cuando se necesite sellado.

La clave privada se genera dentro del vault y nunca se materializa en disco ni en el shell. Un agente o un script puede pedirle a kovra que use la clave — firmar un release, abrir un mensaje sellado — pero no puede exfiltrarla, y cada uso de una clave sensible queda gobernado y auditado. Para cargar una clave en una sesión SSH, ver el ssh-agent gobernado.