Skip to content

feat(sdk,cmdline): settable segment and root integrity algorithms (DSPX-4736) - #400

Open
dmihalcik-virtru wants to merge 1 commit into
mainfrom
DSPX-4736-integrity-algorithm-controls
Open

feat(sdk,cmdline): settable segment and root integrity algorithms (DSPX-4736)#400
dmihalcik-virtru wants to merge 1 commit into
mainfrom
DSPX-4736-integrity-algorithm-controls

Conversation

@dmihalcik-virtru

@dmihalcik-virtru dmihalcik-virtru commented Sep 10, 2026

Copy link
Copy Markdown
Member

Summary

Adds explicit controls for the two integrity algorithms a ZTDF writer picks, and makes an unsupported choice fail loudly instead of being silently accepted.

Rationale

The two algorithms are not interchangeable, and the API previously did not say so:

allowed why
segment HS256, GMAC a segment hash is computed over ciphertext AES-GCM actually produced, so "GMAC" means reading back a real authentication tag
root HS256 only the root signature covers the aggregate of the segment hashes, which never passes through AES-GCM — there is no tag to recover, so GMAC would authenticate nothing

sdk

  • Config.withSegmentIntegrityAlgorithm(HS256|GMAC)
  • Config.withRootIntegrityAlgorithm(HS256) — throws IllegalArgumentException for anything else. The option exists so callers can state the choice explicitly and a CLI can surface the refusal, not to widen it. It is self-contained and does not reach into TDF.

cmdline

  • encrypt --root-integrity-algorithm and --segment-integrity-algorithm, with a case-insensitive ITypeConverter so the flags behave like the equivalents in the other OpenTDF CLIs, and ${COMPLETION-CANDIDATES} so the accepted values render in help.
  • The root algorithm is validated before buildSDK(), so an unsupported value is a picocli usage error (exit 2) rather than a failure after a platform round trip.
  • encryptHelp_advertisesIntegrityAlgorithmFlags pins the literal flag names into the rendered encrypt help, because the cross-SDK xtest feature detectors find them by grepping it. Merging this flips the integrity_algs / gmac_root_rejected gates on and stops those cells silently skipping.

Scope

This is the control surface for evaluating DSPX-4703, deliberately separated from the fix. It changes what a writer may choose; it does not change how a manifest that already declares a GMAC root is verified on read. That is the stacked follow-up.

Splitting it this way means the xtest exploit cases can run against this branch for a live "before" baseline, then against the fix branch to watch them go red → green.

Public API notes

Two new static factory methods on Config. Nothing existing changes shape or default behaviour: the segment default stays GMAC, the root default stays HS256.

Test plan

mvn -q compiler:compile compiler:testCompile -pl sdk,cmdline
mvn -q surefire:test -pl cmdline -Dtest=CommandTest

CommandTest: 26 tests, 0 failures — run with this commit as HEAD and the DSPX-4703 fix commit entirely absent, to confirm the branch stands alone.

Coverage added: GMAC rejected for root in three casings, HS256 accepted in two casings (and reaching the later missing-credentials error, proving it was not rejected), both algorithms accepted for segment, an unknown algorithm rejected, converter case-insensitivity, and the help-rendering assertion.

Summary by CodeRabbit

  • New Features

    • Added command-line options to configure root and segment integrity algorithms during encryption.
    • Supported integrity algorithms can be entered case-insensitively, including HS256 and GMAC.
    • Added validation to prevent unsupported root algorithm selections and reject unknown values.
  • Bug Fixes

    • Improved encryption configuration validation so invalid integrity settings are reported before processing begins.

Cross-SDK coverage lives in opentdf/tests#594.

…PX-4736)

Adds explicit controls for the two integrity algorithms a ZTDF writer picks,
and makes an unsupported choice fail loudly instead of being silently accepted.

