Host-side probes for ward doctor security: PATH posture, sudo, credential env #42

Closed
opened 2026-06-03 23:01:34 +00:00 by coilysiren · 0 comments
Owner

Scope

Sub-issue of #4. Turn ward doctor security from a config-shape summary into a real host probe. Drives three checks off the parsed cfg.Security block:

  1. PATH posture per protected binary. exec.LookPath(p.Name); when p.ExpectedRealPaths is non-empty, fail if the resolved path is not in the list. When ExpectedRealPaths is empty, report the resolved path as informational.
  2. Passwordless sudo. When cfg.Security.Sudo.ForbidPasswordless, run sudo -n true. Use cli-guard/sudo.PasswordRequired(stderr) to distinguish "password needed" (pass) from "ran without password" (fail). No prompting; this is a non-interactive probe.
  3. Credential env scan. For each ProtectedBinary, check every CredentialEnv name against os.Getenv. Warn (do not fail) when a credential var is set in the agent session.

Acceptance

  • ward doctor security against a config with protected_binaries: runs the three probes and prints a one-line-per-check summary plus the overall group line.
  • PATH mismatch against a non-empty expected_real_paths exits non-zero.
  • sudo -n true succeeding under forbid_passwordless: true exits non-zero. sudo -n failing with a password sentinel passes the check.
  • Credential env presence prints a WARN line per hit; never fails the group on its own. A --strict-credentials flag flips that to a failure.
  • All probes are skippable with --skip <name> (e.g. --skip sudo) for hosts where the probe is meaningless (no sudo binary, etc).
  • Tests:
    • runPathPosture driven by a pathLookup fake (mirrors the hook tests' notFoundLookup pattern).
    • runSudoProbe driven by a sudoRunner fake returning canned (stderr, exitcode).
    • runCredEnvProbe driven by a getenv fake.
    • Each probe is pure with no real exec / no real env reads inside the unit test.
  • docs/doctor.md gains a "Probes" section documenting the three checks, exit semantics, and --skip / --strict-credentials.

Out of scope

  • Hook wiring for protected binaries (hook.Protected consumption in ward hook pre-tool-use). Separate sub-issue of #4.
  • New schema fields. cli-guard owns the schema.
  • Auto-fix / remediation. doctor only reports.
## Scope Sub-issue of #4. Turn `ward doctor security` from a config-shape summary into a real host probe. Drives three checks off the parsed `cfg.Security` block: 1. **PATH posture per protected binary.** `exec.LookPath(p.Name)`; when `p.ExpectedRealPaths` is non-empty, fail if the resolved path is not in the list. When `ExpectedRealPaths` is empty, report the resolved path as informational. 2. **Passwordless sudo.** When `cfg.Security.Sudo.ForbidPasswordless`, run `sudo -n true`. Use `cli-guard/sudo.PasswordRequired(stderr)` to distinguish "password needed" (pass) from "ran without password" (fail). No prompting; this is a non-interactive probe. 3. **Credential env scan.** For each `ProtectedBinary`, check every `CredentialEnv` name against `os.Getenv`. Warn (do not fail) when a credential var is set in the agent session. ## Acceptance - `ward doctor security` against a config with `protected_binaries:` runs the three probes and prints a one-line-per-check summary plus the overall group line. - PATH mismatch against a non-empty `expected_real_paths` exits non-zero. - `sudo -n true` succeeding under `forbid_passwordless: true` exits non-zero. `sudo -n` failing with a password sentinel passes the check. - Credential env presence prints a `WARN` line per hit; never fails the group on its own. A `--strict-credentials` flag flips that to a failure. - All probes are skippable with `--skip <name>` (e.g. `--skip sudo`) for hosts where the probe is meaningless (no `sudo` binary, etc). - Tests: - `runPathPosture` driven by a `pathLookup` fake (mirrors the hook tests' `notFoundLookup` pattern). - `runSudoProbe` driven by a `sudoRunner` fake returning canned `(stderr, exitcode)`. - `runCredEnvProbe` driven by a `getenv` fake. - Each probe is pure with no real exec / no real env reads inside the unit test. - `docs/doctor.md` gains a "Probes" section documenting the three checks, exit semantics, and `--skip` / `--strict-credentials`. ## Out of scope - Hook wiring for protected binaries (`hook.Protected` consumption in `ward hook pre-tool-use`). Separate sub-issue of #4. - New schema fields. cli-guard owns the schema. - Auto-fix / remediation. doctor only reports.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
coilyco-flight-deck/ward#42
No description provided.