Skip to content

chore(sdk): alias experimental/tdf manifest and assertion types - #3943

Merged
dmihalcik-virtru merged 2 commits into
mainfrom
dspx-2604-14-type-aliases
Sep 22, 2026
Merged

dmihalcik-virtru merged 2 commits into
mainfrom
dspx-2604-14-type-aliases

Conversation

@dmihalcik-virtru

@dmihalcik-virtru dmihalcik-virtru commented Sep 1, 2026 •

Copy link
Copy Markdown
Member

Part 14 of 20 in the DSPX-2604 re-cut. Base branch: dspx-2604-13-unresolved-kas.

This stack replaces #3782 / #3865 / #3921, which stay open and untouched
until it lands. Nothing here is a rebase of those branches — the work was
re-cut from the ticket so each PR stands on its own.

Proposed Changes

sdk/experimental/tdf carried its own copies of the manifest and assertion
types -- Manifest, Segment, KeyAccess, Assertion, Statement,
AssertionKey and the rest -- structurally identical to the ones in sdk
but distinct to the type system, so anything crossing the boundary needed
conversion. Two copies of the JWT signing and verification logic also had
to be kept in step by hand.

Replaces both files' definitions with type aliases. sdk owns the
definitions; this package re-exports them. Every exported name and every
method survives: Assertion.Sign / Verify / GetHash,
Statement.UnmarshalJSON, AssertionKey.IsEmpty / Algorithm,
AssertionVerificationKeys.Get / IsEmpty and the five String() methods
all come along with the aliased types, so importers compile unchanged. A
manifest produced here can now be handed to the stable SDK without
conversion, which is what the follow-up delegation needs.

Two deliberate non-aliases:

Policy, PolicyBody and PolicyAttribute stay local. sdk.PolicyObject
declares Body as an anonymous struct over an unexported element type, so
there is no nameable sdk equivalent to alias to. Exporting those in sdk
first would make the alias possible; that is a separate change.

IntegrityAlgorithm stays a distinct int type. sdk.IntegrityAlgorithm
is itself = int, so no method can be attached to it, and aliasing would
silently drop String() from this package's public API. The underlying
values match, so the two convert freely.

kSplitKeyType, kPolicyBindingAlg, kGMACPayloadLength and
calculateSignature are retained verbatim: this package still builds its
own manifests and they have callers in writer.go and key_access.go.
The change that removes those callers removes these too.

No behavior change. The package's existing tests pass unmodified.

Checklist

  • I have added or updated unit tests
  • I have added or updated integration tests (if appropriate)
  • I have added or updated documentation

Testing Instructions

cd sdk && go test ./experimental/... -race

No behavior change — the point is that the package's existing tests pass
unmodified against aliased types.

The full DSPX-2604 stack — 20 PRs
# PR Based on
01 #3930 chore: bump go.work toolchain to go1.25.12 and simplify an rt_test condition main
02 #3931 feat(sdk): make the zipstream clock injectable for deterministic ZIP output main
03 #3932 fix(sdk): reject a zipstream write set that omits segment 0 #3931
04 #3933 fix(sdk): map ReadAt plaintext offsets from cumulative segment sizes main
05 #3934 chore(sdk): extract integrityAlgorithmString, createPolicyBinding, signAssertions main
06 #3935 chore(sdk): add direct tests for createKeyAccess, encryptMetadata and tdfSalt main
07 #3936 fix(sdk): fill each segment with io.ReadFull and size the buffer to the input main
08 #3937 chore(cli): move streaming IO helpers into pkg main
09 #3938 fix(cli): stream encrypt instead of buffering the whole payload #3937
10 #3939 fix(cli): stream decrypt and inspect instead of buffering #3938
11 #3940 feat(sdk): add a chunked segment writer (experimental) dspx-2604-base-11 = #3932 + #3934 + #3935
12 #3941 fix(sdk): stop GetManifest from splitting the key under the lock #3940
13 #3942 fix(sdk): reject a chunked split naming a KAS with no resolved public key #3941
14 #3943 chore(sdk): alias experimental/tdf manifest and assertion types #3942
15 #3944 fix(sdk): emit spec-compliant key access in experimental/tdf and delegate Writer #3943
16 #3945 feat(sdk): accept io.Reader in CreateTDF and drop the 64 GB payload cap #3936
17 #3946 chore(sdk): rewrite CreateTDF on top of the chunked writer dspx-2604-base-17 = #3944 + #3945
18 #3947 chore(sdk): drop dead TDFConfig fields and deprecate the TDFFormat enum #3946
19 #3948 fix(cli): drop the encrypt-side stdin spool dspx-2604-base-19 = #3947 + #3939
20 #3949 feat(sdk): graduate the chunked writer to stable API #3948

Reviewable in parallel right now, since they sit directly on main and depend on
nothing else: 01, 02, 04, 05, 06, 07, 08.

Why three PRs have a dspx-2604-base-* base. A GitHub PR takes one base branch,
but 11, 17 and 19 each build on more than one parent. The base-* branches are empty
merge commits that exist only to join those parents so the PR diff shows exactly its
own change and nothing else. They contain no code, have no PR of their own, and go
away once their parents land — retarget the child onto main at that point.

Wants a cross-SDK xtest run before merge: 15, 17 (and therefore 20). They touch
the KAS wire format.

Red checks you may see are network flakes, not this stack. Four distinct ones hit
this batch and all clear on re-run: golangci-lint config verify timing out on
https://golangci-lint.run/.../golangci.v2.8.jsonschema.json (fails the whole go (<module>) job and fail-fast cancels its siblings), the bats installer getting a 403,
Docker Hub timing out on keycloak/keycloak:26.4, and buf reporting "the server
hosted at that remote is unavailable" while the Java SDK generates sources. The
govulncheck step also emits ##[error] annotations against the go1.25.11 stdlib, but
it is continue-on-error: true and never fails a job — 01 bumps the toolchain and
clears those annotations.

Summary by CodeRabbit

  • Compatibility

    • Experimental TDF manifest and assertion types now align with the stable SDK, enabling direct interoperability without type conversion.
    • Existing assertion and manifest behavior is provided through the stable SDK definitions.
  • Documentation

    • Clarified the relationship between the experimental TDF package and the stable SDK.
    • Updated documentation for missing assertion verification keys to reflect current behavior.

@dmihalcik-virtru
dmihalcik-virtru requested review from a team as code owners September 1, 2026 02:57
@coderabbitai

coderabbitai Bot commented Sep 1, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Warning

Review limit reached

Next included review available in 26 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 4029c49d-27b7-4a80-b1a6-05da848be82f

📥 Commits

Reviewing files that changed from the base of the PR and between d9df0fd and 83d8831.

📒 Files selected for processing (1)
  • sdk/experimental/tdf/assertion.go

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 130c8189-4a6e-4eff-b01a-0bf93ed01849

📥 Commits

Reviewing files that changed from the base of the PR and between 1abae3e and d9df0fd.

📒 Files selected for processing (4)
  • sdk/assertion.go
  • sdk/experimental/tdf/assertion.go
  • sdk/experimental/tdf/doc.go
  • sdk/experimental/tdf/manifest.go

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


📝 Walkthrough

Walkthrough

The experimental TDF package now aliases assertion and manifest types to the stable SDK. Local assertion implementations were removed. Policy types remain local because they lack compatible SDK equivalents. Documentation and one SDK comment now describe these relationships.

Changes

TDF SDK Alias Consolidation

Layer / File(s) Summary
Assertion SDK aliases
sdk/experimental/tdf/assertion.go, sdk/assertion.go
Assertion types, constants, and methods now use stable SDK definitions. Local signing, verification, hashing, and JSON unmarshalling implementations were removed.
Manifest SDK aliases
sdk/experimental/tdf/manifest.go, sdk/experimental/tdf/doc.go
Manifest structures now alias stable SDK types. Policy, PolicyBody, and PolicyAttribute remain local, with documentation describing the compatibility limitation.

Priority: ⬇️ Low

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

Change: Refactor

Suggested reviewers: elizabethhealy

Merge Risk: ⚪ Minimal · up to d9df0

The aliases preserve the inspected SDK behavior, and no merge-blocking regression was established.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 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 the main change: aliasing the experimental TDF manifest and assertion types to the stable SDK types.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 7 files.
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
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

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 checked the SDK gate
And found shared types aligned in state
Assertions hop on stable ground
Manifest aliases gather round
Local policies stay in place
While docs explain their special case

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

@github-actions github-actions Bot added comp:sdk A software development kit, including library, for client applications and inter-service communicati size/l labels Sep 1, 2026
@github-actions

github-actions Bot commented Sep 1, 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 255.575311ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 418.615697ms
Throughput 238.88 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 42.780620226s
Average Latency 426.574043ms
Throughput 116.88 requests/second

@dmihalcik-virtru
dmihalcik-virtru force-pushed the dspx-2604-14-type-aliases branch from 0c00bb2 to a3447fc Compare September 1, 2026 03:30
@dmihalcik-virtru dmihalcik-virtru changed the title refactor(sdk/experimental/tdf): alias manifest and assertion types onto sdk refactor(sdk): alias experimental/tdf manifest and assertion types Sep 1, 2026
@dmihalcik-virtru
dmihalcik-virtru force-pushed the dspx-2604-13-unresolved-kas branch from 7f0cb1b to fd974c3 Compare September 1, 2026 03:36
@dmihalcik-virtru
dmihalcik-virtru force-pushed the dspx-2604-14-type-aliases branch from a3447fc to db38449 Compare September 1, 2026 03:36
@github-actions

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 245.553809ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 462.874991ms
Throughput 216.04 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 1m2.193839396s
Average Latency 620.599109ms
Throughput 80.39 requests/second

