Referencia de la API REST

Documentación completa de la API REST para secretos y criptografía post‑cuántica

Modelo de seguridad — tu responsabilidad como desarrollador

El servidor es zero‑knowledge por diseño: nunca ve el texto plano, la passphrase ni ninguna clave privada. Cada secreto se sella a la clave pública ML‑KEM‑768 de un destinatario Y a una passphrase, así que una integración segura depende de cómo TÚ gestionas las cuatro piezas de abajo. Trátalo como un patrón, no como una limitación.

Clave privada del destinatario (ML‑KEM‑768)

Dónde: En la bóveda del navegador del destinatario o en su máquina (keygenpqc.sh). Solo se comparte la clave pública.

Quién la tiene: Solo el destinatario. Nunca el emisor ni el servidor.

Passphrase

Dónde: Solo en tu máquina o en una bóveda controlada por ti.

Quién la tiene: TÚ y el destinatario. Nunca el servidor.

Blob cifrado

Dónde: Almacenamiento del servidor con TTL (Redis).

Quién la tiene: El servidor lo guarda, pero es opaco sin la clave privada y la passphrase juntas.

Token

Dónde: Devuelto por POST /secrets, viaja por el path.

Quién la tiene: El servidor (índice) y quien deba recuperar el secreto.

Reglas del patrón

  • La passphrase y las claves privadas no deben entrar nunca en logs, paneles, bases de datos compartidas ni en el path de la URL.
  • Envía el enlace y la passphrase por canales separados (Signal, Bitwarden Send, Vault, KMS, etc.): la entrega ocurre fuera del servidor de NoTrust.
  • Comprueba fuera de banda la huella de la clave pública del destinatario antes de cifrar para él: una clave cambiada significa un secreto sellado para otro. Firma con ML‑DSA‑65 y que el destinatario fije tu clave, para que sepa quién lo envía.
  • Usa una passphrase robusta. Es un segundo factor: la clave privada sola no abre nada y la passphrase tampoco, pero si la clave privada se filtra, la passphrase es lo único que queda.
  • No existe recuperación. Si pierdes la clave privada o la passphrase, el secreto se pierde: es la garantía que impide al servidor ayudar a un atacante. Guarda la API key en tu gestor de secretos; solo autoriza a crear secretos.

Patrones típicos de integración

Dev → dev (humano)
Pide al destinatario su clave pública (Bóveda → Exportar clave pública, o el .kem.pub de keygenpqc.sh), comprueba su huella con él, crea el secreto y envía el token (o el enlace /secret/<token> que devuelve la API) y la passphrase por dos canales distintos. La web funciona igual con el token: ni el token ni el enlace llevan nunca la passphrase.
CI/CD → runner
El runner tiene su propio par ML‑KEM‑768: la clave pública va con el pipeline y la privada vive en el secret store del runner. El pipeline crea secretos con la API key y una passphrase de su secret store, y nunca imprime ninguna en los logs.
Bot / agente automatizado
Cada agente tiene sus propios pares de claves y mantiene el par (token, passphrase) en memoria efímera tras consumirlos. Firma lo que envía con ML‑DSA‑65 y fija las claves de sus pares, así que un remitente falso se rechaza antes de descifrar nada. Nunca escribe en disco sin cifrar una clave privada ni una passphrase.

Resumen: NoTrust te da el primitivo (cifrar para una clave, almacenar opaco, entregar una vez, autodestruir); la identidad y la distribución de claves son cosa de tu integración. Y para ser precisos: los ordenadores cuánticos no rompen AES‑256. Lo que aporta ML‑KEM‑768 es atar cada secreto a la clave privada del destinatario mediante un encapsulado de claves diseñado para resistirlos.

Autenticación

Crear un secreto a través de la API requiere una API key. Las claves que creas en tu cuenta llevan los permisos de secretos (secrets:create, secrets:read, secrets:delete); los endpoints auxiliares Crypto (PQC) piden los permisos crypto que indican, y esas claves no los tienen (403 INSUFFICIENT_SCOPE). La web no necesita clave. Leer un secreto tampoco: lo protegen la clave privada del destinatario y la passphrase. La API key solo autoriza a crear secretos y no descifra nada, y todas las claves que generas se quedan en tu cliente.

Cabecera: X-API-Key: sk_live_tu_clave_api

O envíala como Authorization: Bearer sk_live_tu_clave_api. Sin clave la API responde 401 API_KEY_REQUIRED_FOR_PQC; con una desconocida o borrada, 401 INVALID_API_KEY; con una revocada o desactivada, 401 REVOKED_API_KEY; con una caducada, 401 EXPIRED_API_KEY.

Tres scripts de shell hacen todo el flujo en tu máquina y escriben el mismo formato que lee la web: un secreto creado aquí se abre en el navegador, y al revés. Necesitaspip install pqcrypto cryptography y curl. Crear un secreto requiere una API key: regístrate y créala en tu cuenta. Todas las claves se quedan en tu máquina; el servidor solo almacena el blob cifrado.

Paso 1 — Verificar soporte PQC (opcional, sin auth)

curl -sS https://notrust.now/api/v1/crypto/capabilities
# {"postQuantumSupported":true,"algorithms":{"kem":{"ML-KEM-768":{...}},"sig":{"ML-DSA-65":{...}}},...}

Paso 2 — Instalar las dependencias y descargar los scripts

pip install pqcrypto cryptography
for f in keygenpqc.sh createpqc.sh decryptpqc.sh; do
  curl -sSO "https://notrust.now/scripts/$f"
done
chmod +x keygenpqc.sh createpqc.sh decryptpqc.sh

Paso 3 — Generar tus pares de claves

