Skip to content

feat(kas): Add kas uri resolver#3062

Open
c-r33d wants to merge 4 commits intoserver-opts-supportfrom
kas_registered_uri
Open

feat(kas): Add kas uri resolver#3062
c-r33d wants to merge 4 commits intoserver-opts-supportfrom
kas_registered_uri

Conversation

@c-r33d
Copy link
Contributor

@c-r33d c-r33d commented Feb 9, 2026

Proposed Changes

1.) Add a kas uri resolver that can be injected into the server start options
2.) Default is to use the static resolver that reads the registered_kas_uri from the kas configuration for previous backwards compatibility.

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

pflynn-virtru and others added 2 commits February 9, 2026 15:20
## Summary
- Upgrades `go` directive to `1.25.0` and `toolchain` to `go1.25.7` in
all workspace modules and `go.work`
- Addresses GO-2026-4337 (`crypto/tls` vulnerability, fixed in go1.25.7)
- Updates `golangci-lint` from `v2.1` to `v2.8.0` in CI workflow and
Makefile (required for Go 1.25 compatibility)
- Updates `govulncheck` `go-version-input` to `1.25.7` in `checks.yaml`
and `vulnerability-check.yaml`
- Updates `sonarcloud.yml` Go version from `1.23` to `1.25.7`

## Test plan
- [x] `go mod tidy` succeeds in all modules
- [x] `go build ./...` succeeds in all modules
- [ ] CI checks pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: Paul Flynn <pflynn@virtru.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
@c-r33d c-r33d requested review from a team as code owners February 9, 2026 15:55
@github-actions github-actions bot added comp:kas Key Access Server size/m labels Feb 9, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @c-r33d, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant architectural improvement by abstracting the Key Access Server (KAS) URI resolution mechanism. It replaces direct string-based KAS URI handling with a flexible interface and an injectable resolver. This change allows for more dynamic and configurable KAS URI management, while ensuring that existing setups continue to function seamlessly through a default static resolver. The primary impact is increased extensibility and maintainability for how KAS endpoints are discovered and utilized within the system.

Highlights

  • Introduced RegisteredKasURIResolver Interface: A new interface, trust.RegisteredKasURIResolver, has been defined, allowing for flexible and pluggable strategies to resolve the Key Access Server (KAS) URI.
  • Default StaticRegisteredKasURIResolver Implementation: A concrete implementation, StaticRegisteredKasURIResolver, was added. This resolver returns a pre-configured KAS URI, ensuring backward compatibility with existing configurations.
  • KAS Service Integration: The KAS service initialization now checks for an injected RegisteredKasURIResolver. If none is provided, it defaults to using the StaticRegisteredKasURIResolver based on the existing determineKASURL logic.
  • Dynamic KAS URI Resolution in KeyIndexer: The KeyIndexer component has been refactored to store and utilize the RegisteredKasURIResolver interface instead of a static KAS URI string. This means KAS URI lookups are now dynamically resolved at the point of use.
  • Injectable via Server Options: The new resolver can be injected into the server's StartConfig via a WithRegisteredKasURIResolver option, providing extensibility for different URI resolution needs.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • service/kas/kas.go
    • Refactored KAS service initialization to accept and utilize a RegisteredKasURIResolver.
    • Implemented a fallback mechanism to create a StaticRegisteredKasURIResolver if no custom resolver is provided, preserving existing behavior.
    • Updated NewPlatformKeyIndexer call to pass the new resolver interface.
  • service/kas/key_indexer.go
    • Modified KeyIndexer struct to hold a trust.RegisteredKasURIResolver instead of a kasURI string.
    • Updated NewPlatformKeyIndexer constructor to accept the resolver.
    • Adjusted String(), FindKeyByAlgorithm(), FindKeyByID(), and ListKeysWith() methods to dynamically resolve the KAS URI using the stored resolver.
    • Added a new private method resolveKASURI() to encapsulate URI resolution logic.
  • service/kas/key_indexer_test.go
    • Introduced constants for test KAS URIs and key IDs to improve test readability and maintainability.
    • Updated MockKeyAccessServerRegistryClient.GetKey to correctly handle mock calls.
    • Modified various test cases (TestKeyDetails, TestListKeysWith, TestListKeys, TestFindKeyByAlgorithm, TestFindKeyByID) to initialize KeyIndexer with the new resolver and adjust mock expectations to include KAS URI filtering.
  • service/kas/static_kas_uri_resolver.go
    • Added a new file defining the StaticRegisteredKasURIResolver type.
    • Implemented the RegisteredKasURIResolver interface for this static resolver, providing ResolveURI(), String(), and LogValue() methods.
  • service/kas/static_kas_uri_resolver_test.go
    • Added comprehensive unit tests for the StaticRegisteredKasURIResolver to verify its initialization, URI resolution, string representation, and logging value.
  • service/pkg/server/options.go
    • Added a kasURIResolver field to the StartConfig struct.
    • Introduced WithRegisteredKasURIResolver as a new StartOptions function to allow external injection of a KAS URI resolver.
  • service/pkg/server/services.go
    • Updated startServicesParams to include the kasURIResolver.
    • Passed the kasURIResolver from startServicesParams to the serviceregistry.RegistrationParams during service startup.
  • service/pkg/server/start.go
    • Modified the Start function to propagate the kasURIResolver from the StartConfig to the startServicesParams.
  • service/pkg/serviceregistry/serviceregistry.go
    • Added a RegisteredKasURIResolver field to the RegistrationParams struct, making the resolver available to registered services.
  • service/trust/key_index.go
    • Defined the new RegisteredKasURIResolver interface, outlining the contract for KAS URI resolution.
