Skip to content

feat(sdk): IsHealthy(ctx) public reachability probe#3412

Merged
marythought merged 7 commits into
mainfrom
DSPX-3008-sdk-healthcheck
Apr 29, 2026
Merged

feat(sdk): IsHealthy(ctx) public reachability probe#3412
marythought merged 7 commits into
mainfrom
DSPX-3008-sdk-healthcheck

Conversation

@marythought

@marythought marythought commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a public SDK.IsHealthy(ctx) (bool, error) method so downstream services (data-harbor and others) can run readiness probes through the SDK instead of open-coding http.Client.Get(healthzEndpoint) — which has no context propagation, bleeds timeout configuration into unrelated RPCs, and bypasses OTEL/auth/audit interceptors.

Background

Takeover of #3379 by @pflynn-virtru. Paul's original 5 commits are preserved on this branch (feat(sdk): add HealthStatus typerefactor(sdk): use url.JoinPath); a final refactor(sdk): simplify HealthCheck to IsHealthy(ctx) per review commit collapses the API per @strantalis' review feedback.

What changed from #3379

Before (#3379) After (this PR)
HealthCheck(ctx, service string) (HealthStatus, error) IsHealthy(ctx) (bool, error)
3 exported HealthStatus* constants + String() method (removed — idiomatic (bool, error) predicate)
service arg with "" / "all" / per-service semantics (removed — always uses "" reachability probe)

Retained:

  • ErrHealthCheckUnsupported for IPC mode (distinct from ErrPlatformUnreachable)
  • The url.JoinPath fix (gemini-code-assist suggestion, applied in feat(sdk): HealthCheck(ctx, service) #3379)
  • All ctx / OTEL / interceptor behavior

Behavior

  • (true, nil) — platform reports SERVING
  • (false, nil) — reachable but NOT_SERVING / UNKNOWN
  • (false, ErrHealthCheckUnsupported) — SDK is in IPC mode
  • (false, err) wrapping ErrPlatformUnreachable — transport / ctx errors

Honors ctx for deadline, cancellation, and OTEL trace-context propagation. OTEL works automatically when otelconnect.NewInterceptor is registered via WithExtraClientOptions at SDK construction.

Test plan

  • go test ./sdk/... — all pass
  • golangci-lint run — clean on changed files (sdk/sdk.go, sdk/sdk_test.go, sdk/options.go)
  • go test -run TestREADMECodeBlocks — pass
  • All commits DCO + SSH signed

Tests cover: IPC mode, unreachable platform, pre-canceled ctx, SERVING happy path, NOT_SERVING, trailing-slash endpoint regression.

Replaces

Replaces #3379. Will close that PR once this one is approved.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added the ability to check platform reachability at runtime, with support for context deadlines and cancellation to enable flexible health verification.
  • Documentation

    • Updated connection validation documentation to clarify construction-time validation and direct users to the new runtime health check capability for ongoing reachability monitoring.

pflynn-virtru and others added 6 commits April 29, 2026 09:26
Introduces the typed status and distinct IPC-mode error that the upcoming
public SDK.HealthCheck(ctx, service) method will return. No behavior change yet.

Signed-off-by: Paul Flynn <pflynn-virtru@users.noreply.github.com>
Splits the gRPC Health Check call out of validateHealthyPlatformConnection
so it can be reused by the upcoming public SDK.HealthCheck method. The
construction-time gate still uses context.Background() and still returns
ErrPlatformUnreachable on any non-SERVING or transport error.

Signed-off-by: Paul Flynn <pflynn-virtru@users.noreply.github.com>
Adds SDK.HealthCheck, returning a typed HealthStatus and an error that
wraps ErrPlatformUnreachable on transport failures or ErrHealthCheckUnsupported
in IPC mode. The method uses SDK.Conn().Options so caller-injected Connect
interceptors (OTEL, auth, audit) apply automatically. Ctx controls timeout,
cancellation, and trace-context propagation.

Tests cover IPC mode, unreachable endpoint, pre-canceled context, and the
happy path against a grpchealth StaticChecker served by httptest.

Signed-off-by: Paul Flynn <pflynn-virtru@users.noreply.github.com>
Signed-off-by: Paul Flynn <pflynn-virtru@users.noreply.github.com>
String concatenation produced a double slash when the caller supplied an
endpoint with a trailing slash (e.g. https://platform.example.com/).
Strict HTTP routers can reject //grpc.health.v1.Health/Check even though
most normalize it. url.JoinPath cleans separators and is stdlib.

Fixes a latent issue in the pre-existing validateHealthyPlatformConnection
too, since both construction-time and runtime paths now share the helper.

Adds TestSDK_HealthCheck_TrailingSlashEndpoint as a regression guard.

Signed-off-by: Paul Flynn <pflynn-virtru@users.noreply.github.com>
Per @strantalis review on #3379: drop the service param and HealthStatus
enum in favor of an idiomatic Go predicate (bool, error). The empty-service
reachability probe is the 95% use case; callers needing per-service or
NOT_SERVING vs UNKNOWN distinction can call gRPC Health v1 directly.

- Remove HealthStatus type/constants and String() method
- Rename HealthCheck(ctx, service) -> IsHealthy(ctx) (bool, error)
- Drop service param from checkPlatformHealth helper (always "")
- Update tests to (bool, error) shape

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Mary Dickson <mary.dickson@virtru.com>
@marythought
marythought requested review from a team as code owners April 29, 2026 16:58
@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 adds a standardized, context-aware health check mechanism to the SDK. By providing a public IsHealthy method, it enables downstream services to perform readiness probes that respect the SDK's configuration, including timeout settings, OTEL tracing, and authentication interceptors, replacing manual HTTP calls that bypassed these critical components.

Highlights

  • New Public Health Probe: Introduced a public SDK.IsHealthy(ctx) (bool, error) method to allow downstream services to perform readiness checks through the SDK, ensuring proper context propagation and interceptor usage.
  • Improved API Design: Simplified the health check API to return a boolean and error, replacing the previous complex HealthStatus type and service-specific arguments.
  • Robustness and Observability: The new method honors context deadlines and cancellation, and automatically supports OTEL tracing when configured.

🧠 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.

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.


A probe to check if all is well, With context sent to break the spell. No more manual calls to make, Just healthy checks for safety's sake.

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.

@coderabbitai

coderabbitai Bot commented Apr 29, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@marythought has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 32 minutes and 57 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: cb84f808-f5b1-4e0a-b73c-bc915923a32f

📥 Commits

Reviewing files that changed from the base of the PR and between 42ac40b and 58d6c1b.

📒 Files selected for processing (1)
  • sdk/sdk_test.go
📝 Walkthrough

Walkthrough

This pull request adds a new runtime health check API (SDK.IsHealthy(ctx)) to validate platform reachability via gRPC Health v1, refactors construction-time validation logic, introduces the connectrpc.com/grpchealth dependency, and provides comprehensive test coverage for the new functionality.

Changes

Cohort / File(s) Summary
Dependency Addition
sdk/go.mod
Added connectrpc.com/grpchealth v1.4.0 as a direct dependency to support gRPC Health v1 protocol integration.
Documentation Update
sdk/options.go
Expanded WithConnectionValidation doc comment to clarify that validation occurs at SDK construction time and reference the new SDK.IsHealthy(ctx) method for runtime readiness checks.
Health Check API
sdk/sdk.go
Introduced public IsHealthy(ctx) method for runtime health probing via gRPC Health v1. Refactored health check logic into checkPlatformHealth helper, added ErrHealthCheckUnsupported error constant, and updated validateHealthyPlatformConnection to delegate to the new helper. Context propagation enables deadline/cancellation at runtime.
Test Coverage
sdk/sdk_test.go
Added 176 lines of new unit tests covering success/failure scenarios for IsHealthy, including IPC mode unsupported errors, unreachable platform endpoints, pre-canceled contexts, Health Check serving status validation, and regression test for trailing slash handling.

Sequence Diagram

sequenceDiagram
    participant App as Application
    participant SDK as SDK
    participant HC as Health Check Service
    participant Ctx as Context

    App->>SDK: IsHealthy(ctx)
    Note over SDK: Check if IPC mode<br/>(conn == nil)
    alt IPC Mode
        SDK-->>App: (false, ErrHealthCheckUnsupported)
    else Network Mode
        SDK->>SDK: Construct health endpoint<br/>via url.JoinPath
        Note over Ctx: Context carries<br/>deadline & cancellation
        SDK->>HC: gRPC Health v1 Check<br/>(with ctx)
        alt Success
            HC-->>SDK: Status = SERVING
            SDK-->>App: (true, nil)
        else Non-Serving or Error
            HC-->>SDK: Status ≠ SERVING<br/>or error
            SDK-->>App: (false, ErrPlatformUnreachable)
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 A health check hops through the network wide,
Context in paw, no need to hide,
Is the platform serving or just shy?
The SDK asks with a watchful eye,
Runtime readiness—now we comply! ✨

🚥 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 accurately describes the main change: adding a new public IsHealthy(ctx) method for SDK reachability probing, which is the primary feature in this pull request.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch DSPX-3008-sdk-healthcheck

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
Review rate limit: 0/1 reviews remaining, refill in 32 minutes and 57 seconds.

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

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

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces a new IsHealthy method to the SDK to support runtime readiness probes via the gRPC Health v1 protocol. The implementation includes adding the grpchealth dependency, refactoring internal health check logic to use url.JoinPath for safer URL construction, and adding comprehensive unit tests. A review comment suggests refining the error returned when a platform is reachable but not in a serving state to improve debuggability for SDK users.

Comment thread sdk/sdk.go
@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 206.527477ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 404.012943ms
Throughput 247.52 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 44.931872231s
Average Latency 447.755206ms
Throughput 111.28 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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@sdk/sdk_test.go`:
- Around line 442-464: Add a new unit test mirroring
TestSDK_IsHealthy_NotServing called e.g. TestSDK_IsHealthy_Unknown that uses the
same pattern (create server via newHealthTestServer to return an UNKNOWN health
status, construct the SDK with sdk.New and sdk.WithPlatformConfiguration, call
s.IsHealthy(ctx)) and assert that error is nil and the returned healthy value is
false; ensure you use the same helper names (newHealthTestServer, s.IsHealthy)
and the same context/timeout pattern so the test locks the contract UNKNOWN ->
(false, nil).

In `@sdk/sdk.go`:
- Around line 467-469: The health check uses context.Background() with no
deadline which can block SDK construction; modify
validateHealthyPlatformConnection to create a bounded context (e.g., ctx, cancel
:= context.WithTimeout(context.Background(), 5*time.Second)) and pass that ctx
to checkPlatformHealth, and ensure you call defer cancel() to release resources;
optionally extract the timeout into a constant like platformHealthTimeout for
clarity and reuse.
🪄 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

Run ID: 1a8ddbc0-b067-4936-aa66-80e73c08a0b3

📥 Commits

Reviewing files that changed from the base of the PR and between 14e7a25 and 42ac40b.

⛔ Files ignored due to path filters (1)
  • sdk/go.sum is excluded by !**/*.sum
📒 Files selected for processing (4)
  • sdk/go.mod
  • sdk/options.go
  • sdk/sdk.go
  • sdk/sdk_test.go

Comment thread sdk/sdk_test.go
Comment thread sdk/sdk.go
@github-actions

Copy link
Copy Markdown
Contributor

Locks the documented contract that UNKNOWN -> (false, nil), distinguishing
it from transport errors which wrap ErrPlatformUnreachable. Refactors
newHealthTestServer to take a grpchealth.Status directly so any of the
three statuses can be exercised.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Mary Dickson <mary.dickson@virtru.com>
@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.108331ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

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

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 397.600842ms
Throughput 251.51 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 42.587529044s
Average Latency 424.242445ms
Throughput 117.41 requests/second

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Govulncheck found vulnerabilities ⚠️

The following modules have known vulnerabilities:

  • tests-bdd

See the workflow run for details.

@github-actions

Copy link
Copy Markdown
Contributor

@marythought
marythought enabled auto-merge April 29, 2026 17:43
@marythought
marythought added this pull request to the merge queue Apr 29, 2026
Merged via the queue into main with commit 3e2cf98 Apr 29, 2026
39 checks passed
@marythought
marythought deleted the DSPX-3008-sdk-healthcheck branch April 29, 2026 18:05
marythought added a commit to opentdf/docs that referenced this pull request Apr 30, 2026
Add a Health checks section to platform-client.mdx covering the new
IsHealthy(ctx) method shipped in opentdf/platform sdk v0.18.0
(opentdf/platform#3412). Documents the (bool, error) contract,
SERVING/NOT_SERVING/UNKNOWN behavior, and the IPC mode and transport
error sentinels.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
marythought added a commit to opentdf/docs that referenced this pull request Apr 30, 2026
#311)

## Summary

Two related changes in one PR:

### 1. Document `SDK.IsHealthy(ctx)` reachability probe

Adds a **Health checks** section to `docs/sdks/platform-client.mdx`
covering the new `SDK.IsHealthy(ctx) (bool, error)` method shipped in
opentdf/platform sdk v0.18.0 (opentdf/platform#3412).

The section documents:

- The `(bool, error)` contract and when to reach for it (readiness
probes, smoke tests, startup gating)
- `SERVING` / `NOT_SERVING` / `UNKNOWN` return semantics
- IPC mode (`ErrHealthCheckUnsupported`) and transport failure
(`ErrPlatformUnreachable`) sentinels
- Context propagation and OTEL tracing behavior

Go-only — IsHealthy is a server-side readiness concern and is not
planned for the web SDK.

### 2. Link unresolved type references in SDK reference tables

Several PascalCase type cells in SDK reference tables were rendering as
plain text instead of links to their definitions, forcing readers to
scroll or grep to learn the type's shape.

**`authorization.mdx`**
- Link `Action` cells to `/sdks/policy#action`
- Add `### GetDecisionMultiResourceRequest` heading so its parameter
cell resolves to a real anchor

**`tdf.mdx`**
- Add `RequiredObligations` to the Type Reference and link the
`TriggeredObligations` cell
- Promote Manifest sub-tables (`EncryptionInformation`, `KeyAccess`,
`Payload`) to H4 subheadings; disambiguate Payload with
`{#manifest-payload}` since the TDF Reader method already owns
`#payload`
- Fully link the `Assertion` fields table (`AssertionType`, `Scope`,
`AppliesToState`, `Statement`, `Binding`) and add a `Binding` type-ref
entry
- Link `AssertionKey` in `AssertionVerificationKeys.DefaultKey`

**`policy.mdx`**
- Link `SubjectSet` in `UpdateSubjectConditionSet` parameters
- Link `SubjectProperty` in `MatchSubjectMappings` parameters

## Test plan

- [x] `npm run build` passes — no new broken anchors introduced
- [x] `vale docs/sdks/platform-client.mdx` clean
- [ ] Surge preview renders the new section and link targets correctly
- [ ] Verify the `SdkVersion` badge shows `0.18.0` for Go

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

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

## Summary by CodeRabbit

* **Documentation**
* Enhanced SDK documentation with improved cross-references and internal
links for better navigation across authorization, policy, and TDF
sections
* Added new documentation sections for platform health-check
capabilities and API request/response types
* Updated type references with proper linking throughout the
documentation

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
JBCongdon pushed a commit to JBCongdon/platform that referenced this pull request May 24, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.18.0](opentdf/platform@sdk/v0.17.0...sdk/v0.18.0)
(2026-04-29)


### Features

* **sdk:** IsHealthy(ctx) public reachability probe
([opentdf#3412](opentdf#3412))
([3e2cf98](opentdf@3e2cf98))


### Bug Fixes

* **deps:** bump github.com/opentdf/platform/protocol/go from 0.27.0 to
0.28.0 in /sdk
([opentdf#3415](opentdf#3415))
([701bd9f](opentdf@701bd9f))
* **deps:** bump go.opentelemetry.io/otel from 1.40.0 to 1.41.0 in /sdk
([opentdf#3399](opentdf#3399))
([d98418b](opentdf@d98418b))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: opentdf-automation[bot] <149537512+opentdf-automation[bot]@users.noreply.github.com>
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/s

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants