API v1
Base: https://eclair.kayzen-lyon.com/api/v1. JSON ovunque, risposte mai memorizzate in cache. I dati binari sono in base64url senza padding. openapi.json
Regola d'oro: cifrare prima di chiamare l'API. Non inviare mai la chiave del link, il PIN né il testo in chiaro. Il modo più semplice è usare il nostro client JavaScript (pacchetto api-client) o la CLI.
Route
| Metodo | Route | Finalità |
|---|---|---|
POST | /secrets | Stocker un secret déjà chiffré |
POST | /secrets/{id}/preview | Libellé chiffré et indicateurs, sans le contenu |
POST | /secrets/{id}/reveal | Révéler (consomme une lecture) |
GET | /manage/{id} | Statut et historique (accusé de lecture) |
DELETE | /manage/{id} | Détruire avant lecture |
POST | /uploads | Ouvrir un envoi de fichiers chiffrés |
POST | /uploads/{id}/parts | URL présignée (5 min) pour une partie |
POST | /requests | Créer une demande de secret (lien de dépôt) |
POST | /requests/{id}/deposits | Déposer un contenu chiffré pour le demandeur |
GET | /requests/{id}/deposits | Lister les dépôts (demandeur) ou vérifier que le lien est ouvert (sans jeton) |
DELETE | /requests/{id} | Fermer la demande et supprimer les dépôts |
POST | /abuse | Signaler un lien abusif |
POST | /webhooks | Enregistrer un webhook https |
DELETE | /webhooks/{id} | Supprimer un webhook |
POST | /domains | Réserver un domaine personnalisé |
GET | /domains/{domain} | État d'un domaine |
POST | /domains/{domain} | Vérifier l'enregistrement TXT et rattacher le domaine |
DELETE | /domains/{domain} | Libérer le domaine |
GET | /config | Limites de l'instance |
GET | /health | Santé du service |
Esempio (TypeScript, cifratura locale)
import { sendSecret, parseSecretLink, receiveSecret } from "@sesame-eclair/api-client";
const options = { baseUrl: "https://eclair.kayzen-lyon.com" };
// Encrypts in this process, then uploads only the ciphertext.
const sent = await sendSecret(options, {
content: { v: 1, type: "text", text: "DB_PASSWORD=..." },
views: 1,
ttlSeconds: 3600,
});
if (sent.ok) console.log(sent.url, sent.manageUrl);
// Recipient side: the key comes from the link fragment.
const link = parseSecretLink(sent.ok ? sent.url : "")!;
const received = await receiveSecret(options, link);Codici di stato
404— stessa risposta per segreti sconosciuti, scaduti, già letti o distrutti.401— PIN errato, con attemptsLeft.403— access_denied: la rete o il paese di chi legge non rispetta le restrizioni del segreto. Il segreto resta intatto.423— non ancora leggibile (rivelazione differita), con availableAt.429— troppe richieste, riprovi tra un'ora.
Webhook
Registri un URL https con POST /webhooks, poi passi webhookId alla creazione del segreto. Riceverà { event, secretId, at } per created, revealed, burned, revoked ed expired: mai il contenuto. Il signingSecret viene mostrato una sola volta; verifichi ogni chiamata in questo modo:
import { createHmac, timingSafeEqual } from "node:crypto";
// header = request.headers["eclair-signature"], body = raw request body (string)
function verify(header: string, body: string, signingSecret: string): boolean {
const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")));
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false; // replay window
const expected = createHmac("sha256", Buffer.from(signingSecret, "base64url"))
.update(`${t}.${body}`)
.digest();
return timingSafeEqual(expected, Buffer.from(v1, "hex"));
}Restrizioni di accesso
accessRules: { cidrs: ["203.0.113.0/24"], countries: ["FR"] } limita l'apertura a determinate reti o paesi (al massimo 20 voci ciascuno). La verifica avviene prima di qualsiasi invio del testo cifrato; un paese sconosciuto viene rifiutato non appena esiste una regola sui paesi.
Dominio personalizzato
POST /domains rivendica un dominio e restituisce un record TXT di verifica e un CNAME. Una volta creati, POST /domains/{domain} verifica il TXT e collega il dominio; il certificato TLS viene emesso automaticamente. La pagina Dominio personalizzato fa tutto questo per Lei.