Skip to content

Use case: time-travel audit & compliance snapshots

Every fact in little big brain is append-only and carries its own provenance, so the graph already is an audit log and you do not build a separate one. To answer a compliance question like “who had access to customer PII on 2026-06-15?” you read the graph as it was at that point in time, and every read echoes back the exact snapshot it ran against, so the result stays citable.

This guide builds a small audit and compliance viewer on two primitives.

  1. The bitemporal cursor pins any read to a past commit (as_of_commit_seq) or a past instant (as_of_valid_time).

  2. Run a compliance query at a past commit. Pin a SPARQL query with as_of_commit_seq. The response echoes the pin, so the result set and its watermark can be stored together as one audit record.

    Terminal window
    curl -sS -X POST "https://0abc1def--production.db.eu.littlebigbrain.com/v1/query/sparql-text?graph=main" \
    -H "Authorization: Bearer $LBB_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"query":"SELECT ?service WHERE { ?service <https://littlebigbrain.com/r/had_access_to> ?pii }","as_of_commit_seq":96}'

    A pin past head is an invalid_input error, so a stale pin is never silently served as a head read.

  3. Reproduce one entity’s state as-of that commit. The same pin works on the point-read surfaces, so you can read exactly what the graph held about a single subject. POST /v1/query/state returns the entity’s current relations at the pinned commit, and POST /v1/query/transitions traces one status relation’s history.

    Terminal window
    curl -sS -X POST "https://0abc1def--production.db.eu.littlebigbrain.com/v1/query/state?graph=main" \
    -H "Authorization: Bearer $LBB_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"entity": {"type": "SERVICE", "name": "billing-service"},
    "relations": ["HAS_ACCESS_TO"],
    "as_of_commit_seq": 96}'

    Request-time SHACL shape selection is not a query surface. Treat published conformance as its own versioned artifact, as described next.

  4. Record published conformance separately. Read GET /v1/ontology/conformance and store its validated_at_seq, ontology version, and shapes version with the audit. Validation is a durable maintenance artifact, and the HTTP request never revalidates an arbitrary past snapshot. A strong request returns strong_read_pending until the report matches head.

    Terminal window
    curl -sS "https://0abc1def--production.db.eu.littlebigbrain.com/v1/ontology/conformance?graph=main&consistency=strong" \
    -H "Authorization: Bearer $LBB_API_KEY"
  5. Stream the change-log between two points. GET /v1/graph/changes returns everything committed since a commit seq: entities, observations, and edge_events with an op of assert, retract, supersede, confidence_update, or annotation. This is the diff and audit trail: the record of what access was granted and what was revoked between two dates. There is no dedicated SDK method, so call the endpoint directly and honor truncated and next_since.

    Terminal window
    curl -sS "https://0abc1def--production.db.eu.littlebigbrain.com/v1/graph/changes?graph=main&branch=main&since=64&limit=500" \
    -H "Authorization: Bearer $LBB_API_KEY"

    A single response looks like:

    {
    "from_commit_seq": 64,
    "to_commit_seq": 96,
    "entities": [ { "id": "...", "type": "SERVICE", "name": "billing-service", "commit_seq": 71 } ],
    "observations": [ { "id": "...", "commit_seq": 88, "text": "access review note" } ],
    "edge_events": [ {
    "edge_event_id": "...", "source": "SERVICE", "source_id": "...",
    "relation": "HAS_ACCESS_TO", "target": "DATASET", "target_id": "...",
    "op": "retract", "commit_seq": 90
    } ],
    "next_since": 96,
    "snapshot_token": "...",
    "truncated": false,
    "reset": false
    }

    Because a large window can be paged, keep calling with since=next_since while truncated is true:

    async function auditTrail(since: number) {
    const base = "https://0abc1def--production.db.eu.littlebigbrain.com/v1/graph/changes";
    const headers = { Authorization: `Bearer ${process.env.LBB_API_KEY}` };
    const events: unknown[] = [];
    let truncated = true;
    while (truncated) {
    const url = `${base}?graph=main&branch=main&since=${since}&limit=500`;
    const page = await fetch(url, { headers }).then((r) => r.json());
    events.push(...page.edge_events);
    since = page.next_since; // advance the cursor
    truncated = page.truncated; // stop when the window is drained
    }
    return events;
    }

    Filter the collected edge_events by op to separate grants (assert) from revocations (retract / supersede), and you have a per-relation change history for the review period. A response with reset: true means next_since is no longer valid, so re-read from the start.

  • The graph is the audit log. Facts are append-only with provenance, so a point-in-time question is answered by a read. Nothing is overwritten: a revoked grant becomes a retract edge event and the earlier grant stays on the record.
  • Pins are exact while retained. as_of_commit_seq selects one immutable generation and every response echoes the pin in snapshot.as_of_commit_seq. The server never substitutes a nearby generation. SPARQL retains the current generation plus 15 predecessors by default; outside that window it returns historical_generation_unavailable.
  • Two clocks, one cursor. as_of_commit_seq answers “what was recorded at commit N?” and as_of_valid_time answers “what was true in the world at time T?” Compliance questions usually need valid-time, the state on the date of record. Reproducing a specific past query uses the commit pin.