Execution Evidence Integrity System
KALYX is an execution evidence integrity system for capturing, verifying, and externally anchoring execution history.
KALYX is an early-stage product under active development. It currently runs from a source checkout and is intended for local or controlled environments.
KALYX is not an EDR, SIEM, antivirus, malware blocker, or full host attestation system. It does not prevent attacks. Its purpose is evidence integrity and trust verification.
Local logs are useful, but they are not automatically trustworthy.
If an attacker can modify, reorder, truncate, or replace local history, a normal log file may still look plausible. An investigator may see commands, timestamps, and process names, but not know whether earlier records were changed or deleted.
Evidence integrity matters because investigations depend on continuity:
- Was this record appended after the previous one?
- Did a record change after it was written?
- Was a verified boundary removed or replaced?
- Is the current ledger trusted enough for detection?
- Does an independent anchor still agree with the host?
KALYX addresses that problem by turning execution events into verifiable, hash-chained evidence.
| Capability | Description |
|---|---|
| Execution ingestion | Accepts sample log events, raw execsnoop-style lines, structured API events, and live eBPF execsnoop output |
| Processing pipeline | Validates, enriches, normalizes, and chains events through shared backend services |
| Hash-chained ledger | Stores execution records in logs/exec_chain.jsonl with sequence number, previous hash, and canonical record hash |
| Verification engine | Recomputes the ledger chain and reports the first untrusted boundary |
| Local checkpoints | Stores verified ledger boundaries in logs/checkpoints.jsonl using chained checkpoint hashes |
| Trust-state enforcement | Blocks new ingestion when the ledger or checkpoint state is untrusted |
| Detection engine | Runs deterministic behavioral rules only after successful full-ledger hash-chain verification |
| Alert persistence | Stores deduplicated alerts in logs/alerts.jsonl |
| FastAPI host backend | Exposes status, ingestion, verification, detection, alerts, and ledger inspection |
| Angular dashboard | Provides a local operations console over the FastAPI backend |
| Raspberry Pi anchor authority | Stores checkpoint boundaries in an independent Pi-side hash chain |
| Anchor comparison | Compares the latest local checkpoint with the latest Raspberry Pi anchor |
KALYX has three layers:
- Interfaces: CLI, FastAPI host API, and Angular dashboard access the system.
- Host evidence core: ingestion, validation, normalization, ledger chaining, verification, checkpoints, detection, alerts, and anchor submission.
- External anchor authority: a Raspberry Pi service stores checkpoint boundaries in an independent anchor chain.
The interfaces are access layers. They do not implement separate integrity logic; they call the shared host evidence core.
flowchart TD
subgraph Interfaces["Interfaces"]
CLI["CLI<br/>kalyx"]
API["FastAPI Host API<br/>kalyx-api"]
UI["Angular Dashboard<br/>frontend"]
end
subgraph Host["Host Evidence Core"]
Ingest["Ingestion + Normalization"]
TrustGate["Trust Gate"]
Ledger["Hash-Chained Ledger"]
Verify["Verification Engine"]
Checkpoints["Checkpoint Chain"]
Detect["Detection Engine"]
Alerts["Alert Log"]
AnchorClient["Anchor Client"]
end
subgraph Pi["Raspberry Pi Anchor Authority"]
AnchorAPI["Anchor API<br/>kalyx-anchor"]
AnchorChain["Pi Anchor Chain"]
end
UI --> API
CLI --> Ingest
API --> Ingest
CLI --> Verify
API --> Verify
CLI --> Detect
API --> Detect
CLI --> AnchorClient
API --> AnchorClient
Ingest --> TrustGate
TrustGate --> Ledger
Verify --> Ledger
Verify --> Checkpoints
Ledger --> Detect
Detect --> Alerts
AnchorClient --> Checkpoints
AnchorClient --> AnchorAPI
AnchorAPI --> AnchorChain
AnchorAPI -. latest anchor .-> AnchorClient
| Layer | Component | Implementation | Responsibility |
|---|---|---|---|
| Interfaces | CLI | kalyx/cli/app.py |
Operational commands for ingestion, verification, checkpoints, detection, alerts, and anchoring |
| Interfaces | FastAPI Host API | kalyx/api/main.py |
HTTP access to shared host services |
| Interfaces | Angular Dashboard | frontend/ |
Local interface for trust state, ledger inspection, verification, ingestion, detection, alerts, and evidence JSON |
| Host Evidence Core | Pipeline | kalyx/services/pipeline.py |
Validation, enrichment, normalization, and trust-gated append |
| Host Evidence Core | Ledger Service | kalyx/services/ledger.py |
Ledger verification, checkpoints, trust states, status, and export |
| Host Evidence Core | Detection Service | kalyx/services/detection.py |
Verification-gated detection and alert persistence |
| Host Evidence Core | Anchor Client | kalyx/services/anchor_client.py |
Checkpoint submission and anchor-status comparison |
| External Anchor Authority | Raspberry Pi Anchor API | kalyx/anchor/api.py |
Independent API for checkpoint anchoring and latest-anchor lookup |
| External Anchor Authority | Raspberry Pi Anchor Storage | kalyx/anchor/storage.py |
Pi-side append-only anchor chain validation and persistence |
flowchart LR
A["Capture event"] --> B["Validate<br/>Enrich<br/>Normalize"]
B --> C["Trust gate"]
C --> D["Append to<br/>hash-chained ledger"]
D --> E["Verify ledger"]
E --> F["Create checkpoint"]
F --> G["Anchor checkpoint<br/>to Raspberry Pi"]
G --> H["Compare anchor status"]
E --> I["Run detection<br/>after hash-chain verification"]
I --> J["Persist alerts"]
- Capture: events enter through sample logs, raw execsnoop-style lines, structured API requests, or live eBPF ingestion.
- Chain: accepted events are validated, enriched, normalized, and appended to the hash-chained ledger after the trust gate passes.
- Verify: the verification engine recomputes ledger hashes and reports the first untrusted boundary.
- Checkpoint: trusted ledger boundaries are recorded in the local checkpoint chain.
- Anchor: checkpoint boundaries can be submitted to the Raspberry Pi authority and compared with the latest external anchor.
- Detect: deterministic rules run only after full-ledger hash-chain verification and persist deduplicated alerts. Detection does not currently evaluate local checkpoint continuity.
KALYX verifies evidence continuity. It does not prove event truth.
| Claim | How |
|---|---|
| A ledger record was changed after append | Recompute canonical record hash |
| A previous-hash link was broken | Compare each prev_hash with expected previous record hash |
| Ledger JSON is malformed | Decode and validate each ledger line |
| The first untrusted record boundary | Report failure_index, valid_until_index, and last_valid_hash |
| A local checkpoint was edited | Validate checkpoint self-hash |
| Checkpoint history was reordered or broken | Validate previous-checkpoint hash chain |
| Ledger fell behind a previous checkpoint | Compare current ledger against latest checkpoint boundary |
| Detection ran only on hash-chain-verified evidence | Detection service verifies the full ledger chain before replaying records |
| A checkpoint was externally anchored | Compare local checkpoint with latest Raspberry Pi anchor |
| Out Of Scope | Reason |
|---|---|
| Event source authenticity | KALYX validates event shape, not event truth |
| Kernel-level trust | Raw execsnoop lines are treated as input, not proof |
| Full host compromise resistance | A fully compromised host can alter local runtime and files |
| Malware prevention | KALYX records and verifies evidence; it does not block processes |
| Complete remote attestation | Raspberry Pi anchoring stores checkpoint boundaries, not full host state |
| Continuous anchor availability | Anchor comparison depends on the Pi service being reachable |
Core boundary:
KALYX verifies records it accepted.
KALYX does not prove the original event source was truthful.
| Trust State | Meaning |
|---|---|
VERIFIED |
Ledger verifies successfully and does not conflict with the latest local checkpoint |
PARTIALLY_TRUSTED |
Verification failed, but earlier records before the failure remain trusted |
UNTRUSTED |
Ledger or checkpoint continuity cannot be trusted |
EMPTY |
Ledger file exists but contains no records |
NO_LEDGER |
No ledger file exists yet |
Ingestion is blocked when the current ledger or checkpoint state is untrusted. Detection is skipped when full-ledger hash-chain verification fails. Detection does not currently consult the checkpoint chain, so a checkpoint-inconsistent ledger can be reported as UNTRUSTED by status while still passing the detection service's narrower hash-chain gate.
KALYX includes an independent Raspberry Pi anchor authority.
The host creates local checkpoints. The Pi stores checkpoint boundaries in its own append-only hash chain. This gives the host a separate authority to compare against after local changes, truncation, or replacement.
On the Raspberry Pi, or locally for testing:
kalyx-anchorDefault service port:
http://127.0.0.1:8081
The Pi anchor stores records in:
anchors/anchor_chain.jsonl
Create local evidence and a checkpoint:
kalyx ingest
kalyx verify --format json
kalyx checkpointSubmit the latest checkpoint to the anchor service:
kalyx anchor --anchor-url http://127.0.0.1:8081 --ledger-id kalyx-main-hostkalyx anchor verifies the ledger, creates or reuses a safe local checkpoint, then sends the checkpoint boundary to the Pi service.
Anchor submission statuses include:
| Status | Meaning |
|---|---|
ACCEPTED |
New checkpoint boundary was stored |
ALREADY_ANCHORED |
Same ledger/checkpoint hash was already stored |
REJECTED_STALE |
Non-duplicate checkpoint index is not newer than the latest Pi anchor for that ledger |
REJECTED_INVALID |
Payload or existing Pi anchor chain failed validation |
kalyx anchor-status --anchor-url http://127.0.0.1:8081 --ledger-id kalyx-main-hostComparison statuses:
| Status | Meaning |
|---|---|
MATCH |
Local checkpoint and Pi anchor have the same checkpoint index and hash |
BEHIND |
Pi anchor is newer than the local checkpoint |
AHEAD |
Local checkpoint is newer than the latest Pi anchor |
DIVERGENCE |
Checkpoint indices match, but checkpoint hashes differ |
NO_ANCHOR |
No Pi anchor exists for the selected ledger |
UNREACHABLE |
Pi anchor service could not be contacted |
Environment defaults:
export KALYX_ANCHOR_URL=http://127.0.0.1:8081
export KALYX_LEDGER_ID=kalyx-main-hostThe Angular dashboard is a local operations console over the FastAPI host API. It does not decide trust in the browser. It displays backend verification, ledger, checkpoint, detection, and alert state.
| Screen | Purpose |
|---|---|
| Overview | Current trust state, ledger state, checkpoint state, recent records, recent alerts |
| Ledger | Searchable/filterable ledger records with full JSON drawer |
| Verification | Run backend verification, inspect trust metadata, check Anchor Status, and submit the latest checkpoint to the anchor service |
| Ingestion | Submit structured events or raw execsnoop-style lines |
| Detection | Run verification-gated detection |
| Alerts | Search and filter persisted alerts |
| Evidence | Inspect raw backend JSON responses |
Run locally:
cd frontend
npm ci
npm startOpen:
http://127.0.0.1:4200/
Checked-in frontend API target for the current development setup:
http://192.168.64.2:8000
Configured in:
frontend/src/environments/environment.ts
This address identifies the Linux host running the FastAPI backend inside the current development virtual machine; it is not a permanent deployment requirement.
The dashboard calls the host FastAPI API for anchor status and anchor submission. It never calls the Raspberry Pi anchor service directly.
For a same-machine setup, change the frontend API target to http://127.0.0.1:8000. Multi-machine environments must use an address that is reachable from the browser. The Raspberry Pi URL remains backend-only configuration.
Install from a local checkout:
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install -U pip
python3 -m pip install -e . pytestRun backend checks:
python3 -m compileall kalyx
python3 -m pytest -qCreate and verify a sample ledger:
kalyx ingest
kalyx verify --format json
kalyx statusRun detection:
kalyx detect
kalyx alertsStart the host API:
kalyx-apiStart the dashboard:
cd frontend
npm ci
npm start| Command | Purpose |
|---|---|
kalyx ingest |
Ingest sample events from sample_exec.log |
kalyx ingest-live |
Run live eBPF ingestion using execsnoop-bpfcc |
kalyx verify |
Verify ledger and write/reuse a checkpoint when safe |
kalyx verify --format json |
Print structured verification output |
kalyx status |
Show ledger, verification, trust, and checkpoint status |
kalyx checkpoint |
Create or reuse a local checkpoint |
kalyx checkpoint --format json |
Print checkpoint operation as JSON |
kalyx anchor |
Submit latest local checkpoint to the anchor service |
kalyx anchor-status |
Compare local checkpoint with latest Pi anchor |
kalyx inspect |
Print ledger entries in readable form |
kalyx export |
Export ledger records and verification state |
kalyx audit |
Display auditd ledger access events for kalyx_ledger_watch |
kalyx detect |
Run deterministic detection after full-ledger hash-chain verification |
kalyx alerts |
Print persisted alerts |
kalyx --help |
Show command help |
KALYX has two FastAPI applications: the host API and the anchor API.
Start:
kalyx-apiBase URL:
http://127.0.0.1:8000
| Method | Route | Protection | Purpose |
|---|---|---|---|
GET |
/ |
Open | Minimal API-running page |
GET |
/status |
Open | Ledger status, trust state, checkpoint metadata |
POST |
/verify |
API key when configured | Verify ledger and write/reuse checkpoint when safe |
POST |
/ingest |
API key when configured | Ingest raw line or structured event |
POST |
/detect |
API key when configured | Run verification-gated detection |
GET |
/alerts |
Open | Return persisted alerts |
GET |
/ledger |
Open | Return recent parsed ledger records |
GET |
/anchor/status |
Open | Compare the latest local checkpoint with the latest Pi anchor |
POST |
/anchor |
API key when configured | Create or reuse a safe local checkpoint and submit it through the host anchor client |
Optional local API-key protection:
export KALYX_API_KEY=example-dev-key
kalyx-apiProtected host routes then require:
X-KALYX-API-Key: example-dev-key
This is lightweight local protection for operational routes. It is not user authentication, RBAC, OAuth, JWT, or source attestation.
Start:
kalyx-anchorBase URL:
http://127.0.0.1:8081
| Method | Route | Purpose |
|---|---|---|
POST |
/anchor |
Store a checkpoint boundary in the Pi anchor chain |
GET |
/anchor/latest?ledger_id=... |
Return the latest anchor accepted for one ledger |
Detailed host API documentation lives in docs/API_ENDPOINTS.md.
Detection is deterministic and rule-based. It runs only after successful ledger verification.
| Rule | Severity | Trigger |
|---|---|---|
DELETE_CREATE |
High | DELETE followed by CREATE on the same known target within 300 seconds |
MODIFY_BURST |
Medium | Repeated MODIFY actions against the same known target in a short window |
DESTRUCTIVE_BURST |
High | Multiple destructive actions by the same user/session within 15 seconds |
SCRIPTED_DESTRUCTIVE_ACTION |
High | DELETE or MODIFY launched by scripting parents outside interactive sessions |
Alerts are persisted with stable signatures to avoid duplicate writes across repeated or concurrent detection runs.
KALYX tests focus on correctness properties that support its integrity claims.
Run:
python3 -m compileall kalyx
python3 -m pytest -qFrontend build check:
cd frontend
npm ci
npm run build| Area | Covered Behavior |
|---|---|
| Ledger integrity | Valid append, deterministic verification, hash mismatch detection |
| Corruption handling | Invalid and truncated JSON, previous-hash mismatch, payload hash mismatch |
| Concurrent appends | File-lock protected sequence and hash continuity under parallel writes |
| Pipeline validation | Missing fields, invalid PID/PPID, empty command rejection |
| Ingestion trust gate | Ingestion blocked after tampering or checkpoint inconsistency |
| Checkpoints | Creation, deduplication, self-hash validation, chain validation, truncation detection |
| Trust states | VERIFIED, PARTIALLY_TRUSTED, UNTRUSTED, EMPTY, NO_LEDGER behavior |
| Detection rules | Delete/create, modify burst, destructive burst, scripted destructive actions |
| Alert persistence | Deduplication and concurrent write safety |
| Host API | Status, ingest, verify, detect, alerts, ledger, API-key behavior |
| Host anchor API | Anchor status comparison, anchor submission, rejection states, unreachable anchors, untrusted ledger handling |
| Anchor service | Anchor creation, anchor-chain integrity, stale rejection, latest lookup |
| Anchor CLI/client | kalyx anchor, kalyx anchor-status, environment overrides, comparison states |
| Angular service/state | API-key header behavior, host anchor endpoint calls, and trust-state display mapping |
GitHub Actions runs backend compile/tests and Angular production build on pushes and pull requests to main.
kalyx/
anchor/
api.py
storage.py
api/
app.py
dashboard.html
main.py
static/
style.css
cli/
app.py
core/
alerts.py
chain.py
detector.py
normalize.py
verify.py
engine/
enrichment.py
ingest_execsnoop.py
ingest_execsnoop_live.py
parser.py
models/
schema.py
services/
anchor_client.py
detection.py
ledger.py
pipeline.py
tests/
test_alert_persistence.py
test_anchor_service.py
test_anchor_status.py
test_api_auth.py
test_api_endpoints.py
test_checkpoint_integrity.py
test_cli_anchor.py
test_detection_rules.py
test_ingestion_trust_gate.py
test_ledger_corruption.py
test_ledger_integrity.py
test_pipeline_validation.py
docs/
API_ENDPOINTS.md
ARCHITECTURE.md
CONFIGURATION.md
DETECTION_ENGINE.md
TESTING_SUMMARY.md
THREAT_MODEL.md
frontend/
angular.json
package.json
proxy.conf.json
src/
app/
core/
features/
layout/
shared/
environments/
pyproject.toml
setup.py
requirements.txt
sample_exec.log
Runtime JSONL and status files are created locally and ignored by git:
logs/exec_chain.jsonl
logs/checkpoints.jsonl
logs/alerts.jsonl
logs/.kalyx_status.json
anchors/anchor_chain.jsonl
Ledger exports are created locally, and .gitignore allows report JSON files to be tracked if added:
reports/ledger_export.json
| Variable | Required | Purpose |
|---|---|---|
KALYX_API_KEY |
No | Protects host API operational routes when configured |
KALYX_ANCHOR_URL |
No | Default anchor URL for kalyx anchor and kalyx anchor-status |
KALYX_LEDGER_ID |
No | Default ledger ID used for anchor submission and comparison |
Example:
export KALYX_API_KEY=example-dev-key
export KALYX_ANCHOR_URL=http://127.0.0.1:8081
export KALYX_LEDGER_ID=kalyx-main-hostFrontend API settings live in:
frontend/src/environments/environment.ts
Same-machine and multi-machine settings are described in docs/CONFIGURATION.md.
Frontend configuration is visible in built JavaScript. Do not treat it as secret storage.
- KALYX does not prevent attacks or block processes.
- KALYX does not prove that an ingested event came from a truthful source.
- Raw execsnoop lines and structured API payloads are treated as input, not proof.
- A full host compromise can defeat local-only evidence.
- Raspberry Pi anchoring stores checkpoint boundaries, not full host state.
- Anchor comparison depends on the Pi service being reachable.
- Live eBPF ingestion requires a compatible Linux environment with
execsnoop-bpfccand suitable privileges. - Ledger storage is local JSONL, not an indexed database.
- Verification is O(n) because each ledger record is recomputed in order.
- Detection uses deterministic rules, not ML or external threat intelligence.
- Detection currently gates on full-ledger hash-chain verification and does not evaluate local checkpoint continuity.
- The Raspberry Pi anchor API is unauthenticated in the current implementation and does not issue signed receipts.
- JSONL ledger: simple, append-friendly, inspectable, and easy to verify line by line.
- Canonical hashing: deterministic serialization makes verification reproducible.
- Local checkpoints: record verified boundaries before external anchoring.
- Raspberry Pi anchor: provides an independent checkpoint authority without introducing a large distributed system.
- Rule-based detection: explainable, deterministic, and testable.
- Thin interfaces: CLI, API, and Angular call shared backend services instead of duplicating trust logic.
- No database: keeps the current system inspectable and avoids operational complexity before indexed storage is needed.
| Document | Purpose |
|---|---|
| docs/ARCHITECTURE.md | Backend architecture, service layers, request flow |
| docs/API_ENDPOINTS.md | Host API route details |
| docs/DETECTION_ENGINE.md | Detection rules, semantics, limitations |
| docs/THREAT_MODEL.md | Trust boundaries and out-of-scope assumptions |
| docs/CONFIGURATION.md | Environment and frontend API configuration |
| docs/TESTING_SUMMARY.md | Current automated test coverage and known gaps |
| DEMO.md | Guided local product walkthrough |
KALYX is currently distributed as source and is not yet packaged as a production service. The working product includes the host API, CLI, Angular dashboard, local integrity services, and Raspberry Pi anchor service described above. Security hardening, deployment automation, and scalable storage remain active product work.
Planned product work:
- Signed checkpoint exchange between host and anchor
- Ledger segmentation and incremental verification
- Authenticated event-source ingestion
- Indexed alert and replay storage
- Stronger Raspberry Pi anchor hardening
- Browser-based Angular test coverage in CI
Want a deeper understanding of how KALYX works? Explore KALYX Learn, an interactive documentation site covering the platform architecture, execution evidence model, integrity verification workflow, trust model, Raspberry Pi anchoring, detection engine, APIs, roadmap, and future vision.
🌐 Visit KALYX Learn https://kalyx-8s5v.vercel.app/
The site includes:
- System Architecture
- Execution Workflow
- Trust Model
- Verification & Detection
- Raspberry Pi External Anchoring
- API Documentation
- Security Boundaries
- Product Roadmap
- Future Enhancements
If you’re evaluating KALYX or contributing to the project, KALYX Learn is the best place to understand the platform before exploring the source code.