Tutorials

How to configure Kensa once so daily scans need almost no flags

Configure Kensa's rules directory, policy variables, host inventory, and results database once so everyday check and remediate commands need almost no flags.

RRemylus Racine
July 8, 2026 · 6 min read
How to configure Kensa once so daily scans need almost no flags

What you'll accomplish

Set Kensa up so your everyday check and remediate commands carry only a host name. After this, Kensa finds its rules on its own, applies your organization's policy values instead of the built-in defaults, knows your fleet from an inventory, and writes results to a path you chose. No -r, no long --var lists, no repeated flags.

The whole scheme rests on one directory Kensa auto-detects. Set that up first, everything else drops into it.

Before you start

  • Kensa and its rules installed from hanalyx.com/download. Install the kensa and kensa-rules packages together.
  • SSH access to your hosts. Kensa uses your system OpenSSH, so ~/.ssh/config, known_hosts, jump hosts, and your SSH agent all apply.
  • Your policy baseline in hand. Know the values your organization enforces (SSH MaxAuthTries, password length, and so on). Kensa ships STIG-leaning defaults; you will override the ones that differ.

Step 1: let Kensa find its rules

Installing the kensa-rules package lands the rule corpus where Kensa looks by default. Confirm a scan finds them with no -r flag:

kensa check -H web01.example.com -u admin --sudo

If that reports "No rules found," the rules package is not installed; install it, or pass --rules-dir <path> explicitly. With the package in place you never pass -r again.

Step 2: create the config directory Kensa auto-detects

Kensa looks for a configuration directory in this order and uses the first one that exists:

  1. --config-dir <path> (explicit flag)
  2. $KENSA_CONFIG_DIR
  3. $XDG_CONFIG_HOME/kensa
  4. ~/.config/kensa
  5. /etc/kensa

For personal daily work, ~/.config/kensa is the sweet spot: no flag, no root.

mkdir -p ~/.config/kensa/conf.d

Anything you put here is picked up automatically. For a shared host where every operator should get the same policy, use /etc/kensa instead (same layout).

Step 3: set your policy variables once

About thirty rules in the corpus are templated with variables like ssh_max_auth_tries and pam_pwquality_minlen. Kensa ships built-in defaults for all of them (STIG-leaning), so scans work out of the box. Where your policy differs, override the value once in a file Kensa reads.

Create ~/.config/kensa/defaults.yml with only the keys you want to change:

variables:
  ssh_max_auth_tries: 3
  pam_pwquality_minlen: 14
  banner_text: |
    Authorized uses only. Activity is monitored.

Now every scan uses your values, no --var needed. You do not copy the whole default set; you list only your overrides. Anything you leave out keeps its built-in default.

Kensa resolves each variable through these tiers, later winning on a collision:

built-in defaults  →  defaults.yml  →  conf.d/*.yml  →  groups/<group>.yml  →  hosts/<host>.yml  →  --var

You do not have to use every tier. defaults.yml alone covers most teams. The rest exist for when one fleet needs more than one policy.

Step 4: layer overrides for groups and single hosts

When part of your fleet needs different values, override per scope instead of maintaining separate configs:

  • conf.d/*.yml — organization-wide overrides, merged alphabetically so you can order them (10-base.yml, 50-org.yml, 99-local.yml). Later files win.
  • groups/<group>.yml — values for one inventory group. A host in the [web] group picks up groups/web.yml.
  • hosts/<hostname>.yml — values for one host, named by the address in your inventory (hosts/web01.example.com.yml).

One rule to remember: a variable's base value must live in a global tier (defaults.yml, conf.d/, or the built-in defaults). The groups/ and hosts/ files override an existing variable; they cannot introduce a brand-new one that has no global default. Since every templated corpus variable already has a built-in default, overriding any of them per group or per host works. Inventing a new variable name only in groups/ will error with "undefined variable" (see the last section).

Step 5: put your fleet in an inventory

Instead of naming one host per command, list them once in an Ansible-style inventory. Group hosts under [section] headers; the group names line up with your groups/*.yml files:

# fleet.ini
[web]
web01.example.com ansible_user=admin
web02.example.com ansible_user=admin

[db]
db01.example.com ansible_user=admin

Scan the whole fleet, or a slice of it, in one command:

# Every host in the inventory, 10 at a time
kensa check --inventory fleet.ini --workers 10 --sudo

# Only the web group
kensa check --inventory fleet.ini --limit web --sudo

--limit takes the same glob and group syntax as Ansible (--limit 'web*,!web02.example.com'). --workers sets how many hosts run concurrently.

Step 6: choose one place for results

By default Kensa writes its transaction log to .kensa/results.db in the current directory, which moves with your shell. Pin it to one stable path so history and rollback always find the same records:

kensa --db ~/.local/share/kensa/results.db check --inventory fleet.ini --sudo

The --db flag is global, so it goes before the subcommand. Point every command at the same file and your whole audit trail lives in one database.

Verify

Confirm the configuration is wired by running the barest possible command, no -r, no --var, against one host:

kensa check -H web01.example.com -u admin --sudo

Two things prove the setup took:

  1. It runs the full corpus rather than reporting "No rules found." The rules directory resolved on its own.
  2. No "undefined variable" error appears. Your variable tiers resolved; the templated rules got their values.

To confirm a specific override is live, scan just the rule it affects and read the row. For the SSH MaxAuthTries value you set in Step 3:

kensa check -H web01.example.com -u admin --sudo --control cis-rhel9:5.1.16

The verdict reflects the value Kensa resolved, which is now yours.

If it didn't work

  • "No rules found." The kensa-rules package is not installed, so the default rules directory is empty. Install it, or pass --rules-dir <path>.
  • Your config directory is ignored. Kensa uses the first directory that exists in the Step 2 list. If you put files in /etc/kensa but also have a ~/.config/kensa, the personal one wins and shadows the system one. Remove the one you don't want, or name the intended one explicitly with --config-dir.
  • "undefined variable" in an inventory scan. You defined a variable only in groups/ or hosts/. Give it a base value in defaults.yml or conf.d/ (the per-group or per-host file then overrides it).
  • An override isn't taking effect. Check the tier order: a value in conf.d/ beats defaults.yml, and a --var on the command line beats every file. If you set the same key in two places, the later tier wins.

For the full flag and file reference, see the documentation.

How to configure Kensa once so daily scans need almost no flags | Hanalyx