Skip to content

feat(cli): enforce required policy flags from man docs - #3840

Open
alkalescent wants to merge 3 commits into
mainfrom
feat/policy-required-flags-from-docs
Open

feat(cli): enforce required policy flags from man docs#3840
alkalescent wants to merge 3 commits into
mainfrom
feat/policy-required-flags-from-docs

Conversation

@alkalescent

@alkalescent alkalescent commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Policy command flags declared required: true in their man-doc frontmatter were
never enforced at the cobra layer. man.DocFlag did not parse the required
key, so required-ness was only checked at runtime via
GetRequiredString/GetRequiredID. As a result, generated tooling that reads
the command tree could not advertise which inputs are
mandatory, and shell completion did not mark them required.

  • Add Required to man.DocFlag and a Doc.MarkRequiredFlags() method,
    mirroring the existing MarkSensitiveFlags. It skips flags declared required
    in the doc but not registered on the command (subcommand / shared injector),
    so a central sweep is safe.
  • Apply it to every policy command via a sweep at the end of
    policy.InitCommands(), once all flags are registered.
  • Reconcile each policy command's doc required: true set with its run
    function so the declared requirements match actual behavior:
    • Added required: true where a flag is unconditionally required in Go
      but the doc omitted it (e.g. namespaces get --id, resource-mappings and
      resource-mapping-groups id/create flags, attributes values ids,
      dynamic-value-mappings create attribute/selector/operator).
    • Removed required: true where the doc over-claimed: deprecated no-op
      flags (kas-grants assign/unassign), mutually-exclusive "one of" groups
      (subject-condition-sets create --subject-sets, attributes create --value, kas key --kas), and paginated limit/offset that fall back to
      a default rather than being enforced.

Behavior

Before: otdfctl policy namespaces get failed at runtime with a custom error.
After: cobra reports required flag(s) "id" not set and the requirement is
visible in --help, completion, and generated tool schemas. Commands whose docs
over-claimed (e.g. kas-registry key list with default pagination) are no longer
blocked.

Testing

  • go build ./...
  • go test ./otdfctl/pkg/man/... ./otdfctl/cmd/... (new tests cover parsing and
    marking; existing policy command tests pass)
  • Manual CLI checks across added/removed cases.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Improved policy CLI validation with accurate required-flag enforcement.
    • Updated required parameters for identifiers and resource-related commands.
    • Allowed appropriate optional flags, including pagination and deprecated-command options, to be omitted.
    • Standardized missing-required-flag error messages.
  • Documentation

    • Updated policy command documentation to reflect current flag requirements.
  • Tests

    • Added coverage for required-flag parsing and enforcement.
    • Updated end-to-end tests for standardized validation errors.

@alkalescent
alkalescent requested a review from a team as a code owner August 5, 2026 20:47
@github-actions github-actions Bot added the size/s label Aug 5, 2026
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2de1b06e-808c-48cd-9098-66011b55673f

📥 Commits

Reviewing files that changed from the base of the PR and between 13ea51d and b7c6964.

📒 Files selected for processing (42)
  • otdfctl/cmd/policy/policy.go
  • otdfctl/docs/man/policy/attributes/create.md
  • otdfctl/docs/man/policy/attributes/get.md
  • otdfctl/docs/man/policy/attributes/values/create.md
  • otdfctl/docs/man/policy/attributes/values/deactivate.md
  • otdfctl/docs/man/policy/attributes/values/get.md
  • otdfctl/docs/man/policy/attributes/values/list.md
  • otdfctl/docs/man/policy/attributes/values/update.md
  • otdfctl/docs/man/policy/dynamic-value-mappings/create.md
  • otdfctl/docs/man/policy/kas-grants/assign.md
  • otdfctl/docs/man/policy/kas-grants/unassign.md
  • otdfctl/docs/man/policy/kas-registry/key/get.md
  • otdfctl/docs/man/policy/kas-registry/key/list-mappings.md
  • otdfctl/docs/man/policy/kas-registry/key/list.md
  • otdfctl/docs/man/policy/kas-registry/key/rotate.md
  • otdfctl/docs/man/policy/key-management/provider/list.md
  • otdfctl/docs/man/policy/namespaces/get.md
  • otdfctl/docs/man/policy/registered-resources/values/list.md
  • otdfctl/docs/man/policy/registered-resources/values/update.md
  • otdfctl/docs/man/policy/resource-mapping-groups/create.md
  • otdfctl/docs/man/policy/resource-mapping-groups/delete.md
  • otdfctl/docs/man/policy/resource-mapping-groups/get.md
  • otdfctl/docs/man/policy/resource-mapping-groups/update.md
  • otdfctl/docs/man/policy/resource-mappings/create.md
  • otdfctl/docs/man/policy/resource-mappings/delete.md
  • otdfctl/docs/man/policy/resource-mappings/get.md
  • otdfctl/docs/man/policy/resource-mappings/update.md
  • otdfctl/docs/man/policy/subject-condition-sets/create.md
  • otdfctl/docs/man/policy/subject-mappings/create.md
  • otdfctl/e2e/actions.bats
  • otdfctl/e2e/attributes.bats
  • otdfctl/e2e/dynamic-value-mapping.bats
  • otdfctl/e2e/kas-keys.bats
  • otdfctl/e2e/key-base.bats
  • otdfctl/e2e/namespaces.bats
  • otdfctl/e2e/obligations.bats
  • otdfctl/e2e/registered-resources.bats
  • otdfctl/e2e/resource-mapping-groups.bats
  • otdfctl/e2e/resource-mapping.bats
  • otdfctl/e2e/subject-mapping.bats
  • otdfctl/pkg/man/docflags.go
  • otdfctl/pkg/man/docflags_test.go
💤 Files with no reviewable changes (9)
  • otdfctl/docs/man/policy/attributes/create.md
  • otdfctl/docs/man/policy/kas-registry/key/get.md
  • otdfctl/docs/man/policy/kas-registry/key/list.md
  • otdfctl/docs/man/policy/kas-grants/assign.md
  • otdfctl/docs/man/policy/key-management/provider/list.md
  • otdfctl/docs/man/policy/subject-condition-sets/create.md
  • otdfctl/docs/man/policy/kas-registry/key/rotate.md
  • otdfctl/docs/man/policy/kas-registry/key/list-mappings.md
  • otdfctl/docs/man/policy/kas-grants/unassign.md

📝 Walkthrough

Walkthrough

Policy command documentation now defines required flags. InitCommands applies this metadata to registered Cobra commands. End-to-end tests now expect Cobra’s standardized required-flag errors.

Changes

Policy CLI required flags

Layer / File(s) Summary
Flag metadata and annotation tests
otdfctl/pkg/man/docflags.go, otdfctl/pkg/man/docflags_test.go
DocFlag supports required metadata. MarkRequiredFlags annotates registered flags and skips unregistered flags.
Policy command required-flag wiring
otdfctl/cmd/policy/policy.go
Policy initialization applies required-flag metadata to the root command and nested policy commands.
Policy documentation and validation updates
otdfctl/docs/man/policy/..., otdfctl/e2e/*.bats
Policy documentation marks command inputs as required or optional. End-to-end tests match standardized Cobra required-flag messages across policy commands.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested labels: docs

Suggested reviewers: elizabethhealy

Poem

A rabbit checks each flag in line,
Required marks now clearly shine.
Optional paths stay light and free,
Cobra reports each missing key.
Tests confirm the rules are clear.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes enforcing required policy flags from man-page documentation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/policy-required-flags-from-docs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 189.973411ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 139.859956ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 455.944951ms
Throughput 219.32 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 48.345889565s
Average Latency 481.205389ms
Throughput 103.42 requests/second

@alkalescent alkalescent changed the title feat(otdfctl): enforce required policy flags from man docs feat(cli): enforce required policy flags from man docs Aug 5, 2026
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 224.614792ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 178.327905ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 451.998964ms
Throughput 221.24 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 48.511212837s
Average Latency 482.632897ms
Throughput 103.07 requests/second

The man-doc frontmatter already declared `required: true` on many policy
command flags, but `man.DocFlag` never parsed it, so required-ness was only
validated at runtime via GetRequiredString/GetRequiredID. Nothing marked the
flags required at the cobra layer, so tools generated from the command tree
(e.g. MCP) could not advertise which inputs are mandatory.

- Add `Required` to `man.DocFlag` and a `Doc.MarkRequiredFlags()` method
  (mirrors MarkSensitiveFlags; skips flags not registered on the command).
- Apply it to every policy command via a sweep in policy.InitCommands().
- Reconcile the doc `required: true` set with the run functions: add it where
  a flag is unconditionally required but the doc omitted it, and remove it
  where the doc over-claimed (deprecated no-op flags, "one of" groups, and
  paginated limit/offset that default rather than enforce).
Mark the unconditionally-required multi-value flags that the handlers reject
when empty but the docs left optional, so cobra enforces them and generated
schemas advertise them:

- subject-mappings create --action (handler errors on zero actions)
- dynamic-value-mappings create --action (handler errors on zero actions)
- resource-mappings create --terms (GetStringSlice Min: 1)

The subject-condition-set "one of" groups stay unmarked (genuinely conditional).
@alkalescent
alkalescent force-pushed the feat/policy-required-flags-from-docs branch from bb487b8 to 6dfcb9d Compare August 6, 2026 05:12
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 199.069927ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 107.391114ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 438.818797ms
Throughput 227.88 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 52.252320197s
Average Latency 520.618937ms
Throughput 95.69 requests/second

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

⚠️ Govulncheck found vulnerabilities ⚠️

The following modules have known vulnerabilities:

  • examples
  • otdfctl
  • sdk
  • service
  • lib/fixtures
  • tests-bdd

See the workflow run for details.

The policy required-flag sweep makes cobra reject missing required flags with
"required flag(s) \"<flag>\" not set" before the run function executes,
replacing the previous custom messages. Update the e2e BATS assertions across
policy commands to expect the cobra output, including sibling sub-cases BATS did
not reach. Assertions for flags that remain conditionally required or governed by
one-of validation (e.g. get/base-key --kas, subject-mapping SCS) are unchanged.

Signed-off-by: Krish Suchak <suchak.krish@gmail.com>
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant