Référence de l'API REST Zeuslock

Authentifiez-vous, listez les incidents, mettez à jour vos politiques et lancez des analyses synchrones via l'API REST Zeuslock. Exemples curl, Python et Node.js inclus.

URL de base et hébergement

Tous les endpoints REST de Zeuslock partagent la même base :

https://api.zeuslock.ai/v1

L'API mutualisée est hébergée en eu-west-3 (Paris). Les données clients, les incidents et la configuration ne quittent jamais l'Union européenne. Si vous utilisez l'édition souveraine, votre URL de base est un sous-domaine dédié — typiquement https://api.<tenant>.zeuslock.cloud/v1 — avec exactement les mêmes endpoints, payloads et comportements. Vous changez d'hôte, le reste est identique.

L'API ne parle que JSON sur HTTPS. Les requêtes en clair sont rejetées dès le edge. Toutes les connexions terminent en TLS 1.3 avec Perfect Forward Secrecy.

Authentification

Deux méthodes sont disponibles. Choisissez-en une par intégration ; ne les mélangez pas dans une même requête.

Clé API (serveur à serveur)

Les clés API sont la méthode par défaut pour l'automatisation backend, les intégrations SIEM, les pipelines CI/CD et les scripts. Créez-en une dans la console opérateur via Paramètres → Clés API, puis passez-la en bearer token :

curl -H "Authorization: Bearer zlsk_live_8f3c..." \
     https://api.zeuslock.ai/v1/incidents

Les clés sont préfixées par zlsk_live_ ou zlsk_test_ pour distinguer les environnements en un coup d'œil. Chaque clé a un scope explicite :

  • read-only — GET sur incidents, politiques, détecteurs.
  • incidents-write — mise à jour du statut et commentaires d'incident.
  • admin — création et modification de détecteurs, politiques et webhooks.

Les clés ne s'affichent qu'à la création. Faites-les tourner depuis la console ; la révocation est effective en moins de cinq secondes dans toutes les régions.