@dmihalcik-virtru
dmihalcik-virtru force-pushed the dspx-2604-12-getmanifest-lock branch from c08ed03 to c068a0c Compare September 17, 2026 16:47
@dmihalcik-virtru
dmihalcik-virtru force-pushed the dspx-2604-14-type-aliases branch from 8127c71 to 1abae3e Compare September 17, 2026 16:47
@github-actions

Copy link
Copy Markdown
Contributor

X-Test Failure Report

@github-actions

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 188.513151ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 409.831741ms
Throughput 244.00 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 54.10423067s
Average Latency 539.926061ms
Throughput 92.41 requests/second

@github-actions

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 235.094779ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 418.916346ms
Throughput 238.71 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 58.74724847s
Average Latency 586.170453ms
Throughput 85.11 requests/second

Base automatically changed from dspx-2604-12-getmanifest-lock to main September 21, 2026 21:21
@dmihalcik-virtru
dmihalcik-virtru force-pushed the dspx-2604-14-type-aliases branch from 1abae3e to 42867d8 Compare September 21, 2026 21:34
@github-actions

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 257.327282ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 425.265126ms
Throughput 235.15 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 1m2.504687827s
Average Latency 623.802358ms
Throughput 79.99 requests/second

@dmihalcik-virtru
dmihalcik-virtru force-pushed the dspx-2604-14-type-aliases branch from 42867d8 to 1d24f7a Compare September 21, 2026 22:02
@github-actions

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 245.509469ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 422.357152ms
Throughput 236.77 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 1m2.666699168s
Average Latency 625.143707ms
Throughput 79.79 requests/second

`sdk/experimental/tdf` carried its own copies of the manifest and assertion
types -- `Manifest`, `Segment`, `KeyAccess`, `Assertion`, `Statement`,
`AssertionKey` and the rest -- structurally identical to the ones in `sdk`
but distinct to the type system, so anything crossing the boundary needed
conversion. Two copies of the JWT signing and verification logic also had
to be kept in step by hand.

Replaces both files' definitions with type aliases. `sdk` owns the
definitions; this package re-exports them. Every exported name and every
method survives: `Assertion.Sign` / `Verify` / `GetHash`,
`Statement.UnmarshalJSON`, `AssertionKey.IsEmpty` / `Algorithm`,
`AssertionVerificationKeys.Get` / `IsEmpty` and the five `String()` methods
all come along with the aliased types, so importers compile unchanged. A
manifest produced here can now be handed to the stable SDK without
conversion, which is what the follow-up delegation needs.

Two deliberate non-aliases:

`Policy`, `PolicyBody` and `PolicyAttribute` stay local. `sdk.PolicyObject`
is itself exported and could be aliased, but it declares `Body` as an
anonymous struct over the unexported `attributeObject`, so `PolicyBody` and
`PolicyAttribute` have no sdk names to alias to, and the local ones are not
assignable to `Body`. Aliasing `Policy` alone would break every caller that
names the other two. For the alias to become possible `sdk` would have to
both export the attribute type and give `Body` a named one; that is a
separate change.

`IntegrityAlgorithm` stays a distinct `int` type. `sdk.IntegrityAlgorithm`
is itself `= int`, so no method can be attached to it, and aliasing would
silently drop `String()` from this package's public API. The underlying
values match, so the two convert freely.

`kSplitKeyType`, `kPolicyBindingAlg` and `kGMACPayloadLength` are retained
verbatim: this package still builds its own manifests and they have callers
in `writer.go` and `key_access.go`. The change that removes those callers
must delete these constants too, or they are left unused. (`calculateSignature`
was part of this set until #4030 removed it; the integrity helpers here are
now `hmacIntegrity`, `segmentIntegrity` and `rootIntegrity`.)

No behavior change. The package's existing tests pass unmodified.

Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
@dmihalcik-virtru
dmihalcik-virtru force-pushed the dspx-2604-14-type-aliases branch from 1d24f7a to d9df0fd Compare September 22, 2026 12:33
@github-actions

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 249.477714ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 428.790628ms
Throughput 233.21 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 58.174352463s
Average Latency 580.338161ms
Throughput 85.95 requests/second

Comment thread sdk/experimental/tdf/assertion.go Outdated
@github-actions

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 255.762263ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 431.148527ms
Throughput 231.94 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 58.927689426s
Average Latency 587.920125ms
Throughput 84.85 requests/second

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Govulncheck found vulnerabilities ⚠️

The following modules have known vulnerabilities:

  • otdfctl
  • service
  • tests-bdd

See the workflow run for details.

@dmihalcik-virtru
dmihalcik-virtru added this pull request to the merge queue Sep 22, 2026
Merged via the queue into main with commit 04475bb Sep 22, 2026
47 checks passed
@dmihalcik-virtru
dmihalcik-virtru deleted the dspx-2604-14-type-aliases branch September 22, 2026 14:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp:sdk A software development kit, including library, for client applications and inter-service communicati size/l

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants