API y Webhooks de Aona
Lea sus eventos de seguridad a través de REST y recíbalos como webhooks firmados. Ambas superficies utilizan el formato OCSF (Open Cybersecurity Schema Framework) para que Sentinel, Splunk y Amazon Security Lake puedan ingerirlos de forma nativa. Los campos específicos de Aona se conservan en enrichments[].
Inicio rápido
Cree una clave en el panel en /api-keys con el alcance events:read y luego:
curl -H "X-Api-Key: aona_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
https://api.aona.ai/v1/eventsLa respuesta está paginada por keyset: pase el next_cursor devuelto como ?cursor= en la siguiente solicitud. Los cursores son opacos y firmados, no los construya a mano.
Verificar webhooks, Node.js
Aona firma cada webhook con HMAC-SHA256. Verifique antes de analizar el cuerpo JSON:
import { createHmac, timingSafeEqual } from "node:crypto";
/**
* Verify an Aona webhook delivery.
*
* const ok = verifyAonaWebhook({
* header: req.headers["x-aona-signature"],
* body: rawRequestBody, // string, before JSON.parse
* secret: process.env.AONA_WEBHOOK_SECRET,
* previousSecret: process.env.AONA_WEBHOOK_SECRET_PREVIOUS, // optional during rotation
* toleranceSeconds: 300,
* });
*/
export function verifyAonaWebhook({
header,
body,
secret,
previousSecret,
toleranceSeconds = 300,
}) {
if (typeof header !== "string") return false;
// Parse "t=<unix>,v1=<hex>"
let t = null, v1 = null;
for (const part of header.split(",")) {
const [k, v] = part.split("=");
if (k === "t") t = Number(v);
else if (k === "v1") v1 = v;
}
if (!t || !v1 || !/^[0-9a-f]{64}$/i.test(v1)) return false;
if (Math.abs(Math.floor(Date.now() / 1000) - t) > toleranceSeconds) return false;
const payload = `${t}.${body}`;
const tryVerify = (s) => {
const expected = createHmac("sha256", s).update(payload).digest("hex");
try {
return timingSafeEqual(Buffer.from(v1, "hex"), Buffer.from(expected, "hex"));
} catch {
return false;
}
};
if (tryVerify(secret)) return true;
if (previousSecret && tryVerify(previousSecret)) return true;
return false;
}Verificar webhooks, Python
import hmac
import hashlib
import time
def verify_aona_webhook(header: str, body: str, secret: str,
previous_secret: str | None = None,
tolerance_seconds: int = 300) -> bool:
"""Verify an Aona webhook delivery.
Pass the raw request body (bytes-or-string before JSON.parse) — the
signature is computed over the wire payload, not the parsed dict.
"""
if not isinstance(header, str):
return False
parsed = dict(part.split("=", 1) for part in header.split(",") if "=" in part)
try:
t = int(parsed["t"])
v1 = parsed["v1"]
except (KeyError, ValueError):
return False
if not (len(v1) == 64 and all(c in "0123456789abcdefABCDEF" for c in v1)):
return False
if abs(int(time.time()) - t) > tolerance_seconds:
return False
payload = f"{t}.{body}".encode("utf-8")
def _try(s: str) -> bool:
expected = hmac.new(s.encode("utf-8"), payload, hashlib.sha256).hexdigest()
return hmac.compare_digest(v1.lower(), expected.lower())
if _try(secret):
return True
if previous_secret and _try(previous_secret):
return True
return FalseRotación de secretos (sin tiempo de inactividad)
Cuando rota el secreto de firma de un webhook en el panel, el secreto anterior sigue siendo válido durante 24 horas. Durante esa ventana, ambos secretos se verifican correctamente. El patrón recomendado se muestra en el código de verificación anterior: pruebe primero el secreto actual y luego recurra al anterior si lo tiene. Actualice su entorno con el nuevo secreto y retire el anterior cuando le convenga.
Protección contra reenvíos
El componente t= de X-Aona-Signature es la marca de tiempo en segundos unix en la que firmamos la carga útil. El verificador rechaza las entregas en las que |now - t| > toleranceSeconds (5 minutos por defecto). No lo relaje sin motivo, es lo único que le protege de que alguien reenvíe una carga útil interceptada.
Idempotencia
Cada entrega incluye X-Aona-Delivery: <uuid>. Si una entrega supera el tiempo de espera y la reintentamos, enviamos el mismo identificador. Deduplique según él para una garantía de «al menos una vez», los receptores que lo almacenan en una pequeña caché acotada nunca actuarán dos veces sobre el mismo evento.
Referencia de eventos OCSF
Los eventos de Aona se ajustan a OCSF class_uid 6005 (Application Activity / Web Resources Activity). Los campos propios de Aona aparecen dentro de enrichments[] con tipos explícitos.
{
"id": "01J5e2-uuid-...",
"version": "2026-05-23",
"class_uid": 6005,
"category_name": "Application Activity",
"activity_name": "Access",
"time": "2026-05-22T14:08:12.314Z",
"actor": { "user": { "uid": "f6c1...-uuid" } },
"app": { "name": "Aona", "uid": "chat-gpt-platform-uuid" },
"type_name": "policy_violation",
"disposition": "BLOCK",
"metadata": {
"product": { "name": "Aona Workforce AI Security" },
"tenant_uid": "your-business-uuid"
},
"enrichments": [
{ "name": "data_security_risk", "value": 0.83, "type": "numeric" },
{ "name": "data_privacy_risk", "value": 0.41, "type": "numeric" },
{ "name": "policy_id", "value": "policy-uuid", "type": "uid" },
{ "name": "action", "value": "BLOCK", "type": "string" },
{ "name": "chat_id", "value": "abc-123", "type": "string" }
]
}Para el esquema completo, consulte la especificación OpenAPI (JSON legible por máquina en /v1/docs-json).
Códigos de estado y límites de tasa
200, éxito.400, solicitud incorrecta (cursor no válido, parámetro de consulta mal formado).401,X-Api-Keyausente, revocada, caducada o no válida. Devolvemos deliberadamente el mismo cuerpo para los cuatro casos.403, su plan no incluye acceso a la API, o a su clave le falta un alcance requerido.404, evento no encontrado (o pertenece a otro inquilino, no hacemos distinción).429, límite de tasa superado. InspeccioneX-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-ResetyRetry-After.
Notas de seguridad
- Solo HTTPS. No entregamos a URL
http://. - Las IP de bucle local y privadas se rechazan en el momento de la creación Y en el de la entrega (fijación de DNS) para evitar SSRF.
- Los certificados TLS autofirmados no superan la verificación, utilice un certificado real.
- Las cargas útiles de los webhooks contienen solo metadatos. El contenido de las indicaciones, el texto de redacción y otro contenido del usuario nunca salen de Aona a través de la API ni de los webhooks.
- Verificación del certificado, sin redirecciones, tiempo de espera de 10 s, límite de respuesta de 1 MiB.