OAuth 2.0 (au nom de l'utilisateur)

Pour les intégrations UI agissant au nom d'un opérateur connecté, utilisez le flux standard authorization code avec PKCE. L'endpoint d'autorisation est https://app.zeuslock.ai/oauth/authorize et l'endpoint de token https://api.zeuslock.ai/v1/oauth/token. Les scopes calquent ceux des clés API. Les access tokens durent une heure et les refresh tokens sont rotés à chaque usage.

Limites de débit

Chaque clé API a droit à 60 requêtes par seconde soutenues et un burst de 600 req/s. Le bucket se recharge au rythme soutenu. Trois en-têtes accompagnent chaque réponse pour que votre client s'auto-régule :

  • X-RateLimit-Limit — plafond soutenu pour cette clé.
  • X-RateLimit-Remaining — requêtes restantes dans la fenêtre courante.
  • X-RateLimit-Reset — timestamp epoch de réinitialisation.

Une fois le bucket vide, l'API renvoie 429 Too Many Requests avec un en-tête Retry-After en secondes. Reculez de façon exponentielle ; ne réessayez jamais plus tôt que la valeur indiquée.

Vue d'ensemble des endpoints

MéthodeCheminUsageScope
GET/v1/incidentsLister les incidents (pagination par curseur)read-only
GET/v1/incidents/{id}Récupérer un incident complet avec contexte de prompt rédigéread-only
POST/v1/incidents/{id}/statusChanger le statut et ajouter un commentaireincidents-write
GET/v1/policiesLister les politiques activesread-only
PUT/v1/policies/{id}Mettre à jour une politique (avec dry-run)admin
GET/v1/detectorsLister les détecteurs personnalisésread-only
POST/v1/detectorsCréer un détecteur personnaliséadmin
POST/v1/scanAnalyse DLP synchrone d'un texte arbitraireread-only

Incidents

Lister les incidents

Retourne les incidents par ordre antichronologique avec pagination par curseur. Le champ next_cursor, lorsqu'il est présent, est opaque : renvoyez-le tel quel à l'appel suivant.

curl -H "Authorization: Bearer zlsk_live_8f3c..." \
     "https://api.zeuslock.ai/v1/incidents?since=2026-05-01T00:00:00Z&severity=high&limit=100"
import httpx

client = httpx.Client(
    base_url="https://api.zeuslock.ai/v1",
    headers={"Authorization": "Bearer zlsk_live_8f3c..."},
    timeout=30,
)

params = {"since": "2026-05-01T00:00:00Z", "severity": "high", "limit": 100}
while True:
    resp = client.get("/incidents", params=params)
    resp.raise_for_status()
    page = resp.json()
    for incident in page["items"]:
        print(incident["id"], incident["detector"], incident["severity"])
    if not page.get("next_cursor"):
        break
    params["cursor"] = page["next_cursor"]
import fetch from "node-fetch";

const base = "https://api.zeuslock.ai/v1";
const headers = { Authorization: "Bearer zlsk_live_8f3c..." };

let cursor;
do {
  const url = new URL(`${base}/incidents`);
  url.searchParams.set("since", "2026-05-01T00:00:00Z");
  url.searchParams.set("severity", "high");
  url.searchParams.set("limit", "100");
  if (cursor) url.searchParams.set("cursor", cursor);

  const res = await fetch(url, { headers });
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  const page = await res.json();
  for (const i of page.items) console.log(i.id, i.detector, i.severity);
  cursor = page.next_cursor;
} while (cursor);

Récupérer un incident

GET /v1/incidents/{id} renvoie l'incident complet, contexte de prompt inclus. Les correspondances sensibles sont rédigées par défaut (par exemple sk-***), avec les offsets pour reconstruire la visualisation dans votre outil.

Mettre à jour le statut

Faites avancer un incident dans votre workflow de triage. Valeurs valides : open, in_review, resolved et false_positive. Un passage en false_positive alimente le job de calibration des détecteurs qui tourne chaque nuit.

curl -X POST "https://api.zeuslock.ai/v1/incidents/inc_8c1f.../status" \
     -H "Authorization: Bearer zlsk_live_8f3c..." \
     -H "Content-Type: application/json" \
     -d '{"status":"resolved","comment":"Clé de test confirmée, rotation effectuée."}'

Politiques

GET /v1/policies liste toutes les politiques actives, avec le mode (monitor, anonymize ou block) par type de finding et les groupes d'utilisateurs concernés.

PUT /v1/policies/{id} met à jour une politique. Ajoutez ?dry_run=true pour valider le changement sur les sept derniers jours de trafic sans l'appliquer réellement — la réponse contient le diff des incidents qui auraient été créés, anonymisés ou bloqués. C'est la façon recommandée de passer de Monitor à Block.

resp = client.put(
    "/policies/pol_credentials",
    params={"dry_run": "true"},
    json={"findings": {"api_key": {"mode": "block"}}},
)
resp.raise_for_status()
print(resp.json()["dry_run_summary"])  # {"would_block": 12, "would_warn": 0, ...}

Détecteurs

Les détecteurs personnalisés capturent les identifiants spécifiques à votre organisation — matricules internes, numéros de référence clients, formats de tokens propriétaires. GET /v1/detectors les liste ; POST /v1/detectors en crée un. Chaque détecteur combine une regex et un ou plusieurs post-validateurs pour maintenir une précision élevée :

  • luhn — checksum de type carte bancaire.
  • mod97 — checksum de type IBAN.
  • entropy_gt — rejette les correspondances dont l'entropie de Shannon est sous un seuil (typiquement 4.5) pour éviter les chaînes d'exemple.
const body = {
  name: "identifiant_client_interne",
  regex: "\\bCUST-[A-Z0-9]{10}\\b",
  post_validators: [{ type: "entropy_gt", value: 4.5 }],
  severity: "medium",
  action: "anonymize"
};

const res = await fetch(`${base}/detectors`, {
  method: "POST",
  headers: { ...headers, "Content-Type": "application/json" },
  body: JSON.stringify(body)
});
console.log(await res.json());

Analyse synchrone

POST /v1/scan est le cheval de bataille pour les jobs CI/CD et les tâches batch. Envoyez du texte brut, recevez les findings en un aller-retour. Les requêtes sont plafonnées à 1 Mo avec un timeout de 30 secondes ; pour des payloads plus gros, découpez côté client ou utilisez l'endpoint batch asynchrone (couvert dans un doc séparé).

curl -X POST "https://api.zeuslock.ai/v1/scan" \
     -H "Authorization: Bearer zlsk_live_8f3c..." \
     -H "Content-Type: application/json" \
     -d '{"text":"Connexion via AKIAIOSFODNN7EXAMPLE et mot de passe hunter2","detectors":["api_key","password"]}'
payload = {"text": open("build.log").read(), "detectors": ["api_key", "private_key", "jwt"]}
findings = client.post("/scan", json=payload).json()["findings"]
if findings:
    raise SystemExit(f"Build échoué : {len(findings)} secrets détectés")

Erreurs

Toutes les erreurs utilisent la même enveloppe JSON pour faciliter le logging et le routage :

{
  "error": {
    "code": "invalid_scope",
    "message": "Cette clé API est en lecture seule et ne peut pas modifier les politiques.",
    "request_id": "req_01HX9YJ3K4M5N6P7Q8R9S0T1U2"
  }
}

Citez toujours request_id lorsque vous contactez le support. Codes HTTP courants :

  • 400 Bad Request — JSON malformé ou champ requis manquant.
  • 401 Unauthorized — bearer token absent ou invalide.
  • 403 Forbidden — token valide mais scope insuffisant.
  • 404 Not Found — ressource inconnue ou hors de votre tenant.
  • 422 Unprocessable Entity — structure valide mais valeurs invalides (regex incorrecte, transition de statut interdite).
  • 429 Too Many Requests — respectez Retry-After.
  • 500 Internal Server Error — retry sûr avec backoff exponentiel.

Webhooks

Pour la livraison push des incidents vers Slack, Splunk HEC, PagerDuty ou Microsoft Sentinel, configurez un webhook dans la console opérateur. Consultez le doc Webhooks pour le schéma de payload et la vérification de signature HMAC.

Épinglez la version d'API via un en-tête (X-Zeuslock-API-Version: 2026-05-01) dès qu'elle est disponible dans votre tenant. Cela fige la forme des réponses pour cette intégration : les évolutions additives futures ne casseront pas votre parseur.