Reference
API reference
When you start the service with --api-port, it answers on a small local HTTP API. Responses are JSON. The API reports the state of the most recent tick, serves the journal, and accepts webhook events.
curl http://127.0.0.1:8787/status#Base URL
http://<api-host>:<api-port>, where --api-host defaults to 127.0.0.1. The API is off until you set --api-port.
#GET /status
Returns counts from the last tick and whether it blocked. It is empty until the first tick finishes.
{
"blocked": true,
"insights": 2,
"findings": 3,
"actions": 1,
"t": 1793000000.123
}| Field | Meaning |
|---|---|
blocked | true if any action in the tick was a block. |
insights | Number of connector insights in the tick. |
findings | Number of scanner findings in the tick. |
actions | Number of actions the policy chose. |
t | Unix time when the tick finished. |
#GET /findings
Returns the scanner findings from the last tick.
[
{
"check": "zero_click",
"severity": "critical",
"path": "webhook_handler.py",
"line": 4,
"message": "unsafe deserialization sink (zero-click RCE vector)"
}
]#GET /insights
Returns the insights from the last tick, plus any received through webhooks since then.
[
{
"connector": "siem-alerts",
"kind": "alert",
"title": "Impossible travel for a service account",
"severity": "high",
"source_id": "a-4821",
"observed_at": 1793000000.1,
"detail": {}
}
]#GET /journal
Returns the last rows of the journal. Use n to choose how many. The default is 100.
curl "http://127.0.0.1:8787/journal?n=20"Each row has a kind of tick, finding, insight, action or kernel-error, and a t timestamp.
#POST /webhook/{source}
Sends an event for inspection. The body is JSON. Kelvar scans the raw body for zero-click sinks and for the same secret patterns that the secrets check uses. If either matches, the severity is set to the matched rule's severity. Otherwise it uses severity from the payload, or info.
curl -X POST http://127.0.0.1:8787/webhook/okta \
-H "Content-Type: application/json" \
-d '{"event": "user.session.start", "severity": "low"}'The response says whether Kelvar blocked the event. A severity of high or critical means block, and anything lower means pass.
{
"ok": true,
"verdict": "pass",
"insight": {
"connector": "webhook:okta",
"kind": "signal",
"title": "user.session.start",
"severity": "low",
"source_id": "wh-1793000000123",
"observed_at": 1793000000.123,
"detail": { "verdict": "pass", "matched_rule": null, "payload": {} }
}
}| Field | Meaning |
|---|---|
verdict | block or pass. |
insight.detail.matched_rule | The rule that matched, or null. |
insight.title | The payload's title or event. A match replaces it with a description of the block. |
Every webhook is appended to the journal as an insight, and a block is appended as an action as well.
#Errors
An unknown path returns status 404 with {"error": "not found"}. A request body that is not valid JSON is wrapped as {"raw": "<body>"} and still inspected.