Six streams. Six places to look.
Every meaningful action on the platform writes to at least one of six logs. This page enumerates what each log captures, where it lives, and how to get yours. The most important one - the platform audit log - is hash-chained so silent edits are detectable.
The streams
Where: pino-http → stdout → Docker → /data/LOG
Coverage: Every API request
Fields: method, path, status, latency, IP, user-agent, request ID
Access: On request for your tenant; aggregated metrics on /metrics
Operational debugging, latency SLO measurement, abuse detection.
Where: grants_audit.platform_audit_log
Coverage: Security-relevant events: signin / signup / failed signin / MFA, attestation issued, disbursement reported, council vote, registry inclusion submitted, recovery action, billing cycle event, webhook delivery attempt.
Fields: log_id, prev_hash, this_hash, actor_user_id, action, resource_type, resource_id, outcome, payload, recorded_at
Access: Foundation-scoped subset on request; full table accessible to JIL operations + auditor users.
Tamper-evident chain. Each row's this_hash includes the previous row's hash, so silent edits are detectable.
Where: grants_audit.application_events
Coverage: Application created, submitted, pre-cleared, decided
Fields: application_id, event_type, actor_user_id, payload, recorded_at
Access: Foundation sees its own; grantee sees their own
Per-application timeline used in the reviewer console and grantee status page.
Where: grants_audit.grant_events
Coverage: Grant created, milestone submitted, milestone approved, disbursement authorized, grant closed
Fields: grant_id, event_type, actor_user_id, payload, recorded_at
Access: Foundation + grantee scoped
Per-grant timeline used in CREB attestation packages.
Where: grants_grant.disbursements (webhook_attempts, webhook_last_error, webhook_next_attempt_at columns)
Coverage: Every outbound webhook delivery attempt
Fields: attempt count, last error, next retry at, settled at
Access: Foundation sees its own
Backoff retry [60s, 5m, 30m, 2h, 12h]. Visible to confirm delivery to your endpoint.
Where: GET /metrics on grants-api
Coverage: process_*, nodejs_*, http_request_duration_seconds histogram, http_requests_total counter
Fields: labels: method, route (matched pattern), status, service
Access: Operational scrape; aggregated across tenants
Latency SLO tracking, error-rate alerting, capacity planning.
Hash-chained audit - what that means
Each row ingrants_audit.platform_audit_logcarries the SHA-256 hash of the previous row'sthis_hash concatenated with this row's payload. Rebuild the chain from row 1 forward and the current head matches; tamper with any row in the middle and every subsequent hash diverges.
row 1: prev_hash = NULL,
this_hash = sha256(NULL || payload₁)
row 2: prev_hash = this_hash₁,
this_hash = sha256(this_hash₁ || payload₂)
row 3: prev_hash = this_hash₂,
this_hash = sha256(this_hash₂ || payload₃)
...
row N: prev_hash = this_hash_{N-1},
this_hash = sha256(this_hash_{N-1} || payload_N)How to get yours
In-portal
Foundation accounts can view application events and grant events directly in the reviewer and grant detail pages. Sign in to your account.
API
Pull your platform-audit-log slice via the API. Filterable by action, resource_type, recorded_at range. JSON or CSV export. See API docs →
On-demand SAR
Subject Access Request: written request to[email protected]. Response within 30 days perData Protection Addendum.
Want a verifier walkthrough?
For auditors and regulators, we provide a dedicated walkthrough of the chain-verification tool plus a static export of the audit log for the period in scope. By appointment.
Request a walkthrough →