Skip to content

feat(server): implement OSEP-0011 signed endpoint for secure route access#787

Merged
hittyt merged 17 commits intoalibaba:mainfrom
Pangjiping:feat/signed-endpoint-inte
Apr 27, 2026
Merged

feat(server): implement OSEP-0011 signed endpoint for secure route access#787
hittyt merged 17 commits intoalibaba:mainfrom
Pangjiping:feat/signed-endpoint-inte

Conversation

@Pangjiping
Copy link
Copy Markdown
Collaborator

@Pangjiping Pangjiping commented Apr 25, 2026

Summary

  • Implement OSEP-0011: add GetSignedEndpoint API that returns a time-limited signed route token for sandbox endpoint access. The server signs routes with SHA256, and the ingress gateway verifies the signature before proxying traffic. This enables secure, short-lived access to sandbox ports without sharing static tokens.

Changes

Server (OSEP-0011 signing)

  • GET /sandboxes/{sandboxId}/endpoints/{port}?expires=<unix_seconds> — when expires is provided, returns a signed route token embedded in the endpoint URL/headers
  • POST /sandboxes secure_access field — enables static SecureAccessToken header on unsigned GetEndpoint responses
  • SHA256 signing: hex8(sha256(BE32(len(secret)) || secret || BE32(len(canonical)) || canonical)) + key_id
  • Canonical: v1\nshort\n{sandbox_id}\n{port}\n{expires_b36}\n
  • Shared signing key config ([ingress.secure_access]) in server TOML, shared with ingress via --secure-access-keys
  • Signed endpoint omits the static SecureAccessToken header (route token only)

SDKs (all 5)

  • New GetSignedEndpoint(sandboxId, port, expires) method on each SDK — Go, TypeScript, Python, Kotlin, C#.

Helm chart

  • server.gateway.secureAccess.activeKey / keys — shared signing keys
  • _helpers.tpl renders [ingress.secure_access] TOML
  • ingress-gateway.yaml passes --secure-access-keys flag

E2E tests

  • K8s ingress E2E configures signing keys via Helm, runs GetSignedEndpoint test
  • Tests: obtain signed endpoint, make /ping call through gateway with route token, verify expired timestamps rejected

Documentation

  • OSEP-0011 status updated to implemented

Testing

  • Not run (explain why)
  • Unit tests
  • Integration tests
  • e2e / manual verification

Breaking Changes

  • None
  • Yes (describe impact and migration path)

Checklist

  • Linked Issue or clearly described motivation
  • Added/updated docs (if needed)
  • Added/updated tests (if needed)
  • Security impact considered
  • Backward compatibility considered

Pangjiping and others added 14 commits April 25, 2026 14:43
…cess

Add route signing utilities (base36 expiry, SHA256-based signature), config
models for secure access keys, and API/service layer changes to issue
time-limited signed route tokens on GetEndpoint.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The routeToken field is not needed since the signed route is already
embedded in the endpoint URL. Remove the corresponding field from the
schema, the build_signed_route_token utility, and all related tests.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Implement get_signed_endpoint across Go, JS, Python, Kotlin, and C#
SDKs. Each SDK exposes a new method (GetSignedEndpoint / get_signed_endpoint /
getSignedEndpoint) that calls the existing endpoint API with the expires
query parameter for OSEP-0011 signed route tokens.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add server.gateway.secureAccess to values.yaml. When keys are provided,
the Helm chart renders [ingress.secure_access] into the server's TOML
config and passes --secure-access-keys to the ingress gateway container,
ensuring both sides use the same OSEP-0011 signing keys.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add K8s E2E test for OSEP-0011 signed endpoints: verify route token is
returned, make a /ping call through the gateway with the signed endpoint,
and confirm expired timestamps are rejected. Wire signing keys into Helm
values so server and ingress share the same key for E2E runs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The API returns endpoint without scheme; the SDK internally prepends
{protocol}://. Match that in the E2E test.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
feat(tests): verify signed endpoint omits and unsigned includes the header

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@Pangjiping Pangjiping added documentation Improvements or additions to documentation feature New feature or request component/server sdks labels Apr 25, 2026
@Pangjiping Pangjiping marked this pull request as ready for review April 25, 2026 09:19
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7f13df2a6b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread server/opensandbox_server/services/k8s/kubernetes_service.py
Comment thread server/opensandbox_server/config.py Outdated
Pangjiping and others added 3 commits April 25, 2026 18:00
Without this check, values > uint64 max reach encode_expires_b36()
and raise ValueError, which the generic exception handler converts
into a 500. Validate explicitly and return 400 INVALID_PARAMETER.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Duplicate key_id entries cause a runtime mismatch: server signs with the
first match while ingress stores keys in a map (last duplicate wins),
making all signed endpoints fail verification.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@hittyt hittyt left a comment

Choose a reason for hiding this comment

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

LGTM

@hittyt hittyt merged commit ff48f45 into alibaba:main Apr 27, 2026
41 of 42 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/server documentation Improvements or additions to documentation feature New feature or request sdks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants