VxCloud
📡Advanced20 minSecurity

Stream audit events to Splunk / Datadog

Pull the audit event stream, deduplicate with its hash chain, and forward to your SIEM — with a copy-paste worker in plain Node.js.

What you'll build

  • A worker that pages the audit API and forwards to a SIEM
  • Hash-chain dedup so reconnects don’t double-count
  • Filtered streams (e.g. only critical / prod deploys)

Before you begin

  • A workspace with SSO/RBAC configured (so events have real actors)
  • A Splunk HEC token or Datadog API key
  • Node.js 18+ wherever the worker will run
1

Understand the audit endpoint

Audit events are read from GET /api/v3/audit/events. It’s a filterable, paginated feed — you poll forward with offset / next_offset.

query params
category=provision|deploy|login|apikey|vault|billing
severity=info|warning|critical
actor=<username>      from=<ISO8601>   to=<ISO8601>
q=<free text>         limit=1..1000    offset=<int>

Each event carries hash and prev_hash — hash = sha256(prev_hash + id + timestamp + actor). That chain is how you dedup and how you detect tampering.

2

Page through events

Poll with a stored cursor. The response tells you when to stop and where to resume:

audit feed
$ curl ".../api/v3/audit/events?severity=critical&limit=200&offset=0"
{"count":200,"has_more":true,"next_offset":200,"data":[…]}
$ curl ".../api/v3/audit/events?severity=critical&offset=200"
{"count":47,"has_more":false,"next_offset":247,"data":[…]}
caught up — persist next_offset and sleep
Persist next_offset durably so a worker restart resumes, not replays from zero.
3

Deduplicate with the hash chain

Reconnects and overlapping windows will re-deliver events. Keep a bounded set of recently seen hash values and drop repeats before forwarding — this is what stops your SIEM double-counting a prod deploy:

dedup.js
const seen = new Set();           // bounded LRU in production
function isNew(ev) {
  if (seen.has(ev.hash)) return false;
  seen.add(ev.hash);
  if (seen.size > 50_000) seen.delete(seen.values().next().value);
  return true;
}

Verify the chain too

For tamper-evidence, also assert each event’s prev_hash equals the previous event’s hash. A break means events were dropped or altered upstream — alert on it.
4

Forward to your SIEM

A complete, dependency-free worker — point it at Splunk HEC or Datadog and run it anywhere:

audit-forwarder.js
const BASE = process.env.VXCLOUD_BASE;
const TOKEN = process.env.VXCLOUD_TOKEN;       // xc_live_… read key
const SIEM = process.env.SPLUNK_HEC_URL;
let offset = Number(process.env.START_OFFSET || 0);

async function tick() {
  const r = await fetch(`${BASE}/api/v3/audit/events?limit=500&offset=${offset}`,
    { headers: { Authorization: `Bearer ${TOKEN}` } });
  const { data, has_more, next_offset } = await r.json();

  for (const ev of data) {
    if (!isNew(ev)) continue;
    await fetch(SIEM, {
      method: 'POST',
      headers: { Authorization: `Splunk ${process.env.HEC_TOKEN}` },
      body: JSON.stringify({ event: ev, sourcetype: 'vxcloud:audit' }),
    });
  }
  offset = next_offset;
  setTimeout(tick, has_more ? 0 : 15_000);     // drain fast, then idle
}
tick();
Deployment progress100%
  • Fetch page (cursor at offset)30%
  • Dedup via hash chain55%
  • POST to Splunk HEC / Datadog85%
  • Persist next_offset, idle 15s100%
Drain-then-idle keeps latency low without hammering the API when quiet.

Audit trail in your SIEM

Every privileged action — deploys, key issuance, Vault reads, logins — now lands in Splunk/Datadog, deduped and tamper-evident. That closes the loop started in the SSO & RBAC tutorial.

Nice work — you're done!

You completed Stream audit events to Splunk / Datadog. Keep the momentum going with the next walkthrough, or jump back to the full catalog.