Skip to content

GLog — the two ways to integrate

GLog is the gStack centralized, tamper-evident audit/logging building block. There are exactly two ways to work with it, and most deployments use both:

A. Headless (machine → API)B. The Board (human → UI)
Whoyour service/backendoperators, auditors, security teams
HowPOST/GET the REST API (or an SDK)log in to the web app and browse
Purposeemit audit events, query them programmaticallyinvestigate: search, correlate, integrity, transparency
AuthJWT — service token (client-credentials) or GLog HS512JWT — Keycloak login (PKCE) or GLog username/password
Entry pointhttps://glog.gstack.esempla.systems/api/v1/...https://glog.gstack.esempla.systems
Docsthis file §1, integration-guide.md, api.md, sdk.mdthis file §2, using-the-board.md

Both talk to the same backend and the same immutable store (SHA-256 hash chain per (tenant, service)). The Board is just a read client over the API. Authentication for both is JWT — see §3 and auth-and-integrations.md for the full picture.


1. Method A — Headless (service integration)

Section titled “1. Method A — Headless (service integration)”

Your service sends one HTTP call per audit event; no UI, no human. This is how GPay, GPass, GNotify, GRegistry etc. report what they do.

Emit an event

Terminal window
curl -X POST https://glog.gstack.esempla.systems/api/v1/app/audit-events \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"tenantId": "demo",
"service": "gnotify",
"operation":"NOTIFICATION_SENT",
"status": "SUCCESS",
"actor": { "type": "SERVICE", "id": "gnotify" },
"object": { "type": "NOTIFICATION", "id": "trk-123" },
"correlationId": "corr-abc",
"occurredAt": "2026-07-30T10:00:00Z",
"details": { "channel": "email" }
}'

GLog stores it immutably and returns the persisted event (with its hash and prevHash).

Query events

Terminal window
curl "https://glog.gstack.esempla.systems/api/v1/app/audit-events?tenantId=demo&service=gnotify&from=2026-07-30T00:00:00Z&size=50" \
-H "Authorization: Bearer $TOKEN"
  • How it works headless: GLog is a stateless OAuth2 resource server. It authorizes on audit:read / audit:write / audit:admin scopes and enforces tenant isolation (the tenant claim in the token must equal the tenantId in the request). Retries are safe with an Idempotency-Key. Ingest can run fully async (RabbitMQ) or synchronously.
  • SDKs wrap all of this in one call (token handling, retries, typed builders): Java (Maven), Node (npm), PHP (Composer) — see sdk.md.
  • Full field/endpoint reference: api.md. Copy-paste recipes (curl / Java / PHP / Python / Node): integration-guide.md.

A human opens https://glog.gstack.esempla.systems, authenticates, and investigates the audit trail visually — no code. The Board covers monitoring (dashboard, log search, correlated flows), analysis (services, transparency), and compliance (integrity, archive) plus admin.

Full walkthrough of every screen, filters, and workflows: using-the-board.md.


GLog only ever sees a JWT bearer token; it validates it and reads scope + tenant. Which issuer minted it depends on the caller:

CallerFlowTokenIssuer
Service (headless)OAuth2 client-credentialsRS256Keycloak realm interdictii, confidential client (e.g. glog-ingest)
Human (Board)Keycloak PKCE loginRS256Keycloak realm interdictii, public client glog-web
Human/Service (no Keycloak)GLog username/passwordHS512GLog itself (iss=glog-localauth)

The live demo runs the dualauth profile: it accepts both RS256 (Keycloak) and HS512 (GLog) tokens, routed by the token’s iss claim. Exactly what to create in Keycloak and why: auth-and-integrations.md.

Minimal example — get a service token, then post:

Terminal window
TOKEN=$(curl -s -X POST "$KC/realms/interdictii/protocol/openid-connect/token" \
-d grant_type=client_credentials -d client_id=glog-ingest -d client_secret=$SECRET \
| jq -r .access_token)
curl -X POST https://glog.gstack.esempla.systems/api/v1/app/audit-events \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{...}'