Skip to content

feat(sdk): DSPX-2418 add attribute discovery methods#3082

Open
marythought wants to merge 3 commits intomainfrom
feat/dspx-2418-discovery-methods
Open

feat(sdk): DSPX-2418 add attribute discovery methods#3082
marythought wants to merge 3 commits intomainfrom
feat/dspx-2418-discovery-methods

Conversation

@marythought
Copy link
Contributor

@marythought marythought commented Feb 17, 2026

Summary

Adds five convenience discovery methods to the Go SDK's SDK struct, addressing GitHub Discussions #947 and #1204 where developers had no ergonomic way to discover attributes or validate them before encryption.

  • ListAttributes(ctx, namespace...) — returns all active attributes, auto-paginates
  • ValidateAttributes(ctx, fqns) — fail-fast batch check that value FQNs exist before CreateTDF; returns ErrAttributeNotFound naming which FQNs are missing
  • ValidateAttributeExists(ctx, fqn) — single-FQN wrapper around ValidateAttributes
  • ValidateAttributeValue(ctx, attributeFqn, value) — checks that a value string is permitted for an attribute, handling both enumerated attributes (value must be in the registered list, case-insensitive) and dynamic attributes (any value accepted); addresses #2930
  • GetEntityAttributes(ctx, entity) — returns attribute FQNs assigned to a PE/NPE via GetEntitlements
  • Adds ErrAttributeNotFound sentinel to sdk.go

Security hardening applied during implementation

  • Pagination loop in ListAttributes capped at 1000 pages to prevent unbounded memory growth from a misbehaving server
  • ValidateAttributes enforces the server's 250-FQN limit client-side for a clear local error
  • GetEntityAttributes matches response entitlements against the requested entity ID rather than blindly returning index 0

Checklist

Testing Instructions

  • 21 unit tests in sdk/discovery_test.go covering all methods, edge cases (empty input, pagination overflow, ID mismatch, service errors, invalid FQN format)
  • go test ./sdk/... passes (pre-existing auth/oauth failure is unrelated)
  • golangci-lint run ./sdk/... — no new issues introduced
  • Docs updated in companion PR against opentdf/docs

@marythought marythought requested review from a team as code owners February 17, 2026 21:00
@github-actions github-actions bot added the comp:sdk A software development kit, including library, for client applications and inter-service communicati label Feb 17, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @marythought, 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 significantly enhances the Go SDK by providing a set of new methods for attribute discovery and validation. These additions aim to streamline the developer workflow by offering ergonomic ways to interact with attributes, ensuring their existence and proper assignment before critical operations like TDF creation. The changes improve the SDK's robustness and developer experience by preventing common pitfalls related to attribute management.

Highlights

  • Attribute Discovery Methods: Added four convenience discovery methods to the Go SDK's SDK struct, addressing issues where developers lacked ergonomic ways to discover or validate attributes before encryption.
  • ListAttributes Function: Introduced ListAttributes(ctx, namespace...) to return all active attributes, with automatic pagination and an optional namespace filter.
  • Attribute Validation: Implemented ValidateAttributes(ctx, fqns) for fail-fast checking that attribute FQNs exist, returning ErrAttributeNotFound for missing FQNs, and ValidateAttributeValue(ctx, fqn) as a single-FQN wrapper.
  • Entity Attribute Retrieval: Added GetEntityAttributes(ctx, entity) to retrieve attribute FQNs assigned to a given entity (PE/NPE) via GetEntitlements.
  • New Error Type: Added ErrAttributeNotFound sentinel error to sdk.go for clearer error handling.

🧠 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
  • sdk/discovery.go
    • Added ListAttributes function to retrieve all active attributes with pagination.
    • Added ValidateAttributes function to check for the existence of multiple attribute FQNs.
    • Added GetEntityAttributes function to fetch attributes assigned to an entity.
    • Added ValidateAttributeValue function as a wrapper for single attribute FQN validation.
    • Defined maxListAttributesPages and maxValidateFQNs constants for safety limits.
  • sdk/discovery_test.go
    • Added comprehensive unit tests for ListAttributes, covering empty results, single/multi-page responses, namespace filtering, page limit exceeding, and service errors.
    • Added comprehensive unit tests for ValidateAttributes, covering empty input, all found, some missing, all missing, too many FQNs, invalid FQN format, and service errors.
    • Added comprehensive unit tests for GetEntityAttributes, covering nil entity, found entitlements, no entitlements, ID mismatch, and service errors.
    • Added comprehensive unit tests for ValidateAttributeValue, covering valid/existing, valid/missing, and invalid format.
    • Introduced mock clients (mockDiscoveryAttributesClient, mockDiscoveryAuthzClient) and helper functions (newDiscoverySDK, makeAttr, fqnMap) for testing.
  • sdk/sdk.go
    • Added ErrAttributeNotFound sentinel error.
Activity
  • Added 21 new unit tests in sdk/discovery_test.go covering all new methods and edge cases.
  • Confirmed go test ./sdk/... passes.
  • Confirmed golangci-lint run ./sdk/... introduces no new issues.
  • Updated documentation in a companion pull request against opentdf/docs.
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.


Attributes now found, SDK guides the true path, Data flows secure.

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
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 several useful attribute discovery methods to the Go SDK, which will improve the developer experience for discovering and validating attributes. The implementation is well-structured and includes comprehensive unit tests. I've identified one high-severity issue in GetEntityAttributes that could lead to incorrect data being returned, and a medium-severity suggestion to improve performance in ListAttributes.

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

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 361.121093ms
Throughput 276.92 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 39.150052759s
Average Latency 390.119879ms
Throughput 127.71 requests/second

Prefer nil over []string{} as the zero value for a slice return
when no entitlements match the requested entity ID.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Mary Dickson <mary.dickson@virtru.com>
@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 161.384817ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 362.795749ms
Throughput 275.64 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 39.05372406s
Average Latency 388.400342ms
Throughput 128.03 requests/second

- Pre-allocate the result slice in ListAttributes using PageResponse.Total
  on the first page, reducing allocations when paginating large lists.
- Remove the entityID == "" short-circuit in GetEntityAttributes that
  caused the first entitlement in the response to be returned regardless
  of its entity ID when the caller passed an entity with no ID.
- Add TestGetEntityAttributes_EmptyEntityID to cover the fixed case.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Mary Dickson <mary.dickson@virtru.com>
@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 190.180451ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 367.43287ms
Throughput 272.16 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 41.46831481s
Average Latency 413.071717ms
Throughput 120.57 requests/second

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/m

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments