Skip to content

feat: Add user command with policy-based validation#197

Merged
jarfernandez merged 8 commits intomainfrom
feat/add-user-command
Mar 15, 2026
Merged

feat: Add user command with policy-based validation#197
jarfernandez merged 8 commits intomainfrom
feat/add-user-command

Conversation

@jarfernandez
Copy link
Copy Markdown
Owner

Summary

  • Add new user command that validates container image USER directives against configurable security policies (UID ranges, blocked usernames, numeric UID requirements)
  • Without flags or policy, behaves identically to root-user (basic non-root check). With policy, enforces granular constraints: --min-uid, --max-uid, --blocked-users, --require-numeric, and --user-policy (JSON/YAML file or stdin)
  • Fully integrated into the all command with config file support (file reference and inline policy), CLI flag overrides, and --include/--skip support

Details

New files

  • internal/user/policy.go / validator.go — Core validation logic and policy loading
  • cmd/check-image/commands/user.go — Standalone user command with 5 flags
  • config/user-policy.yaml / config/user-policy.json — Sample policy files

Modified files

  • cmd/check-image/commands/all_config.go / all_orchestration.goall command integration (check count 10→11)
  • cmd/check-image/commands/render.go — Text renderer for user check
  • internal/output/results.goUserDetails and UserViolation output structs
  • Config files updated with user section examples
  • CLAUDE.md and README.md documentation

Test coverage

  • internal/user/ at 100% coverage
  • cmd/check-image/commands/user_test.go: unit tests + 11 RunE end-to-end subtests
  • all_orchestration_test.go and all_config_test.go: 9 + 10 new integration tests
  • Overall coverage: 94.6%

Test plan

  • go test ./... — all tests pass
  • pre-commit run --all-files — all hooks pass
  • 22 CLI-based end-to-end tests (standalone + all integration) — all pass
  • Coverage verified at 94.6% overall

🤖 Generated with Claude Code

Add a new `user` command that validates the container image USER directive
against configurable security policies. Without flags/policy, it performs
a basic non-root check (same as `root-user`). With a policy file or CLI
flags, it enforces UID ranges, blocked usernames, and numeric UID
requirements.

New components:
- `internal/user/` package: policy loading, validation logic, parsing
- `cmd/check-image/commands/user.go`: standalone command with 5 flags
  (`--user-policy`, `--min-uid`, `--max-uid`, `--blocked-users`,
  `--require-numeric`)
- `internal/output/results.go`: `UserDetails` and `UserViolation` structs
- `cmd/check-image/commands/render.go`: text renderer for user check

Integration with `all` command:
- Registered as 11th check in `buildCheckDefs()`
- Config file support with individual fields and inline policy
- All existing tests updated for new check count (10→11)

Comprehensive test coverage:
- Unit tests for `internal/user/` (policy loading, validation, parsing)
- Unit tests for standalone `user` command (basic, with policy, flags)
- E2e tests: policy file YAML/JSON, stdin, CLI overrides, JSON/text output
- E2e tests for `all` integration: include, skip, config, inline policy,
  user+root-user coexistence, JSON output
- Config tests: loadAllConfig, applyUserConfig, determineChecks
- Create `config/user-policy.yaml` and `config/user-policy.json` with
  UID range, blocked users, and require-numeric settings
- Add `user` section to `config/config.yaml` and `config/config.json`
  referencing the new policy files
- Add inline `user` section to `config/config-inline.yaml` and
  `config/config-inline.json` with embedded policy
- CLAUDE.md: Add `user` command section with flags, validation logic,
  implementation details, and design decisions. Update `all` command
  flags and check count (10→11). Add `user-policy` to config files
  list and stdin support section. Add `user-policy` to inline config
  example
- README.md: Add `user` command section with usage examples and flag
  descriptions. Update `all` command flags and check count. Add user
  policy files section, stdin example, and update inline config
  description. Add `internal/user/` to project structure
Overall coverage: 94.2% → 93.1%. New `internal/user` package at 100%.
`cmd/check-image/commands` dropped from 90.6% to 88.5% due to
`resolveUserPolicy` in the standalone command's `RunE` handler not
being exercised (tests call `runUser()` directly, consistent with
other commands).
Add comprehensive tests for `resolveUserPolicy` covering all flag
combinations: no flags, policy file only, flags only, flags overriding
policy file, individual flags (require-numeric, max-uid), invalid
policy file, and min-uid > max-uid validation error.

Coverage: 93.1% → 94.6% overall. `resolveUserPolicy` now at 100%.
`cmd/check-image/commands` improved from 88.5% to 90.9%.
Add `TestUserCommand_RunE` with 11 subtests that exercise the full
Cobra command pipeline (RunE → resolveUserPolicy → runUser →
renderResult → Result update):
- Basic non-root pass/fail
- Policy file (YAML/JSON) pass/fail
- CLI flags overriding policy file
- CLI flags only (blocked-users)
- Invalid policy file error
- JSON output format
- Stdin policy input
- Empty user (not set)
- require-numeric via CLI flag

`cmd/check-image/commands` coverage: 90.9% → 91.5%.
- Unify root violation messages to single "user must not be root"
  for empty, "root", and UID 0 cases
- Change header from "Checking USER directive" to "Checking user"
- Change label from "USER:" to "User:" in text output
- Remove "Violations:" header, show bullet list directly
- Use lowercase "user" instead of "USER" in all messages, flag
  descriptions, and documentation
These fields are redundant in JSON/text output since the full `user`
field already contains the complete value. The parsed components remain
in `internal/user/UserInfo` where they are needed for validation logic.
@jarfernandez jarfernandez self-assigned this Mar 15, 2026
@jarfernandez jarfernandez merged commit f37ae30 into main Mar 15, 2026
13 checks passed
@jarfernandez jarfernandez deleted the feat/add-user-command branch March 15, 2026 17:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant