Skip to content

feat(policy): Add the ability to do substring search#3551

Draft
c-r33d wants to merge 10 commits into
mainfrom
search-term-impl
Draft

feat(policy): Add the ability to do substring search#3551
c-r33d wants to merge 10 commits into
mainfrom
search-term-impl

Conversation

@c-r33d
Copy link
Copy Markdown
Contributor

@c-r33d c-r33d commented May 29, 2026

General goal

Search for policy objects with a List req by specifying a Search term. The search term is simply that, a word or phrase. We do this by using the LIKE or ILIKE command depending on the specific RPC.

The following sanitization is done for each query:

  • Whitespace is removed from the beginning and end of the term
  • Characters that are used by LIKE\ILIKE such as % and _ are escaped before being queried.

Note

Currently there is no goal to optimize this strategy, this is to serve as a starting point. In the case optimizations are needed
we can look into adding GIN indexes and pg_trgm for better fuzziness matching.

Implementations

RPC Searchable fields
ListNamespaces Namespace FQN (attribute_fqns.fqn)
ListAttributes Attribute FQN (attribute_fqns.fqn)
ListKeyAccessServers KAS name (key_access_servers.name), KAS URI (key_access_servers.uri)
ListKeys Key ID (kas_keys.key_id)
ListObligations Obligation FQN (<namespace fqn>/obl/<obligation name>)
ListRegisteredResources Registered resource name (registered_resources.name)
ListSubjectMappings Attribute value FQN (attribute_fqns.fqn), metadata label values (metadata.labels.*)
ListSubjectConditionSets Metadata label values (metadata.labels.*)

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 29, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4a83fabc-e8cd-4964-8aef-88502906ff08

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch search-term-impl

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 and usage tips.

@github-actions github-actions Bot added comp:policy Policy Configuration ( attributes, subject mappings, resource mappings, kas registry) docs Documentation labels May 29, 2026
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, 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 standardized substring search mechanism across the policy service API. By adding a reusable Search message type to various List request objects, it enables clients to filter resources using a search term. The implementation includes necessary protocol buffer updates, documentation adjustments, and validation logic to ensure search terms are handled correctly.

Highlights

  • New Search Capability: Introduced a new Search message type in the policy selectors, allowing for substring-based searching with a defined term.
  • API Integration: Updated multiple List request messages across various policy services (Attributes, KeyAccessServers, Namespaces, Obligations, RegisteredResources, and SubjectMappings) to include the optional Search field.
  • Validation: Added strict validation for the search term length (max 253 characters) using buf.validate and included a corresponding Go unit test.
New Features

🧠 You can now enable Memory (public preview) 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.

Ignored Files
  • Ignored by pattern: docs/openapi/**/* (20)
    • docs/openapi/authorization/authorization.openapi.yaml
    • docs/openapi/authorization/v2/authorization.openapi.yaml
    • docs/openapi/common/common.openapi.yaml
    • docs/openapi/entity/entity.openapi.yaml
    • docs/openapi/entityresolution/entity_resolution.openapi.yaml
    • docs/openapi/entityresolution/v2/entity_resolution.openapi.yaml
    • docs/openapi/kas/kas.openapi.yaml
    • docs/openapi/policy/actions/actions.openapi.yaml
    • docs/openapi/policy/attributes/attributes.openapi.yaml
    • docs/openapi/policy/kasregistry/key_access_server_registry.openapi.yaml
    • docs/openapi/policy/keymanagement/key_management.openapi.yaml
    • docs/openapi/policy/namespaces/namespaces.openapi.yaml
    • docs/openapi/policy/objects.openapi.yaml
    • docs/openapi/policy/obligations/obligations.openapi.yaml
    • docs/openapi/policy/registeredresources/registered_resources.openapi.yaml
    • docs/openapi/policy/resourcemapping/resource_mapping.openapi.yaml
    • docs/openapi/policy/selectors.openapi.yaml
    • docs/openapi/policy/subjectmapping/subject_mapping.openapi.yaml
    • docs/openapi/policy/unsafe/unsafe.openapi.yaml
    • docs/openapi/wellknownconfiguration/wellknown_configuration.openapi.yaml
  • Ignored by pattern: protocol/**/* (7)
    • protocol/go/policy/attributes/attributes.pb.go
    • protocol/go/policy/kasregistry/key_access_server_registry.pb.go
    • protocol/go/policy/namespaces/namespaces.pb.go
    • protocol/go/policy/obligations/obligations.pb.go
    • protocol/go/policy/registeredresources/registered_resources.pb.go
    • protocol/go/policy/selectors.pb.go
    • protocol/go/policy/subjectmapping/subject_mapping.pb.go
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 the 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 counterproductive. 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.


