Skip to content

feat(sdk/go): complete Go SDK with domain clients, auth, and hardening (Drop B) - #19

Closed
rhuss wants to merge 1 commit into
mainfrom
go-sdk-b-complete
Closed

feat(sdk/go): complete Go SDK with domain clients, auth, and hardening (Drop B)#19
rhuss wants to merge 1 commit into
mainfrom
go-sdk-b-complete

Conversation

@rhuss

@rhuss rhuss commented Aug 10, 2026

Copy link
Copy Markdown
Owner

Summary

Complete the Go SDK contribution (Drop B) building on the foundation from Drop A (PR NVIDIA#2271):

  • 13 domain clients: config, exec, file, health, inference, policy, profile, provider, refresh, service, ssh, tcp, workspace
  • Authentication: OIDC package (auth code, device code, browser, client credentials flows) and gateway token management
  • Edge connectivity: Cloudflare tunnel and WebSocket proxy
  • Test infrastructure: fake client implementations with validation parity for all 14 domains
  • Proto extensions: inference and options proto definitions with generated Go bindings
  • Hardening: watch goroutine race fix, TLS config conflict detection, WaitReady helper extraction, deep-copy credential tests
  • API cleanup: removed unused option structs and config fields (YAGNI)
  • Documentation: API reference pages (18 pages), getting started guide, architecture overview, error handling, and testing guides

All changes target sdk/go/. CI integration follows in a subsequent PR.

Ref NVIDIA#2044

Reviewer Verification Checklist

  1. Build: cd sdk/go && mise run ci passes (lint + build + test + docs:check)
  2. Module path: grep -r 'rhuss/openshell-sdk-go' sdk/go/ returns zero matches
  3. File count: git diff --stat | tail -1 shows 212 files changed
  4. Drop A fixes present:
    • context_errors.go exists (renamed from grpc_errors.go)
    • Watch implementation has done-check before error delivery
    • conn.go rejects TLS params with plaintext address
    • sandbox_client.go has checkTerminalPhase helper
  5. YAGNI removed: No GetOptions, DeleteOptions, UpdateOptions, RetryPolicy structs; CreateOptions kept (actively used with Annotations field)
  6. Proto isolation: No proto types in public API signatures (only in internal/converter/)
  7. License headers: All .go files have SPDX Apache-2.0 headers; config files have upstream SPDX headers

Test plan

  • mise run ci passes: lint (0 issues), build, test (all packages), proto:check, docs:check
  • Zero downstream module path references (grep -r 'rhuss/openshell-sdk-go' sdk/go/ returns empty)
  • All 14 domain client files present
  • All 6 Drop A follow-up fixes verified present
  • YAGNI removals applied, build passes after removals
  • No excluded files (dev tooling, downstream-only, deferred content) in diff
  • Upstream pre-commit hooks pass (license check, markdown lint, Rust lint)

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 278 files, which is 178 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5f244ac9-4c46-4931-baa4-4a666e782d48

📥 Commits

Reviewing files that changed from the base of the PR and between 5bb930a and 61f9432.

⛔ Files ignored due to path filters (7)
  • Cargo.lock is excluded by !**/*.lock
  • mise.lock is excluded by !**/*.lock
  • sdk/go/go.sum is excluded by !**/*.sum
  • sdk/go/proto/inferencev1/inference.pb.go is excluded by !**/*.pb.go
  • sdk/go/proto/inferencev1/inference_grpc.pb.go is excluded by !**/*.pb.go
  • sdk/go/proto/openshellv1/openshell.pb.go is excluded by !**/*.pb.go
  • sdk/go/proto/sandboxv1/sandbox.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (278)
  • .agents/skills/debug-inference/SKILL.md
  • .agents/skills/debug-openshell-cluster/SKILL.md
  • .agents/skills/generate-sandbox-policy/SKILL.md
  • .agents/skills/launch-openshell-gator/SKILL.md
  • .agents/skills/openshell-cli/SKILL.md
  • .agents/skills/test-release-canary/SKILL.md
  • .github/workflows/release-canary.yml
  • README.md
  • architecture/build.md
  • architecture/gateway.md
  • architecture/sandbox.md
  • architecture/security-policy.md
  • crates/openshell-core/Cargo.toml
  • crates/openshell-core/src/endpoint_path.rs
  • crates/openshell-core/src/grpc_client.rs
  • crates/openshell-core/src/host_pattern.rs
  • crates/openshell-core/src/lib.rs
  • crates/openshell-core/src/middleware.rs
  • crates/openshell-core/src/provider_credentials.rs
  • crates/openshell-core/src/secrets.rs
  • crates/openshell-gateway-interceptors/src/plan.rs
  • crates/openshell-policy/src/ambiguity.rs
  • crates/openshell-policy/src/lib.rs
  • crates/openshell-providers/src/profiles.rs
  • crates/openshell-sandbox/src/lib.rs
  • crates/openshell-server/src/grpc/policy.rs
  • crates/openshell-server/src/grpc/provider.rs
  • crates/openshell-server/src/grpc/sandbox.rs
  • crates/openshell-server/src/provider_profile_sources.rs
  • crates/openshell-supervisor-middleware-builtins/Cargo.toml
  • crates/openshell-supervisor-middleware-builtins/src/lib.rs
  • crates/openshell-supervisor-middleware-builtins/src/regex.rs
  • crates/openshell-supervisor-middleware/src/headers.rs
  • crates/openshell-supervisor-middleware/src/lib.rs
  • crates/openshell-supervisor-middleware/src/remote.rs
  • crates/openshell-supervisor-network/src/l7/graphql.rs
  • crates/openshell-supervisor-network/src/l7/mod.rs
  • crates/openshell-supervisor-network/src/l7/path.rs
  • crates/openshell-supervisor-network/src/l7/relay.rs
  • crates/openshell-supervisor-network/src/l7/rest.rs
  • crates/openshell-supervisor-network/src/l7/websocket.rs
  • crates/openshell-supervisor-network/src/policy_local.rs
  • crates/openshell-supervisor-network/src/proxy.rs
  • crates/openshell-supervisor-network/src/proxy/relay.rs
  • crates/openshell-supervisor-network/src/proxy/tests/compatibility.rs
  • deploy/helm/openshell/README.md
  • deploy/helm/openshell/templates/_gateway-workload.tpl
  • deploy/helm/openshell/tests/gateway_config_test.yaml
  • deploy/helm/openshell/values.yaml
  • docs/kubernetes/setup.mdx
  • docs/providers/aws-sigv4.mdx
  • docs/reference/policy-schema.mdx
  • docs/sandboxes/manage-providers.mdx
  • docs/sandboxes/policies.mdx
  • docs/sandboxes/providers-v2.mdx
  • e2e/python/test_sandbox_policy.py
  • e2e/python/test_sandbox_providers.py
  • e2e/rust/e2e-openshift.sh
  • e2e/rust/tests/host_gateway_alias.rs
  • e2e/rust/tests/proxy_egress_pipeline.rs
  • e2e/rust/tests/websocket_conformance.rs
  • e2e/support/gateway-common.sh
  • e2e/with-kube-gateway.sh
  • proto/openshell.proto
  • proto/sandbox.proto
  • scripts/agents/gator/agent.yaml
  • scripts/agents/gator/bin/gh
  • scripts/agents/gator/bin/gh_guard_test.sh
  • scripts/agents/gator/bin/review_feedback_ledger_test.sh
  • scripts/agents/gator/prompts/gator.md
  • scripts/agents/gator/skills/gator-gate/SKILL.md
  • sdk/go/.golangci.yml
  • sdk/go/README.md
  • sdk/go/buf.gen.yaml
  • sdk/go/docs/book.toml
  • sdk/go/docs/src/SUMMARY.md
  • sdk/go/docs/src/api/client.md
  • sdk/go/docs/src/api/config.md
  • sdk/go/docs/src/api/edge.md
  • sdk/go/docs/src/api/exec.md
  • sdk/go/docs/src/api/fake.md
  • sdk/go/docs/src/api/files.md
  • sdk/go/docs/src/api/gateway.md
  • sdk/go/docs/src/api/health.md
  • sdk/go/docs/src/api/oidc.md
  • sdk/go/docs/src/api/overview.md
  • sdk/go/docs/src/api/policy.md
  • sdk/go/docs/src/api/profiles.md
  • sdk/go/docs/src/api/providers.md
  • sdk/go/docs/src/api/refresh.md
  • sdk/go/docs/src/api/sandboxes.md
  • sdk/go/docs/src/api/services.md
  • sdk/go/docs/src/api/ssh.md
  • sdk/go/docs/src/api/tcp.md
  • sdk/go/docs/src/architecture.md
  • sdk/go/docs/src/error-handling.md
  • sdk/go/docs/src/getting-started.md
  • sdk/go/docs/src/introduction.md
  • sdk/go/docs/src/testing.md
  • sdk/go/docs/theme/custom.css
  • sdk/go/go.mod
  • sdk/go/mise.toml
  • sdk/go/openshell/v1/auth_refresh.go
  • sdk/go/openshell/v1/auth_refresh_test.go
  • sdk/go/openshell/v1/client.go
  • sdk/go/openshell/v1/client_test.go
  • sdk/go/openshell/v1/config.go
  • sdk/go/openshell/v1/config_client.go
  • sdk/go/openshell/v1/config_client_test.go
  • sdk/go/openshell/v1/context_errors.go
  • sdk/go/openshell/v1/context_errors_test.go
  • sdk/go/openshell/v1/doc.go
  • sdk/go/openshell/v1/edge/cloudflare.go
  • sdk/go/openshell/v1/edge/cloudflare_test.go
  • sdk/go/openshell/v1/edge/doc.go
  • sdk/go/openshell/v1/edge/tunnel.go
  • sdk/go/openshell/v1/edge/tunnel_test.go
  • sdk/go/openshell/v1/errors.go
  • sdk/go/openshell/v1/errors_test.go
  • sdk/go/openshell/v1/example_fake_test.go
  • sdk/go/openshell/v1/example_test.go
  • sdk/go/openshell/v1/exec_client.go
  • sdk/go/openshell/v1/exec_client_test.go
  • sdk/go/openshell/v1/fake/broadcaster.go
  • sdk/go/openshell/v1/fake/broadcaster_test.go
  • sdk/go/openshell/v1/fake/config.go
  • sdk/go/openshell/v1/fake/config_test.go
  • sdk/go/openshell/v1/fake/doc.go
  • sdk/go/openshell/v1/fake/exec.go
  • sdk/go/openshell/v1/fake/exec_test.go
  • sdk/go/openshell/v1/fake/fake.go
  • sdk/go/openshell/v1/fake/fake_test.go
  • sdk/go/openshell/v1/fake/file.go
  • sdk/go/openshell/v1/fake/file_test.go
  • sdk/go/openshell/v1/fake/health.go
  • sdk/go/openshell/v1/fake/health_test.go
  • sdk/go/openshell/v1/fake/inference.go
  • sdk/go/openshell/v1/fake/inference_test.go
  • sdk/go/openshell/v1/fake/policy.go
  • sdk/go/openshell/v1/fake/policy_test.go
  • sdk/go/openshell/v1/fake/profile.go
  • sdk/go/openshell/v1/fake/profile_test.go
  • sdk/go/openshell/v1/fake/provider.go
  • sdk/go/openshell/v1/fake/provider_test.go
  • sdk/go/openshell/v1/fake/refresh.go
  • sdk/go/openshell/v1/fake/refresh_test.go
  • sdk/go/openshell/v1/fake/sandbox.go
  • sdk/go/openshell/v1/fake/sandbox_test.go
  • sdk/go/openshell/v1/fake/service.go
  • sdk/go/openshell/v1/fake/service_test.go
  • sdk/go/openshell/v1/fake/ssh.go
  • sdk/go/openshell/v1/fake/ssh_test.go
  • sdk/go/openshell/v1/fake/store.go
  • sdk/go/openshell/v1/fake/store_test.go
  • sdk/go/openshell/v1/fake/tcp.go
  • sdk/go/openshell/v1/fake/tcp_test.go
  • sdk/go/openshell/v1/fake/workspace.go
  • sdk/go/openshell/v1/fake/workspace_test.go
  • sdk/go/openshell/v1/file.go
  • sdk/go/openshell/v1/file_client.go
  • sdk/go/openshell/v1/file_client_test.go
  • sdk/go/openshell/v1/gateway/config.go
  • sdk/go/openshell/v1/gateway/config_test.go
  • sdk/go/openshell/v1/gateway/doc.go
  • sdk/go/openshell/v1/gateway/errors.go
  • sdk/go/openshell/v1/gateway/errors_test.go
  • sdk/go/openshell/v1/gateway/gateway.go
  • sdk/go/openshell/v1/gateway/gateway_test.go
  • sdk/go/openshell/v1/gateway/options.go
  • sdk/go/openshell/v1/gateway/paths.go
  • sdk/go/openshell/v1/gateway/paths_test.go
  • sdk/go/openshell/v1/gateway/token.go
  • sdk/go/openshell/v1/gateway/token_test.go
  • sdk/go/openshell/v1/health.go
  • sdk/go/openshell/v1/health_client.go
  • sdk/go/openshell/v1/health_client_test.go
  • sdk/go/openshell/v1/inference.go
  • sdk/go/openshell/v1/inference_client.go
  • sdk/go/openshell/v1/inference_client_test.go
  • sdk/go/openshell/v1/integration_test.go
  • sdk/go/openshell/v1/internal/converter/copy.go
  • sdk/go/openshell/v1/internal/converter/coverage_test.go
  • sdk/go/openshell/v1/internal/converter/errors.go
  • sdk/go/openshell/v1/internal/converter/exec.go
  • sdk/go/openshell/v1/internal/converter/exec_test.go
  • sdk/go/openshell/v1/internal/converter/health.go
  • sdk/go/openshell/v1/internal/converter/health_test.go
  • sdk/go/openshell/v1/internal/converter/inference.go
  • sdk/go/openshell/v1/internal/converter/inference_test.go
  • sdk/go/openshell/v1/internal/converter/network_policy.go
  • sdk/go/openshell/v1/internal/converter/network_policy_test.go
  • sdk/go/openshell/v1/internal/converter/policy.go
  • sdk/go/openshell/v1/internal/converter/policy_test.go
  • sdk/go/openshell/v1/internal/converter/profile.go
  • sdk/go/openshell/v1/internal/converter/profile_test.go
  • sdk/go/openshell/v1/internal/converter/provider_test.go
  • sdk/go/openshell/v1/internal/converter/refresh.go
  • sdk/go/openshell/v1/internal/converter/refresh_test.go
  • sdk/go/openshell/v1/internal/converter/sandbox.go
  • sdk/go/openshell/v1/internal/converter/sandbox_test.go
  • sdk/go/openshell/v1/internal/converter/service.go
  • sdk/go/openshell/v1/internal/converter/service_test.go
  • sdk/go/openshell/v1/internal/converter/setting.go
  • sdk/go/openshell/v1/internal/converter/setting_test.go
  • sdk/go/openshell/v1/internal/converter/ssh.go
  • sdk/go/openshell/v1/internal/converter/ssh_test.go
  • sdk/go/openshell/v1/internal/converter/time_test.go
  • sdk/go/openshell/v1/internal/converter/workspace.go
  • sdk/go/openshell/v1/internal/converter/workspace_test.go
  • sdk/go/openshell/v1/internal/grpc/conn.go
  • sdk/go/openshell/v1/internal/grpc/conn_test.go
  • sdk/go/openshell/v1/oidc/authcode.go
  • sdk/go/openshell/v1/oidc/authcode_test.go
  • sdk/go/openshell/v1/oidc/browser.go
  • sdk/go/openshell/v1/oidc/browser_test.go
  • sdk/go/openshell/v1/oidc/credentials.go
  • sdk/go/openshell/v1/oidc/credentials_test.go
  • sdk/go/openshell/v1/oidc/device.go
  • sdk/go/openshell/v1/oidc/device_test.go
  • sdk/go/openshell/v1/oidc/discovery.go
  • sdk/go/openshell/v1/oidc/discovery_test.go
  • sdk/go/openshell/v1/oidc/doc.go
  • sdk/go/openshell/v1/oidc/errors.go
  • sdk/go/openshell/v1/oidc/errors_test.go
  • sdk/go/openshell/v1/oidc/example_test.go
  • sdk/go/openshell/v1/oidc/keyboard.go
  • sdk/go/openshell/v1/oidc/keyboard_test.go
  • sdk/go/openshell/v1/oidc/oidc.go
  • sdk/go/openshell/v1/oidc/oidc_test.go
  • sdk/go/openshell/v1/oidc/options.go
  • sdk/go/openshell/v1/oidc/options_test.go
  • sdk/go/openshell/v1/oidc/token.go
  • sdk/go/openshell/v1/oidc/token_test.go
  • sdk/go/openshell/v1/options.go
  • sdk/go/openshell/v1/policy.go
  • sdk/go/openshell/v1/policy_client.go
  • sdk/go/openshell/v1/policy_client_test.go
  • sdk/go/openshell/v1/profile.go
  • sdk/go/openshell/v1/profile_client.go
  • sdk/go/openshell/v1/profile_client_test.go
  • sdk/go/openshell/v1/provider_client.go
  • sdk/go/openshell/v1/provider_client_test.go
  • sdk/go/openshell/v1/refresh.go
  • sdk/go/openshell/v1/refresh_client.go
  • sdk/go/openshell/v1/refresh_client_test.go
  • sdk/go/openshell/v1/sandbox.go
  • sdk/go/openshell/v1/sandbox_client.go
  • sdk/go/openshell/v1/sandbox_client_test.go
  • sdk/go/openshell/v1/service.go
  • sdk/go/openshell/v1/service_client.go
  • sdk/go/openshell/v1/service_client_test.go
  • sdk/go/openshell/v1/ssh.go
  • sdk/go/openshell/v1/ssh_client.go
  • sdk/go/openshell/v1/ssh_client_test.go
  • sdk/go/openshell/v1/stub_clients.go
  • sdk/go/openshell/v1/tcp.go
  • sdk/go/openshell/v1/tcp_client.go
  • sdk/go/openshell/v1/tcp_client_test.go
  • sdk/go/openshell/v1/types.go
  • sdk/go/openshell/v1/types/config.go
  • sdk/go/openshell/v1/types/errors.go
  • sdk/go/openshell/v1/types/health.go
  • sdk/go/openshell/v1/types/inference.go
  • sdk/go/openshell/v1/types/network_policy.go
  • sdk/go/openshell/v1/types/options.go
  • sdk/go/openshell/v1/types/policy.go
  • sdk/go/openshell/v1/types/profile.go
  • sdk/go/openshell/v1/types/sandbox.go
  • sdk/go/openshell/v1/types/service.go
  • sdk/go/openshell/v1/types/setting.go
  • sdk/go/openshell/v1/types/types.go
  • sdk/go/openshell/v1/types/workspace.go
  • sdk/go/openshell/v1/watch_test.go
  • sdk/go/openshell/v1/workspace.go
  • sdk/go/openshell/v1/workspace_client.go
  • sdk/go/openshell/v1/workspace_test.go
  • tasks/go.toml
  • tasks/test.toml

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


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.

@rhuss
rhuss requested a balanced review from Copilot August 10, 2026 05:26

Copilot AI 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.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

Add the Go SDK implementation covering all gateway RPC services with
domain-typed clients, comprehensive OIDC authentication flows, fake
test doubles, and proto converters.

Domain clients: Sandbox, Provider, Exec, File, TCP, SSH, Policy,
Profile, Health, Service, Config, Workspace, Inference, Refresh.
Each client validates inputs, resolves sandboxes by name, and converts
between domain types and proto at the boundary.

Auth: OIDC authorization code (PKCE), device code (RFC 8628), and
client credentials (RFC 6749 Section 4.4) flows with gateway config
auto-resolution. Token refresh with singleflight deduplication and
exponential backoff. Edge tunnel proxy for gRPC-over-WebSocket.

Gateway: On-disk gateway discovery with user/system directory
precedence, lazy token loading, and auth mode mapping.

Testing: In-memory fake client with deep-copy isolation, watch
broadcasting with filtering, and workspace-scoped object stores.
Bufconn-based gRPC tests for all domain clients.

Ref: NVIDIA#2044

Signed-off-by: Roland Huß <rhuss@redhat.com>
@rhuss
rhuss force-pushed the go-sdk-b-complete branch from 61f9432 to 3e46ae8 Compare August 11, 2026 12:31
@rhuss rhuss closed this Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants