Skip to content

feat(kas): support ML-KEM client session keys in rewrap - #3814

Open
dmihalcik-virtru wants to merge 2 commits into
mainfrom
DSPX-4221-pq-sessions
Open

feat(kas): support ML-KEM client session keys in rewrap#3814
dmihalcik-virtru wants to merge 2 commits into
mainfrom
DSPX-4221-pq-sessions

Conversation

@dmihalcik-virtru

@dmihalcik-virtru dmihalcik-virtru commented Jul 31, 2026

Copy link
Copy Markdown
Member

Summary

Part of DSPX-4221 (Session Keys should support ML-KEM). rewrap's clientPublicKey — the client-generated ephemeral "session key" used to wrap the response DEK back to the client — only accepted RSA/EC keys. extractSRTBody parsed it with x509.ParsePKIXPublicKey, which doesn't recognize ML-KEM's SPKI OID and rejected it as a parse failure before the request ever reached the (already KEM-aware) wrap dispatch.

Changes

  • service/kas/access/rewrap.go: extractSRTBody now recognizes pure ML-KEM-768/1024 SPKI client public keys via ocrypto.ParseKEMPublicSPKI, mirroring the dispatch order ocrypto.FromPublicPEMWithSalt already uses internally. tdf3Rewrap gates the ML-KEM session-key path on Preview.MLKEMTDFEnabled, matching the existing EC gate (Preview.ECTDFEnabled). The wrap-to-client-key crypto itself needed no changes — ocrypto.FromPublicPEMWithSalt already dispatches ML-KEM/hybrid keys to the KEM encryptor, since it's shared with the KAS-managed-key (mlkem-wrapped KAO) path.
  • sdk/kas_client.go: unwrap() only branched EC vs RSA; added an ML-KEM branch (handleKEMKeyResponse/processKEMResponse) so the Go SDK can decrypt a rewrap response wrapped to an ML-KEM session key. sdk.WithSessionKeyType(ocrypto.MLKEM768Key / MLKEM1024Key) already existed but previously caused a decrypt-time failure since unwrap() would try (and fail) to type-assert the KEM decryptor as RSA.
  • otdfctl: --session-key-algorithm now accepts mlkem:768/mlkem:1024 (the underlying sdk.WithSessionKeyType plumbing already supported these ocrypto.KeyType values, just not the CLI flag mapping); updated docs/man/decrypt.

New audit field: sessionKeyType

A rewrap succeeding doesn't by itself prove which session-key type KAS actually used — nothing observable previously recorded it, so the companion xtest PR could only infer correctness indirectly from a successful decrypt (which would also pass if a client silently fell back to RSA). To make that test load-bearing:

  • service/logger/audit/rewrap.go: RewrapAuditEventParams gains a SessionKeyType field, surfaced as eventMetaData.sessionKeyType on rewrap audit events.
  • service/kas/access/rewrap.go: populates it from asymEncrypt.KeyType() (already computed for the Preview.MLKEMTDFEnabled gate above) when building each KAO's audit event.
  • Updated the existing service/logger/audit unit tests for the new field.

Scope

Deliberately limited to pure ML-KEM (768/1024), matching the ticket title and the existing mechanism-mlkem precedent — hybrid PQ/T session keys (X-Wing, secp+ML-KEM) are out of scope here.

Test plan

go build ./service/... ./sdk/... ./otdfctl/...
go vet ./service/kas/... ./service/logger/... ./sdk/...
go test ./service/kas/... ./service/logger/... ./sdk/...
gofmt -l service/kas/access/rewrap.go service/logger/audit/rewrap.go service/logger/audit/rewrap_test.go service/logger/audit/logger_test.go sdk/kas_client.go otdfctl/cmd/tdf/decrypt.go

All pass, no regressions. Manually verified otdfctl help decrypt now lists mlkem:768/mlkem:1024 for --session-key-algorithm.

Related work

Companion PRs:

Ref: DSPX-4221

Summary by CodeRabbit

  • New Features

    • Added support for ML-KEM-768 and ML-KEM-1024 session-key algorithms in decryption and key rewrapping.
    • Added ML-KEM session-key options and usage examples to CLI documentation.
    • Added support for processing permitted wrapped keys and preserving obligation metadata.
  • Security & Auditing

    • ML-KEM rewrapping is restricted when preview functionality is disabled.
    • Rewrap audit events now record the session-key type.

@dmihalcik-virtru
dmihalcik-virtru requested review from a team as code owners July 31, 2026 21:35
@github-actions github-actions Bot added comp:sdk A software development kit, including library, for client applications and inter-service communicati comp:kas Key Access Server size/m labels Jul 31, 2026
@coderabbitai

coderabbitai Bot commented Jul 31, 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: d66cab13-bd94-485c-9abe-8581098b1fb5

📥 Commits

Reviewing files that changed from the base of the PR and between e3725bf and 5f9a4de.

📒 Files selected for processing (8)
  • otdfctl/cmd/tdf/decrypt.go
  • otdfctl/docs/man/decrypt/_index.md
  • sdk/kas_client.go
  • service/kas/access/rewrap.go
  • service/logger/audit/logger_test.go
  • service/logger/audit/rewrap.go
  • service/logger/audit/rewrap_test.go
  • spec/DSPX-4221.md

📝 Walkthrough

Walkthrough

Decryption now supports ML-KEM-768 and ML-KEM-1024 session keys. The KAS client processes ML-KEM responses. The rewrap service recognizes ML-KEM keys, enforces preview gating, and records the session key type in audit events. Documentation and a draft specification were added.

Changes

ML-KEM session-key support

Layer / File(s) Summary
Client selection and specification
otdfctl/cmd/tdf/decrypt.go, otdfctl/docs/man/decrypt/_index.md, spec/DSPX-4221.md
The CLI accepts and documents ML-KEM-768 and ML-KEM-1024 session-key algorithms. The DSPX-4221 specification defines session-key contracts, preview gating, scope, and acceptance criteria.
KAS ML-KEM unwrap processing
sdk/kas_client.go
KAS unwrap dispatches ML-KEM responses to a KEM handler. The handler decrypts permitted wrapped keys, preserves obligations, and records decryption or denial errors.
Server rewrap and audit metadata
service/kas/access/rewrap.go, service/logger/audit/rewrap.go, service/logger/audit/*_test.go
The rewrap service recognizes ML-KEM SPKI keys and rejects ML-KEM rewraps when preview support is disabled. Rewrap audit events include sessionKeyType, with updated immediate and deferred event tests.

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

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant KASClient
  participant RewrapService
  participant AuditLogger
  CLI->>KASClient: Select ML-KEM session key
  KASClient->>RewrapService: Request rewrap
  RewrapService->>RewrapService: Validate ML-KEM preview support
  RewrapService-->>KASClient: Return KAO results
  RewrapService->>AuditLogger: Record sessionKeyType
  KASClient->>KASClient: Decrypt permitted wrapped keys
  KASClient-->>CLI: Return decrypted keys and obligations
Loading

Possibly related PRs

Suggested labels: docs

Suggested reviewers: strantalis

Poem

A rabbit checks each ML-KEM key,
While KAS unwraps what it can see.
Audit fields record the type,
Preview gates keep flows precise.
The CLI documents every leap.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.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 summarizes the primary change: support for ML-KEM client session keys in KAS rewrap flows.
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 DSPX-4221-pq-sessions

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@spec/DSPX-4221.md`:
- Line 21: Update the wording in the ML-KEM session encryption requirement to
use the hyphenated compound adjective “client-generated” before “key pair.”
- Line 20: Insert one blank line immediately after each Markdown section heading
in spec/DSPX-4221.md, including the headings at lines 20, 23, 26, 29, 32, 35,
and 38, so the document satisfies MD022.
- Around line 20-40: Complete the DSPX-4221 specification by replacing all
template placeholders with concrete requirements covering mlkem:768 and
mlkem:1024 support, pure versus hybrid scope, preview gating, rewrap and
decryption behavior, contracts, constraints, out-of-scope items, and testable
acceptance criteria.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a027b735-ad03-4660-934b-4c85249d7e80

📥 Commits

Reviewing files that changed from the base of the PR and between 4e140ac and 33e7fce.

📒 Files selected for processing (5)
  • otdfctl/cmd/tdf/decrypt.go
  • otdfctl/docs/man/decrypt/_index.md
  • sdk/kas_client.go
  • service/kas/access/rewrap.go
  • spec/DSPX-4221.md

Comment thread spec/DSPX-4221.md
Comment thread spec/DSPX-4221.md Outdated
Comment thread spec/DSPX-4221.md 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 248.368523ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 420.215968ms
Throughput 237.97 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 50.858163359s
Average Latency 506.324883ms
Throughput 98.31 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 218.79516ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 433.252595ms
Throughput 230.81 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 54.130352027s
Average Latency 539.671697ms
Throughput 92.37 requests/second

@github-actions

github-actions Bot commented Aug 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 201.522414ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 440.171793ms
Throughput 227.18 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 52.510271245s
Average Latency 523.636634ms
Throughput 95.22 requests/second

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@spec/DSPX-4221.md`:
- Line 45: Update the Go SDK contract entry for sdk.WithSessionKeyType to remove
the invalid bitwise OR expression on string-based ocrypto.KeyType values. List
separate calls for MLKEM768Key and MLKEM1024Key if either option is supported,
or describe accepting both options in prose outside code formatting.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 0ae928d2-8118-4f28-a031-389390aef2db

📥 Commits

Reviewing files that changed from the base of the PR and between 33e7fce and e3725bf.

📒 Files selected for processing (8)
  • otdfctl/cmd/tdf/decrypt.go
  • otdfctl/docs/man/decrypt/_index.md
  • sdk/kas_client.go
  • service/kas/access/rewrap.go
  • service/logger/audit/logger_test.go
  • service/logger/audit/rewrap.go
  • service/logger/audit/rewrap_test.go
  • spec/DSPX-4221.md

Comment thread spec/DSPX-4221.md Outdated
Address CodeRabbit review comments on spec/DSPX-4221.md:
- Fix invalid Go syntax in the SDK contract example (ocrypto.KeyType is a
  string type; bitwise-OR between two enum values doesn't compile).
- Remove the "and vice versa" independence claim, which overstated test
  coverage (only RSA-wrapped-TDF + ML-KEM-session-key is tested).

Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
@github-actions

github-actions Bot commented Aug 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 188.175262ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 439.876583ms
Throughput 227.34 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 49.209714086s
Average Latency 490.80922ms
Throughput 101.61 requests/second

@github-actions

github-actions Bot commented Aug 1, 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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds end-to-end support for pure ML-KEM (768/1024) client session keys in the KAS rewrap flow, so clients can request a PQ session key for wrapping the response DEK and successfully decrypt the rewrap response.

Changes:

  • KAS rewrap request parsing now recognizes ML-KEM SPKI client public keys and gates ML-KEM session-key rewrap behind Preview.MLKEMTDFEnabled; rewrap audit events now record sessionKeyType.
  • Go SDK KASClient.unwrap() adds an ML-KEM branch to decapsulate/decrypt rewrap responses when the session key type is ML-KEM.
  • otdfctl decrypt --session-key-algorithm and docs now accept/document mlkem:768 and mlkem:1024; added spec/ticket write-up.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
spec/DSPX-4221.md Spec/ticket documentation for ML-KEM session-key support and acceptance criteria.
service/logger/audit/rewrap.go Adds sessionKeyType to rewrap audit event metadata.
service/logger/audit/rewrap_test.go Updates audit event unit test expectations to include sessionKeyType.
service/logger/audit/logger_test.go Updates logger JSON assertions to include sessionKeyType in rewrap audit logs.
service/kas/access/rewrap.go Accepts ML-KEM SPKI in extractSRTBody, gates ML-KEM session-key rewrap via preview flag, and populates audit SessionKeyType.
sdk/kas_client.go Adds ML-KEM unwrap/decrypt handling for rewrap responses.
otdfctl/docs/man/decrypt/_index.md Documents mlkem:768/mlkem:1024 for --session-key-algorithm and adds an example.
otdfctl/cmd/tdf/decrypt.go Maps mlkem:768/mlkem:1024 CLI values to ocrypto key types.
Suppressed comments (2)

service/kas/access/rewrap.go:1045

  • The new preview gate for ML-KEM session-key rewrap lacks test coverage. There are tests for other rewrap behavior, but none that assert an ML-KEM clientPublicKey is rejected when Preview.MLKEMTDFEnabled is false and accepted when true.
	if ocrypto.IsMLKEMKeyType(asymEncrypt.KeyType()) && !p.Preview.MLKEMTDFEnabled {
		p.Logger.ErrorContext(ctx, "ml-kem session key rewrap not enabled")
		failAllKaos(requests, results, err400("invalid request"))
		return "", results, nil
	}

sdk/kas_client.go:318

  • Error message is misleading: this failure is from k.sessionKey.PrivateKeyInPemFormat(), not ocrypto.PrivateKeyInPemFormat. Consider aligning wording with the EC path ("failed to get private key").
	clientPrivateKey, err := k.sessionKey.PrivateKeyInPemFormat()
	if err != nil {
		return nil, fmt.Errorf("ocrypto.PrivateKeyInPemFormat failed: %w", err)
	}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +450 to +454
// Pure ML-KEM client session keys are SPKI-wrapped under the NIST ML-KEM
// OIDs (FIPS 203), which x509.ParsePKIXPublicKey does not recognize and
// would otherwise reject as a parse failure. Accept them here; whether
// ML-KEM rewrap is actually enabled is checked later in tdf3Rewrap.
if oid, _, kemErr := ocrypto.ParseKEMPublicSPKI(block.Bytes); kemErr == nil &&
Comment thread sdk/kas_client.go
Comment on lines +186 to +190
switch {
case ocrypto.IsECKeyType(k.sessionKey.GetKeyType()):
return k.handleECKeyResponse(response)
case ocrypto.IsMLKEMKeyType(k.sessionKey.GetKeyType()):
return k.handleKEMKeyResponse(response)
dmihalcik-virtru added a commit to opentdf/tests that referenced this pull request Aug 3, 2026
Address CodeRabbit review comments on spec/DSPX-4221.md:
- Note the platform-side session-key-mlkem feature-detection imprecision
  (reuses the pre-existing Preview.MLKEMTDFEnabled/mechanism probe rather
  than a dedicated readiness check; each SDK's own hardcoded capability
  flag is what actually gates the test), matching the comment already in
  tdfs.py's feature-detection block.
- Fix invalid Go syntax in the SDK contract example (ocrypto.KeyType is a
  string type; bitwise-OR between two enum values doesn't compile).
- Remove the "and vice versa" independence claim, which overstated test
  coverage (only RSA-wrapped-TDF + ML-KEM-session-key is tested).

Fix a real CI failure this surfaced: the plain assert_rewrap_success(
session_key_type=X) pattern used for the new EC/RSA/ML-KEM session-key-type
assertions has two problems that only show up once you assert on the
*specific* algorithm rather than just "a rewrap succeeded":

1. eventMetaData.sessionKeyType is new (added by the companion platform PR,
   unreleased) and not behind any version/preview flag we can check
   statically. Asserting a specific value against a baseline/pre-fix
   platform build finds zero matches -- indistinguishable from a real
   negotiation bug. Broke test_tdf_roundtrip's new ecwrap assertion and
   test_session_key_rsa_roundtrip against CI's baseline (unpatched) platform
   matrix.
2. Log collection is poll-based. When two rewraps for different session
   keys happen back-to-back in the same test (a plain decrypt immediately
   followed by one requesting a specific algorithm), the earlier rewrap's
   log line can still be un-tailed at the time of the later mark and get
   folded into the same collection batch -- a bare count-based assertion
   then reports success using the wrong (earlier) event instead of waiting
   for the right one. Reproduced locally: test_tdf_roundtrip[...-ztdf-ecwrap]
   failed 3/3 runs with "Expected session_key_type=ec:secp256r1, but
   platform reported {'rsa:2048'}" even against the patched platform PR
   branch, where the feature itself works correctly (confirmed via a
   standalone otdfctl decrypt + raw platform.log inspection).

Added AuditLogAsserter.assert_rewrap_session_key_type(), which waits for an
event matching the expected type before falling back to a short existence
check (present-but-different-value still fails loudly; field-never-present
logs a warning and passes). Used by test_tdf_roundtrip's ecwrap block and
both test_session_key_rsa_roundtrip and test_session_key_mlkem_roundtrip.
Verified locally against the platform PR branch: all three pass
consistently now (previously ecwrap failed 3/3 runs).

Also address a Copilot review finding on SDK.decrypt(): ecwrap=True and
session_key_algorithm could both be set, which the CLI wrappers turn into
duplicate/competing --session-key-algorithm (or --rewrap-key-type) flags,
with the winner depending on the underlying CLI's parsing order rather than
caller intent. No current call site combines them, but rather than leave
that as an implicit landmine, decrypt() now raises ValueError if both are
passed -- ecwrap is shorthand for session_key_algorithm="ec:secp256r1"
anyway.

Remove the now-redundant decrypt-side XT_WITH_ECWRAP shortcut. It predates
session_key_algorithm and was pure sugar for
session_key_algorithm="ec:secp256r1"; XT_WITH_ECWRAP stays for encrypt
(selects the TDF's own KAO wrapping mechanism, an unrelated axis).
Dropped SDK.decrypt()'s ecwrap bool param (one call site, migrated to
session_key_algorithm), removed the dead decrypt-branch XT_WITH_ECWRAP
handling from all three cli.sh wrappers, and updated each script's env-var
doc comment. Verified against go, java, and js (companion PR branch)
decrypt SDKs -- all pass.

Add a TODO in assert_rewrap_session_key_type() documenting the plan for
closing the remaining gap: once opentdf/platform#3814 merges and cuts a
release, gate on a version-checked "audit-session-key-type" feature
(mirroring the existing audit_logging pattern) and hard-fail on mismatch
instead of warning. Not actionable yet since there is no release version
to check against pre-merge -- see the stacked draft PR reproducing the gap
this leaves open (unpatched web-sdk silently sending the wrong session-key
algorithm on EC rewrap, masked when paired with an unpatched platform that
does not emit the field at all).

Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp:kas Key Access Server comp:sdk A software development kit, including library, for client applications and inter-service communicati size/m

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants