Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ 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.3.2 (kensa)
./bin/kensa --version # → kensa 0.4.1 (kensa)
```

The five binaries:
Expand Down Expand Up @@ -110,7 +110,7 @@ ldd bin/kensa # "not a dynamic executable"

## Status

`v0.3.2`. The 0.x line is the development phase.
`v0.4.1`. The 0.x line is the development phase.

The `api/` Go package is held to a stricter contract — frozen under v1
semver for OpenWatch's consumption. Behavior on the rest of the surface
Expand All @@ -130,7 +130,15 @@ surface on `pkg/kensa` — `LoadRules` / `BuiltInVars` / `RuleVariables` —
so api consumers load the corpus and inject operator-configured
variables without copying files or importing `internal/` (v0.3.1), and
public scanner construction with a caller-supplied `TransportFactory` —
`NewScanner` / `DefaultWithTransportFactory` (v0.3.2).
`NewScanner` / `DefaultWithTransportFactory` (v0.3.2). Most recently:
structured per-check evidence (`RuleOutcome.Evidence []CheckEvidence` —
the exact command, output, and expected value behind each verdict),
exported as a Kensa-native document (`-o evidence:`) and an OSCAL 1.0.6
Assessment Results document (`-o oscal:`), conformance-gated against the
vendored NIST schema and live-validated on the test fleet (v0.4.0), and
public OSCAL export on `pkg/kensa` — `ExportOSCALScan` /
`WriteOSCALScan` / `ExportOSCAL` / `WriteOSCAL` — so api consumers turn a
scan into OSCAL without the CLI (v0.4.1).
All 29 handlers carry passing spec-driven tests.

Open ship items before v1.0: RHEL 8 `$kernelopts` capture in the boot
Expand Down
20 changes: 10 additions & 10 deletions docs/guide/01-install.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## What you'll have when you're done

`kensa` and `kensa-rules` installed from signed packages, the verification
keys imported, and `kensa --version` printing `kensa 0.3.2`. From there,
keys imported, and `kensa --version` printing `kensa 0.4.1`. From there,
[02-quickstart](02-quickstart.md) is the next step.

Target hosts (the machines you'll scan) need no kensa installation —
Expand Down Expand Up @@ -55,27 +55,27 @@ sudo apt install kensa kensa-rules
### Air-gapped

On a connected host, download the bundled tarball from
[the v0.3.2 release](https://github.com/Hanalyx/kensa/releases/tag/v0.3.2):
[the v0.4.1 release](https://github.com/Hanalyx/kensa/releases/tag/v0.4.1):

```
kensa_0.3.2_linux_<arch>_with-rules.tar.gz # binaries + rules + LICENSE + KEYS
kensa_0.3.2_checksums.sha256 # sha256 of every artifact
kensa_0.3.2_checksums.sha256.sig # cosign signature of the checksums
kensa_0.4.1_linux_<arch>_with-rules.tar.gz # binaries + rules + LICENSE + KEYS
kensa_0.4.1_checksums.sha256 # sha256 of every artifact
kensa_0.4.1_checksums.sha256.sig # cosign signature of the checksums
```

Verify before transferring:

```bash
sha256sum -c kensa_0.3.2_checksums.sha256 # one OK line per artifact you downloaded
sha256sum -c kensa_0.4.1_checksums.sha256 # one OK line per artifact you downloaded
cosign verify-blob --key cosign.pub \
--signature kensa_0.3.2_checksums.sha256.sig \
kensa_0.3.2_checksums.sha256
--signature kensa_0.4.1_checksums.sha256.sig \
kensa_0.4.1_checksums.sha256
```

Then copy the tarball to the air-gapped host and:

```bash
tar xzf kensa_0.3.2_linux_amd64_with-rules.tar.gz
tar xzf kensa_0.4.1_linux_amd64_with-rules.tar.gz
sudo install -m 0755 kensa kensa-validate kensa-keygen /usr/local/bin/
sudo install -m 0755 kensa-systemd-helper /usr/libexec/
sudo mkdir -p /usr/share/kensa && sudo cp -r rules /usr/share/kensa/
Expand Down Expand Up @@ -150,7 +150,7 @@ tarball). The rules corpus lives at `rules/` in the repo; copy it to
kensa --version
```

You're done when this prints `kensa 0.3.2 (kensa)`. If it doesn't,
You're done when this prints `kensa 0.4.1 (kensa)`. If it doesn't,
the binary isn't on your `$PATH` — go back to **Step 2**.

## Next
Expand Down
6 changes: 4 additions & 2 deletions docs/guide/04-scan-and-remediate.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,10 @@ still go to stderr).

The exit code and every `-o FORMAT[:PATH]` output are produced from the
canonical result struct, not reconstructed from the rendered rows. Read
the result document (or `-o json`/`oscal`/etc.) for the record of what
changed; the rows are the same data rendered for a human as it arrives.
the result document (`-o json`, `-o evidence` for the Kensa-native
evidence document, `-o oscal` for OSCAL 1.0.6, etc.) for the record of
what changed; the rows are the same data rendered for a human as it
arrives.

### Inventory (multi-host)

Expand Down
31 changes: 29 additions & 2 deletions docs/guide/07-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,14 @@ One pointer that IS current: programs importing the `api` Go package
from `ScanResult.Outcomes` (since v0.3.0) — one `RuleOutcome` per rule
with a `ComplianceStatus` of `pass` / `fail` / `skipped` / `error`, the
rule's severity, a human-readable detail, and the rule's normalised
compliance-framework references (`FrameworkRefs`). The check-only
compliance-framework references (`FrameworkRefs`). Since v0.4.0 each
`RuleOutcome` also carries `Evidence []CheckEvidence` — one entry per
command the check ran, with the exact `Command`, captured
`Stdout`/`Stderr`, `ExitCode`, and `Expected` value: the reproducible
proof behind a verdict, so a consumer can show or re-verify the finding
without re-running the scan. `ScanResult` additionally exposes the
`Capabilities` and `Platform` the scan evaluated against, so the host
context a verdict was computed under is self-describing. The check-only
`ScanResult.Transactions` entries remain for backward compatibility, but
their `committed`/`rolled_back` statuses are a legacy encoding of
compliant/non-compliant — prefer `Outcomes` for an unambiguous verdict.
Expand Down Expand Up @@ -56,6 +63,26 @@ supply their own `api.TransportFactory`:
- Full service (remediate, history, transaction log):
`kensa.DefaultWithTransportFactory(ctx, storePath, yours, engineOpts...)`.

Exporting a scan as a standards artifact is public surface too (package
`github.com/Hanalyx/kensa/pkg/kensa`, since v0.4.1). A scan's verdicts
and their embedded check evidence convert to an OSCAL 1.0.6 Assessment
Results document with no shelling out to the CLI:

- `kensa.ExportOSCALScan(result, hostname)` → `[]byte` of OSCAL 1.0.6 AR
JSON (`kensa.WriteOSCALScan(w, result, hostname)` streams to an
`io.Writer`). One finding + observation per rule, the `CheckEvidence`
embedded as relevant-evidence, framework refs as control-ids. The scan
document is **unsigned** by design — it is derived from the read-only
`ScanResult`.
- `kensa.ExportOSCAL(envelope)` / `kensa.WriteOSCAL(w, envelope)` — the
remediation counterpart, rendering a signed `api.EvidenceEnvelope`
(the audit-truth-of-record a transaction produces) as OSCAL. This path
is anchored on the envelope's Ed25519 signature.

The byte production lives in `internal/` and is conformance-gated against
the vendored NIST OSCAL 1.0.6 schema; these are the importable entry
points to it.

End-to-end, the whole consumer chain is public:
`kensa.LoadRules(…, operatorVars)` → construct (either form above) →
`Scan` → `ScanResult.Outcomes`.
`Scan` → `ScanResult.Outcomes` → `kensa.ExportOSCALScan(…)`.