Un par ML‑KEM‑768, para el que otros cifran, y un par ML‑DSA‑65, con el que firmas. Comparte los .pub y comprueba las huellas con tus contactos; los .key nunca salen de tu máquina. Un usuario de la web te añade en la bóveda desde Contactos → Importar Claves Públicas de Contacto.

./keygenpqc.sh ./me
# ML-KEM-768  ./me.kem.pub / .kem.key   fingerprint EA32DFFC845BE8CD
# ML-DSA-65   ./me.dsa.pub / .dsa.key   fingerprint D2D52250A960FE9E
# Share the .pub files. The .key files never leave this machine.

Paso 4 — Crear un secreto para un destinatario

-r es la clave pública ML‑KEM‑768 del destinatario: un usuario de la web la descarga de la bóveda con Exportar clave pública. Usa tu propio .kem.pub para guardarte un secreto a ti mismo. La passphrase es obligatoria (6 caracteres como mínimo) y se pide por teclado si NOTRUST_PASSPHRASE no está definida. Envíala por un canal distinto al del enlace.

export NOTRUST_API_KEY="sk_live_your_api_key"   # from https://notrust.now/en/account

./createpqc.sh -r alice.kem.pub -s me.dsa.key -S me.dsa.pub -t 60 "the secret"
# Passphrase (min. 6 characters):
# Repeat the passphrase:
# https://notrust.now/secret/1acf9280a2cb4a6a9032edcd60a0a71c

Paso 5 — Abrir un secreto que te han enviado

Con -p, el secreto se rechaza si no lleva una firma válida de la clave ML‑DSA‑65 de ese remitente. La firma se comprueba antes de descifrar nada.

./decryptpqc.sh -k me.kem.key -p alice.dsa.pub \
  https://notrust.now/secret/1acf9280a2cb4a6a9032edcd60a0a71c
# Passphrase:
# Signature valid: signed by A9A120728164FF6B (the sender you pinned).
# the secret

Esta llamada CONSUME una vista: el secreto se elimina después. Si te equivocas de passphrase, el script conserva el blob para que reintentes con -i.

Formato del payload (v2), para escribir tu propio cliente

Lo que envía createpqc.sh y lee la web. El servidor rechaza todo lo que no sea un payload ML‑KEM‑768 (400 PQC_REQUIRED).

# key  = scrypt(passphrase, salt; N=65536, r=8, p=1, dkLen=32)
#        XOR ML-KEM-768 shared secret (encapsulated to the recipient's public key)
# box  = ChaCha20-Poly1305(key, iv), no associated data
# sign = ML-DSA-65 (optional) over these lines joined with "\n":
#        pqc-sig-v1, id=, ttl=, maxViews=, version= (from metadata),
#        ciphertext=, iv=, salt=, kemCiphertext=, recipientPublicKey=

POST /api/v1/secrets        X-API-Key: sk_live_your_api_key
{ "secret": "<payload as a JSON string>", "ttl": 15, "maxViews": 1 }   # ttl in minutes

payload = {
  "ciphertext": "<Base64: ChaCha20-Poly1305 output, tag included>",
  "iv": "<Base64, 12 bytes>",
  "salt": "<Base64, 32 bytes>",
  "algorithm": "ChaCha20-Poly1305",
  "keyDerivation": "Scrypt+KEM",
  "scryptParams": { "N": 65536, "r": 8, "p": 1, "dkLen": 32 },
  "ttl": 900, "maxViews": 1, "hasPassphrase": true,              # ttl in seconds here
  "metadata": { "id": "<UUID v4>", "ttl": 900, "maxViews": 1, "version": 2,
                "requireSignature": true, "clientSidePQC": true,
                "timestamp": 1790000000000 },
  "kyberData": { "publicKey": "<recipient's ML-KEM-768 key, 1184 bytes>",
                 "ciphertext": "<ML-KEM-768 ciphertext, 1088 bytes>" },
  "signatureData": { "algorithm": "ML-DSA-65",
                     "publicKey": "<sender's ML-DSA-65 key, 1952 bytes>",
                     "signature": "<3309 bytes>" }                  # or null
}

Algoritmos por función

FunciónRutaAlgoritmosAPI key
Secretos

Secretos de un solo uso sellados a la clave de un destinatario

/createML‑KEM‑768 + passphrase (Scrypt) + ChaCha20‑Poly1305, firma ML‑DSA‑65 opcionalSí para la API (las claves se quedan en el cliente)
File Crypto

Cifra/descifra ficheros (máx. 2 MB)

/file-cryptoML‑KEM‑768 + ChaCha20‑Poly1305 + ML‑DSA‑65 (ficheros .pqc)No
P2P Direct

WebRTC · sin almacenamiento en servidor

/p2pML‑KEM‑768 + ChaCha20‑Poly1305 sobre WebRTCNo

La web funciona en tu navegador sin cuenta: tus claves viven en su bóveda cifrada. Crear secretos a través de la API requiere API key, y todas las claves se quedan en el cliente: el servidor solo guarda el blob cifrado — crear cuenta · obtener API key

Postman Collection

API de Secretos

Secretos de un solo uso post‑cuánticos, cifrados de extremo a extremo. El servidor nunca ve el texto plano, la passphrase ni ninguna clave privada.

Arquitectura Zero‑Knowledge

Todo ocurre en el cliente: se encapsula una clave con ML‑KEM‑768 a la clave pública del destinatario, se combina (XOR) con otra que Scrypt deriva de la passphrase y el secreto se cifra con ChaCha20‑Poly1305. El servidor no acepta otro formato y solo guarda el blob cifrado.

Descargar Scripts

Tres scripts de shell que crean y abren secretos en el mismo formato que la web. Necesitan python3 con pqcrypto y cryptography, y curl: