Persistence
Kernite core evaluation is dependency-free and stateless by default. It does not write to your database automatically. Kernite can emit decision events when you use controlled evaluation with a configured sink (jsonl, csv, sqlite).
In production, still treat evidence persistence as an app-level responsibility: capture the decision contract from evaluate_execute(...), evaluate_execute_controlled(...), or POST /execute and write it to a durable sink (DB, object storage, log pipeline, etc.).
Why persist governance evidence
Persisting governance evidence enables:- Auditability: reproduce what was evaluated and why for any write attempt.
- Security posture reporting: quantify what was blocked (deny events) and why.
- Operational debugging: reason codes and trace hashes reduce time-to-resolution.
- Analytics: top deny reasons, noisy principals, hot operations, and policy regressions.
Production Notes
- Authentication/authorization: Kernite server does not include built-in authn/authz. Run it behind your trusted boundary (for example mTLS, JWT verification, internal network policy, or API gateway auth).
- Request size/timeouts: Kernite server does not define built-in max body size or per-request timeout controls. Enforce size limits and timeouts at ingress/runtime (reverse proxy, gateway, or process supervisor).
- Logging/metrics: Kernite server is minimal by design (startup log only, request access logs suppressed by default). For app-embedded flows, you can also enable Kernite decision sinks (
KERNITE_SINK,KERNITE_SINK_PATH) to persist event records, then forward/aggregate them in your telemetry stack.
The decision contract (what to store)
Persistence best practices
Do not store only approvals or . Store:- approved decisions (writes that were allowed)
- denied decisions (writes that were blocked)
- application outcomes for request errors (for example invalid request or transport failure)
Recommended minimal record
Store these fields in your sink:created_at(server timestamp)workspace_idprincipal_idobject_typeoperationdecision(approved|denied)outcome(approved|denied|error) optional, app-levelreason_codes[]ctx_idtrace_hashidempotency_keypolicy_version(if available)latency_ms(if measured)
request_json(redacted/sanitized)response_json(full decision response; may be large)
response_json. If you need analytics, store indexable columns plus optional JSON.
Transaction semantics
A robust write path is:- Evaluate:
evaluate_execute(...)(orPOST /execute) - Persist governance evidence (approved/denied/error outcome)
- If
decision == "approved", perform the actual mutation - Return
{ok, data, governance}
Strong pattern: same transaction for evidence and mutation
If your app uses a DB transaction, write both governance evidence and domain mutation in the same transaction. This prevents missing evidence for successful writes.Failure policy: fail-closed vs fail-open
Decide what happens if your sink is unavailable.Fail-closed (strict audit/compliance)
If sink write fails, deny the operation. This guarantees evidence exists for any allowed mutation.Fail-open (availability first) + outbox
If availability matters more, allow mutation even if sink write fails, then retry evidence persistence via outbox table or queue.Patterns by sink type
Database sink (recommended for analytics)
Pros:- easy querying (top deny reasons, per-principal rates, per-operation breakdown)
- optional joins with domain data
- schema and retention planning required
- index
workspace_id,principal_id,decision,created_at - unique key
(workspace_id, idempotency_key)for retry dedupe
Object storage sink (S3/GCS/Azure Blob)
Pros:- cheap and durable
- good for long-term retention
- querying needs secondary system (Athena/BigQuery/etc.) or ETL
- JSONL partitioned by date, for example
s3://bucket/kernite/year=YYYY/month=MM/day=DD/*.jsonl
Log pipeline sink (OpenTelemetry/Datadog/Cloud Logging)
Pros:- immediate dashboards and alerts
- easy anomaly detection (deny spikes)
- retention and full-fidelity JSON may be expensive
- emit metric counters for
decisionandreason_codes - emit structured logs including
trace_hashandctx_id
Redaction and sensitive data
Governance evidence may contain sensitive data (PII, secrets, tokens). If you storerequest_json or full response_json, apply redaction.
- remove or hash emails, phone numbers, addresses
- remove tokens, credentials, and secrets
- prefer IDs/references over raw payload values
- store indexable fields plus
reason_codes - store a redacted subset of request/response JSON
Example: minimal persistence in an application write path
Replacepersist_evidence(...) with your sink implementation.