feat: Add user command with policy-based validation#197
Merged
jarfernandez merged 8 commits intomainfrom Mar 15, 2026
Merged
Conversation
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.
This was referenced Mar 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
usercommand that validates container image USER directives against configurable security policies (UID ranges, blocked usernames, numeric UID requirements)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)allcommand with config file support (file reference and inline policy), CLI flag overrides, and--include/--skipsupportDetails
New files
internal/user/policy.go/validator.go— Core validation logic and policy loadingcmd/check-image/commands/user.go— Standaloneusercommand with 5 flagsconfig/user-policy.yaml/config/user-policy.json— Sample policy filesModified files
cmd/check-image/commands/all_config.go/all_orchestration.go—allcommand integration (check count 10→11)cmd/check-image/commands/render.go— Text renderer forusercheckinternal/output/results.go—UserDetailsandUserViolationoutput structsusersection examplesCLAUDE.mdandREADME.mddocumentationTest coverage
internal/user/at 100% coveragecmd/check-image/commands/user_test.go: unit tests + 11RunEend-to-end subtestsall_orchestration_test.goandall_config_test.go: 9 + 10 new integration testsTest plan
go test ./...— all tests passpre-commit run --all-files— all hooks passallintegration) — all pass🤖 Generated with Claude Code