Skip to content
Aa

Security events

Security events confirm web application firewall (WAF) actions for the selected virtual host. The API returns events as JSON-encoded strings; decode each string to read the event fields.

Query XCSH_NAMESPACE and the discovered XCSH_VIRTUAL_HOST over the 24-hour XCSH_START_24H–XCSH_END_TIME window. Select action="block" and at most three events; the current demo requires its WAF and rejection traffic.

  1. Build a virtual-host and block-action query.

    Terminal window
    XCSH_EVENT_QUERY="$(jq -nr --arg vh "<XCSH_VIRTUAL_HOST>" \
    '"{vh_name=\"" + $vh + "\",action=\"block\"}"')"
    XCSH_REQUEST="$(jq -nc --arg ns "<XCSH_NAMESPACE>" --arg start "$XCSH_START_24H" \
    --arg end "$XCSH_END_TIME" --arg query "$XCSH_EVENT_QUERY" '{
    namespace: $ns, start_time: $start, end_time: $end,
    limit: 3, sort: "DESCENDING", query: $query
    }')"
  2. Query the events.

    Terminal window
    curl --silent --show-error --fail-with-body --request POST \
    --header "Authorization: APIToken <XCSH_API_TOKEN>" \
    --header 'Content-Type: application/json' \
    --data-binary "$XCSH_REQUEST" \
    "<XCSH_API_URL>/api/data/namespaces/<XCSH_NAMESPACE>/app_security/events" |
    jq -er --arg ns "<XCSH_NAMESPACE>" --arg vh "<XCSH_VIRTUAL_HOST>" '{
    total_hits: (.total_hits | tonumber),
    returned: (.events | length),
    events: [.events[]? | (if type == "string" then fromjson else . end)
    | select(.namespace == $ns and .vh_name == $vh)
    | {time, namespace, vh_name, action, sec_event_type,
    sec_event_name, rsp_code, app_firewall_name}]
    }'

Captured 2026-10-06T03:13:55Z; HTTP 200.

{
"total_hits": 135,
"returned": 3,
"events": [
{
"time": "2026-10-06T03:12:02.413Z",
"namespace": "<XCSH_NAMESPACE>",
"vh_name": "<XCSH_VIRTUAL_HOST>",
"action": "block",
"sec_event_type": "waf_sec_event",
"sec_event_name": "WAF",
"rsp_code": "200",
"app_firewall_name": "<XCSH_WAF_NAME>"
},
{
"time": "2026-10-06T03:07:02.531Z",
"namespace": "<XCSH_NAMESPACE>",
"vh_name": "<XCSH_VIRTUAL_HOST>",
"action": "block",
"sec_event_type": "waf_sec_event",
"sec_event_name": "WAF",
"rsp_code": "200",
"app_firewall_name": "<XCSH_WAF_NAME>"
},
{
"time": "2026-10-06T03:02:03.054Z",
"namespace": "<XCSH_NAMESPACE>",
"vh_name": "<XCSH_VIRTUAL_HOST>",
"action": "block",
"sec_event_type": "waf_sec_event",
"sec_event_name": "WAF",
"rsp_code": "200",
"app_firewall_name": "<XCSH_WAF_NAME>"
}
]
}

Expect total_hits and matching events with action: "block" and an application firewall name. total_hits can exceed the first three returned events; use the scroll API for complete exports.

Security-event metrics aggregate counters separately from the event-log API above. Select XCSH_NAMESPACE and XCSH_VIRTUAL_HOST over the fixed two-hour window, grouped by VH_NAME and SEC_EVENT_TYPE.

  1. Build a namespace and virtual-host metrics selector for the fixed two-hour window.

    Terminal window
    XCSH_REQUEST="$(jq -nc --arg ns "<XCSH_NAMESPACE>" --arg start "$XCSH_START_TIME" \
    --arg end "$XCSH_END_TIME" --arg vh "<XCSH_VIRTUAL_HOST>" '{
    namespace: $ns, start_time: $start, end_time: $end,
    step: "5m", group_by: ["VH_NAME", "SEC_EVENT_TYPE"],
    label_filter: [{label: "VH_NAME", op: "EQ", value: $vh}]
    }')"
  2. Query security-event metrics.

    Terminal window
    curl --silent --show-error --fail-with-body --max-time 60 --request POST \
    --header "Authorization: APIToken <XCSH_API_TOKEN>" \
    --header 'Content-Type: application/json' \
    --data-binary "$XCSH_REQUEST" \
    "<XCSH_API_URL>/api/data/namespaces/<XCSH_NAMESPACE>/app_security/metrics" |
    jq -er '{data, step}'

The namespace security-event metrics query at 2026-10-06T03:12:47Z returned HTTP 200 with no counters. Its two-hour selector used group_by: ["VH_NAME", "SEC_EVENT_TYPE"] and filtered VH_NAME to the discovered virtual host.

{
"data": [],
"step": "5m"
}

This empty metric response does not contradict populated WAF counters or authoritative block-event logs. Treat it and the empty connection series as unavailable telemetry until meaningful points are captured.