Activity
  • The author c-r33d created this pull request to introduce a KAS URI resolver.
  • The changes involve refactoring the KAS service to use an injectable RegisteredKasURIResolver interface.
  • A default StaticRegisteredKasURIResolver implementation was added for backward compatibility.
  • The KeyIndexer was updated to dynamically resolve KAS URIs using this new interface.
  • Server startup options and service registration parameters were modified to support the injection of custom resolvers.
  • New unit tests were added for the static resolver, and existing tests for KeyIndexer were updated to reflect the new architecture.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.


A URI, once fixed, Now resolves with new intent, Flexibility.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@c-r33d c-r33d changed the title Add kas uri resolver feat(kas): Add kas uri resolver Feb 9, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a KAS URI resolver, which is a great step towards more dynamic service configuration. The changes are well-structured, introducing a RegisteredKasURIResolver interface and a default StaticRegisteredKasURIResolver implementation for backward compatibility. The necessary plumbing to inject the resolver from server start options down to the KAS service is correctly implemented. The KeyIndexer is refactored to use this resolver, and the tests are updated accordingly.

I have a few minor suggestions to improve code consistency and reduce duplication in tests, but overall, this is a solid contribution.

Comment on lines 189 to 198
mockClient := new(MockKeyAccessServerRegistryClient)
kasURI := testKasURI
resolver, err := NewStaticRegisteredKasURIResolver(kasURI)
s.Require().NoError(err)
keyIndexer := &KeyIndexer{
sdk: &sdk.SDK{
KeyAccessServerRegistry: mockClient,
},
resolver: resolver,
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

To improve maintainability and reduce code duplication, consider refactoring this common test setup logic into a helper method on the KeyIndexTestSuite. This block of code is repeated in TestListKeys, TestFindKeyByAlgorithm, and TestFindKeyByID.

A helper function could look like this:

func (s *KeyIndexTestSuite) newTestKeyIndexer(kasURI string) (*KeyIndexer, *MockKeyAccessServerRegistryClient) {
	mockClient := new(MockKeyAccessServerRegistryClient)
	resolver, err := NewStaticRegisteredKasURIResolver(kasURI)
	s.Require().NoError(err)
	keyIndexer := &KeyIndexer{
		sdk: &sdk.SDK{
			KeyAccessServerRegistry: mockClient,
		},
		resolver: resolver,
	}
	return keyIndexer, mockClient
}

Then, each test could simply call keyIndexer, mockClient := s.newTestKeyIndexer(testKasURI).

Comment on lines +32 to +34
if r.kasURI == "" {
return "", fmt.Errorf("registered KAS URI is empty")
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

For consistency, it would be better to return the package-level errKasURIEmpty here, which is also used in the NewStaticRegisteredKasURIResolver constructor when the URI is empty. This makes the error handling more uniform.

Suggested change
if r.kasURI == "" {
return "", fmt.Errorf("registered KAS URI is empty")
}
if r.kasURI == "" {
return "", errKasURIEmpty
}


resolver = &StaticRegisteredKasURIResolver{}
uri, err = resolver.ResolveURI()
require.Error(t, err)
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

To make this test more specific and robust, consider using require.ErrorIs to assert that the expected error errKasURIEmpty is returned. This is especially relevant given the suggestion to make the error returned from ResolveURI consistent.

Suggested change
require.Error(t, err)
require.ErrorIs(t, err, errKasURIEmpty)

@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 368.628777ms
Throughput 271.28 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 38.75311319s
Average Latency 386.033207ms
Throughput 129.02 requests/second

@c-r33d c-r33d requested review from a team as code owners February 9, 2026 16:02
@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2026

X-Test Failure Report

opentdfplatformKK8UQL.dockerbuild
cukes-report

@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 349.810116ms
Throughput 285.87 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 38.880264443s
Average Latency 387.054593ms
Throughput 128.60 requests/second

@github-actions
Copy link
Contributor

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 366.362767ms
Throughput 272.95 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 40.308858804s
Average Latency 400.587812ms
Throughput 124.04 requests/second

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

Labels

comp:kas Key Access Server size/m

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants