mirror of
https://github.com/vee1e/krply.git
synced 2026-09-01 09:49:51 +00:00
Audit: correlation event_ids include stage and response code so the multi-stage lines of one request no longer collapse under dedup; match scans are bounded to a time window and a page instead of the object's full history. Web: dry-run results are read from dry_run_result (nested) so the verdict is rendered correctly and conflicts/errors/skipped are shown; the plans view no longer POSTs an unsolicited plan on page load; coverage and streams surface API errors instead of showing a misleading empty state and follow cursor pagination so they are not stuck on the oldest page; the diff path tokenizer handles backslash-escaped dotted keys. Deploy/CI: the chart no longer grants the query server a cluster-wide read ClusterRole, runs as non-root with a read-only root filesystem, adds liveness/readiness probes, wires the ConfigMap as env (STORE_PATH, LISTEN_ADDR), defaults the journal to a PVC instead of an ephemeral emptyDir, and adds imagePullSecrets; the replay ClusterRole drops the unused update verb; a Dockerfile builds a static distroless image; GitHub actions are pinned by commit SHA, jobs set least-privilege permissions, the Vercel deploy skips fork PRs, CI passes the Makefile test timeouts, and make lint runs a real web syntax check. Docs: event-schema/consistency no longer describe an ingest_sequence field, an observed-time-based event_id, or restart-from-checkpoint; the threat model documents the unauthenticated HTTP API surface and the chart's RBAC change; replay-safety matches the enforced dry-run gate.
65 lines
3.8 KiB
Markdown
65 lines
3.8 KiB
Markdown
# Event schema
|
|
|
|
Every journal record is an immutable entry. The wire format is api/event/v1. This document describes the fields, the record types, and how keys and hashes are derived.
|
|
|
|
## Record fields
|
|
|
|
| Field | Purpose |
|
|
|---|---|
|
|
| cluster_id | Separates resource version and UID domains; one per physical cluster |
|
|
| stream_id | Identifies group, version, resource, namespace, and selector |
|
|
| event_id | Deterministic deduplication key |
|
|
| ingest_seq | Local storage order (ascending); returned in this order |
|
|
| observed_at | Collector observation time |
|
|
| watch_type | Original event type (ADDED, MODIFIED, DELETED, BOOKMARK, ERROR) |
|
|
| synthetic | True for baseline events |
|
|
| resource | Group, version, kind, namespace, name, UID, resource version |
|
|
| object_hash | Fast equality and deduplication |
|
|
| object | Raw or faithfully preserved payload (JSON) |
|
|
| provenance | Optional audit correlation |
|
|
|
|
The raw watch payload is kept separate from normalized fields. This preserves unknown CRD fields. Never re-serialize the object into a lossy normalized shape.
|
|
|
|
## Record types
|
|
|
|
The journal stores event records plus these special records:
|
|
|
|
| Type | Meaning |
|
|
|---|---|
|
|
| event | A watch event (ADDED, MODIFIED, DELETED) |
|
|
| baseline | A list result (initial or post-relist) |
|
|
| gap | Continuity was lost (for example, a 410 Gone response) |
|
|
| coverage_change | A resource became unavailable or was newly discovered |
|
|
| audit_correlation | Optional request provenance matched from audit logs |
|
|
| snapshot | A materialized set of stream boundaries |
|
|
| checkpoint | Progress marker advanced by a bookmark |
|
|
|
|
The corresponding record type constants in internal/event are: TypeEvent, TypeBaseline, TypeGap, TypeCoverageChange, TypeAuditCorrelation, TypeSnapshot, and TypeCheckpoint. The watch types are: WatchAdded, WatchModified, WatchDeleted, WatchBookmark, and WatchError.
|
|
|
|
## event_id derivation
|
|
|
|
The field event_id is the deterministic deduplication key. The derivation is:
|
|
|
|
```
|
|
EventID(stream, resource, watchType, observedAt) -> string
|
|
```
|
|
|
|
The inputs are the stream identity, the resource reference, and the watch type. For live watch events the observed time is deliberately excluded: the same underlying API event must always produce the same key, so a duplicate delivery after a reconnect is idempotent. Collector-generated synthetic baselines pass the list observation time, so an unchanged object re-listed after a gap is treated as a new observation rather than a duplicate and survives deduplication. See ../consistency/consistency.md for the ingestion guarantee.
|
|
|
|
## object_hash
|
|
|
|
The function ObjectHash(objectJSON) returns a fast equality hash over the raw object payload. It lets consumers detect that a MODIFIED event did not change the object. It is not a cryptographic commitment. Treat it as a performance and equality helper only. Deduplication is by event_id, not by object content.
|
|
|
|
## Provenance
|
|
|
|
The field provenance is optional. When audit logs are available, an audit event is correlated to a stored event by cluster, namespace, name, UID, and resource version. It is recorded as a TypeAuditCorrelation record that references the field event_id. Audit identity is available only through this optional correlation. A watch event itself never contains the actor who made the change.
|
|
|
|
## Versioning
|
|
|
|
The package api/event/v1 is the public wire format. Internal packages stay private until the schema and replay contract stabilize. The manifest used by the object-storage segment layout records a schema version alongside the redaction policy version. Do not change api/event/v1 without a coordinated schema bump. Consumers of the journal and replay contract depend on it.
|
|
|
|
## See also
|
|
|
|
- Ingestion and deduplication: ../consistency/consistency.md.
|
|
- Storage layout and segment manifests: ../architecture/architecture.md.
|
|
- Sanitization of the object payload before replay: ../replay-safety/replay-safety.md.
|