The two are not interchangeable:
  - A segment hash is computed over ciphertext AES-GCM actually produced, so
    "GMAC" there means reading back a real authentication tag. Both HS256 and
    GMAC are valid.
  - The root signature covers the aggregate of the segment hashes, which never
    passes through AES-GCM. There is no tag to recover, so HS256 is the only
    meaningful choice.

sdk:
  - Config.withSegmentIntegrityAlgorithm(HS256|GMAC)
  - Config.withRootIntegrityAlgorithm(HS256), which throws
    IllegalArgumentException for anything else. The option exists so callers
    can state the choice explicitly and a CLI can surface the refusal, not to
    widen it.

cmdline:
  - `encrypt --root-integrity-algorithm` and `--segment-integrity-algorithm`,
    with a case-insensitive converter so the flags behave like the equivalents
    in the other OpenTDF CLIs, and ${COMPLETION-CANDIDATES} in the description
    so the accepted values appear in help.
  - The root algorithm is validated before buildSDK(), so an unsupported value
    is reported as a picocli usage error (exit 2) rather than after a platform
    round trip.
  - A test pins the literal flag names into the rendered encrypt help, because
    the cross-SDK xtest feature detectors find them by grepping it.

This is the control surface for evaluating DSPX-4703. It does not itself change
how a manifest that already declares a GMAC root is verified on read.

Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
@dmihalcik-virtru
dmihalcik-virtru requested review from a team as code owners September 10, 2026 16:08
@coderabbitai

coderabbitai Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: b919f587-558c-4de8-996d-f5dfa4a1789c

📥 Commits

Reviewing files that changed from the base of the PR and between 98c839e and c51dab1.

📒 Files selected for processing (3)
  • cmdline/src/main/java/io/opentdf/platform/Command.java
  • cmdline/src/test/java/io/opentdf/platform/CommandTest.java
  • sdk/src/main/java/io/opentdf/platform/sdk/Config.java

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The SDK adds root and segment integrity algorithm configuration. The encrypt command adds case-insensitive algorithm options, validates root algorithm support, and tests accepted and rejected values.

Changes

Integrity algorithm configuration

Layer / File(s) Summary
SDK integrity configuration
sdk/src/main/java/io/opentdf/platform/sdk/Config.java
Config adds configurators for segment and root integrity algorithms. Root configuration accepts only HS256.
Encrypt command parsing and validation
cmdline/src/main/java/io/opentdf/platform/Command.java, cmdline/src/test/java/io/opentdf/platform/CommandTest.java
The encrypt command accepts both algorithm options through a case-insensitive converter. Tests cover help output, valid values, unsupported root values, unknown values, and casing.

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

Severity of issue fixed: Low

Sequence Diagram(s)

sequenceDiagram
  participant EncryptCommand
  participant IntegrityAlgorithmConverter
  participant Config
  participant TDFConfig
  EncryptCommand->>IntegrityAlgorithmConverter: Convert option value
  IntegrityAlgorithmConverter-->>EncryptCommand: Return IntegrityAlgorithm
  EncryptCommand->>Config: Build integrity configuration
  Config-->>EncryptCommand: Return TDFConfig option
  EncryptCommand->>TDFConfig: Apply configuration before SDK creation
Loading

Suggested reviewers: mkleene

Merge Risk: ⚪ Minimal · up to c51da

This change adds configurable segment and root integrity algorithms with validation and case-insensitive CLI parsing. The supplied coverage addresses accepted and rejected inputs, so no merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 15 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding configurable segment and root integrity algorithms in the SDK and command-line interface.
  • Fix all pre-merge checks with AI
✨ 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 DSPX-4736-integrity-algorithm-controls

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

A rabbit checks each flag,
Root rules hold the path,
Segment values pass,
Tests catch invalid inputs,
The SDK stays aligned.

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

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
0.0% Coverage on New Code (required ≥ 33%)

See analysis details on SonarQube Cloud

@github-actions

Copy link
Copy Markdown
Contributor

@dmihalcik-virtru
dmihalcik-virtru added this pull request to stack #402 September 10, 2026 19:32
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