Atomic compliance remediation for Linux. Every change runs as a
four-phase transaction — Capture → Apply → Validate → Commit/Rollback —
with signed evidence and full rollback on failure.
kensa check --rules-dir /usr/share/kensa/rules --severity high <host>
kensa remediate --rules-dir /usr/share/kensa/rules --severity high <host>
kensa history
kensa rollback <transaction-id>One static binary. No glibc floor. No runtime dependency on the target host beyond OpenSSH.
Pre-1.0 note. The commands above describe the v1.0 ship state. Until the
kensa-rpmandkensa-rulespackages publish, install ismake buildfrom this repo and--rules-dir <local-path>is mandatory. See Building from source for what runs today.
The operator manual is in docs/guide/. Start with
01-install and
02-quickstart. Chapters that mark
themselves Stub carry pre-1.0 placeholders; the binary's --help
and the relevant .spec.yaml under specs/ are the authoritative
source until they land.
| Status | What happened | Reversible? |
|---|---|---|
committed |
Applied, validated, evidence signed and persisted | kensa rollback |
rolled_back |
Applied but validation failed; pre-state restored from capture | already reverted |
skipped |
Host was already compliant; no apply ran | nothing to revert |
A handler is capturable if it records the host's pre-state before
Apply. Of the 29 handlers shipped, 19 are capturable (file permissions,
file content, services, sysctl, mount options, SELinux booleans, kernel
modules, audit rules, cron, packages, and PAM) and give the full
atomicity guarantee. The remaining 10 are non-capturable, carry
transactional: false in their rule YAML, and kensa plan flags them
before any apply runs.
See 03-concepts for the contract in full.
kensa is statically linked (CGO_ENABLED=0) and uses the pure-Go DNS
resolver (-tags netgo). It depends on the Linux kernel ABI only — no
libc. The same binary runs on:
| Distribution | libc | CI gate |
|---|---|---|
| RHEL 8, Rocky 8, AlmaLinux 8 | glibc 2.28 | rockylinux:8 |
| RHEL 9 / 10 and derivatives | glibc 2.34+ | (inherits 2.28 floor) |
| Ubuntu 22.04 / 24.04 LTS, Debian | glibc | (inherits glibc compat) |
| Alpine 3+ | musl | alpine:3 |
A regression — a transitive dependency that pulls cgo, a Makefile
change that drops -tags netgo, a binary that links against
glibc-specific symbols — fails CI before merge.
This is how to run kensa today, pre-1.0. Requires Go 1.26+ and make.
git clone git@github.com:Hanalyx/kensa.git
cd kensa
make build # builds all five binaries into bin/
./bin/kensa --version # → kensa 0.1.0 (kensa)The five binaries:
| Binary | Purpose |
|---|---|
kensa |
The CLI: check, remediate, rollback, history, plan, verify |
kensa-fuzz |
Failure-injection harness for atomicity verification on real hosts |
kensa-validate |
Rule YAML and spec validator |
kensa-keygen |
Ed25519 keypair generator for evidence signing |
kensa-systemd-helper |
Privileged systemd D-Bus helper (sudo-invoked) |
Run a scan today:
./bin/kensa check \
--rules-dir /path/to/kensa-rules \
--severity high \
<host>Verify the binary is statically linked:
file bin/kensa # "ELF 64-bit ... statically linked"
ldd bin/kensa # "not a dynamic executable"v0.1.0 (codename Sentinel). The 0.x line is the development phase.
The api/ Go package is held to a stricter contract — frozen under v1
semver from this version onward for OpenWatch's consumption. Behavior
on the rest of the surface (CLI flags, rule schema additions, output
formats) may change between MINOR versions with one release of
deprecation warning.
Open ship items before v1.0: rules-dir default-path resolution
(/usr/share/kensa/rules), grub_parameter_set deadman wiring,
service-handler ports onto the systemd D-Bus primitive layer, and
first-principles tests for the ten currently-untested non-capturable
handlers.
See VERSION for the current string and
VERSIONING_PLAN.md for the release contract.
Every component has a .spec.yaml under specs/ with acceptance
criteria that map to Go tests. The strict-coverage gate
(make spec-coverage-strict) enforces tier-specific thresholds:
- Tier 1 (engine, handlers, deadman) — 100% AC-to-test
- Tier 2 (checks, transport, API) — 80%
- Tier 3 (CLI, formatters) — 50%
A divergence between spec and code in Tier 1 is an atomicity violation.
Run make spec-sync for the full pipeline.
BSL 1.1, converts to Apache 2.0 on 2029-01-01.
See CONTRIBUTING.md. Every engine PR carries a
human-authored failure-mode analysis. Rollback handlers require
two-human review and a real-host atomicity test via kensa-fuzz.