A search term added to the list, To find the data that we missed. With LIKE or ILIKE in the base, We find the items in their place.

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.

Copy link
Copy Markdown
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 new Search message containing a term field and integrates it as an optional search parameter across multiple list request protobuf definitions in the policy service. It also includes updated documentation and a unit test for search term validation. The reviewer recommends enforcing a minimum length of 1 character on the search term to prevent inefficient database queries with empty strings, along with adding a corresponding test case to verify this validation.

}

message Search {
string term = 1 [(buf.validate.field).string.max_len = 253];
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.

medium

To prevent empty or whitespace-only search queries from being sent to the database (which can cause inefficient queries like LIKE '%%'), we should enforce a minimum length of 1 character for the search term when the Search message is provided.

Suggested change
string term = 1 [(buf.validate.field).string.max_len = 253];
string term = 1 [(buf.validate.field).string = {
min_len: 1
max_len: 253
}];

Comment on lines +12 to +25
func TestSearchTermValidation(t *testing.T) {
v, err := protovalidate.New()
require.NoError(t, err)

require.NoError(t, v.Validate(&policy.Search{
Term: strings.Repeat("a", 253),
}))

err = v.Validate(&policy.Search{
Term: strings.Repeat("a", 254),
})
require.Error(t, err)
require.Contains(t, err.Error(), "string.max_len")
}
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.

medium

Since we are adding a min_len: 1 constraint to the search term, we should also add a test case to verify that an empty search term fails validation.

Suggested change
func TestSearchTermValidation(t *testing.T) {
v, err := protovalidate.New()
require.NoError(t, err)
require.NoError(t, v.Validate(&policy.Search{
Term: strings.Repeat("a", 253),
}))
err = v.Validate(&policy.Search{
Term: strings.Repeat("a", 254),
})
require.Error(t, err)
require.Contains(t, err.Error(), "string.max_len")
}
func TestSearchTermValidation(t *testing.T) {
v, err := protovalidate.New()
require.NoError(t, err)
require.NoError(t, v.Validate(&policy.Search{
Term: strings.Repeat("a", 253),
}))
err = v.Validate(&policy.Search{
Term: strings.Repeat("a", 254),
})
require.Error(t, err)
require.Contains(t, err.Error(), "string.max_len")
err = v.Validate(&policy.Search{
Term: "",
})
require.Error(t, err)
require.Contains(t, err.Error(), "string.min_len")
}

@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 193.762597ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 436.257597ms
Throughput 229.22 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 44.183129069s
Average Latency 440.150866ms
Throughput 113.17 requests/second

### Proposed Changes

1.) Add substring searching to ListNamespaces, `fqn` field.
2.) Escape characters used by `LIKE\ILIKE` from incoming input
3.) Specify `\` as the escape character

### 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



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added search functionality to namespace listing with support for name
and FQN matching
  * Search is case-insensitive and supports prefix matching
  * Search integrates with namespace state filtering (ACTIVE/INACTIVE)
* Special wildcard characters are properly escaped to prevent unexpected
matches

* **Tests**
* Added comprehensive test coverage for search functionality,
pagination, and edge cases

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 345.389784ms
Throughput 289.53 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 33.995128928s
Average Latency 338.569152ms
Throughput 147.08 requests/second

## Summary
- Adds ListAttributes RPC search support by wiring request search into
the policy DB list query.
- Applies escaped, case-insensitive matching in the attributes SQL path
and adds integration coverage for search behavior, wildcard literals,
empty search, and pagination after filtering.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added search functionality for attributes, including filtering by
fully qualified name with wildcard escaping and combined namespace/state
filters.

* **Tests**
* Added comprehensive integration tests for attribute search operations,
including pagination and filter combinations.

* **Chores**
  * Updated sqlc tool to version 1.31.1.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Chris Reed <creed@virtru.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 411.721055ms
Throughput 242.88 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 43.221880474s
Average Latency 429.755265ms
Throughput 115.68 requests/second

c-r33d added 2 commits June 2, 2026 10:31
## Summary
- Adds ListRegisteredResources RPC search support by wiring request
search into the policy DB list query.
- Applies escaped, case-insensitive matching in the registered resources
SQL path and adds integration coverage for search behavior, wildcard
literals, namespace filters, empty/whitespace search, and pagination
after filtering.

---------

Signed-off-by: Chris Reed <creed@virtru.com>
## Summary
- Adds ListKeyAccessServers RPC search support by wiring request search
into the policy DB list query.
- Applies escaped, case-insensitive matching in the KAS registry SQL
path and adds integration coverage for search behavior, wildcard
literals, empty search, and pagination after filtering.

---------

Signed-off-by: Chris Reed <creed@virtru.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

X-Test Failure Report

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 351.017662ms
Throughput 284.89 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 33.582497649s
Average Latency 334.238148ms
Throughput 148.89 requests/second

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 696.517827ms
Throughput 143.57 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 43.558439679s
Average Latency 433.163115ms
Throughput 114.79 requests/second

## Summary
- Adds ListObligations RPC search support by wiring request search into
the policy DB list query.
- Applies escaped, case-insensitive matching in the obligations SQL path
and adds integration coverage for search behavior, wildcard literals,
empty search, and pagination after filtering.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added search capability to obligation listings, supporting search by
name and fully qualified name with case-insensitive matching.
  * Search integrates seamlessly with namespace filters and pagination.

* **Tests**
* Added comprehensive integration tests for search functionality,
including combined filtering, whitespace handling, and pagination
behavior.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Chris Reed <creed@virtru.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 471.79831ms
Throughput 211.95 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 45.129210758s
Average Latency 449.703704ms
Throughput 110.79 requests/second

## Summary
- Adds ListSubjectConditionSets RPC search support by wiring request
search into the policy DB list query.
- Applies escaped, case-insensitive matching in the subject condition
set SQL path and adds integration coverage for search behavior, wildcard
literals, empty search, and pagination after filtering.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added search functionality for subject condition sets filtered by
metadata labels.
* Search supports pagination, sorting, and combines with namespace
filtering.
  * Search properly handles whitespace and special character escaping.

* **Tests**
* Expanded integration test coverage for search behavior with metadata
labels.
  * Updated existing sorting tests with improved cleanup utilities.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Chris Reed <creed@virtru.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 3, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 448.027521ms
Throughput 223.20 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 45.529077403s
Average Latency 453.865093ms
Throughput 109.82 requests/second

## Summary
- Adds ListSubjectMappings RPC search support by wiring request search
into the policy DB list query.
- Applies escaped, case-insensitive matching in the subject mappings SQL
path and adds integration coverage for search behavior, wildcard
literals, empty search, and pagination after filtering.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Subject mappings now support search filtering by attribute values and
metadata labels
* Search results can be combined with namespace filters for refined
queries
* Automatic whitespace trimming and special character handling ensure
accurate searches
  * Result pagination works correctly with all filters applied

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Chris Reed <creed@virtru.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 3, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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.747948ms
Throughput 226.89 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 44.533754526s
Average Latency 443.74433ms
Throughput 112.27 requests/second

## Summary
- Adds ListKeys RPC search support by wiring request search into the
policy DB list query.
- Applies escaped, case-insensitive matching in the KAS key SQL path and
adds integration coverage for search behavior, wildcard literals, empty
search, whitespace handling, and pagination after filtering.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

* **New Features**
  * Search capability for KAS registry keys by key ID.
  * Search input automatically trims leading and trailing whitespace.
  * Wildcard characters in search queries are properly escaped.
  * Search results work seamlessly with existing filters and pagination.

* **Tests**
  * Added comprehensive test coverage for search functionality.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Chris Reed <creed@virtru.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 3, 2026

⚠️ Govulncheck found vulnerabilities ⚠️

The following modules have known vulnerabilities:

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

See the workflow run for details.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 3, 2026

Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 441.708301ms
Throughput 226.39 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 46.121442304s
Average Latency 459.492499ms
Throughput 108.41 requests/second

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

Labels

comp:policy Policy Configuration ( attributes, subject mappings, resource mappings, kas registry) docs Documentation size/s

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant