mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-27 07:03:17 +08:00
* feat(providers): report bounded token-grant failures Signed-off-by: Shiju <shiju@nvidia.com> * test(providers): align policy metadata and TLS lockfile Signed-off-by: Shiju <shiju@nvidia.com> * test(providers): fix trusted grant recovery fixture Signed-off-by: Shiju <shiju@nvidia.com> * test(providers): enable denial API in recovery fixture Signed-off-by: Shiju <shiju@nvidia.com> * refactor(providers): simplify token-grant failure reporting Remove duplication and dead paths from the token-grant failure reporting without changing classification, the workload-visible 502 response, or the wire format. - Build the gRPC failure envelope with tonic-types, store the typed failure in EndpointFailure, and share one request-ID rule and one endpoint-status authority check. - Merge the gateway exchange client wrapper, drop forwarding validators, and name the request field when a reported cause is rejected. - Inject fallback credentials only from live provider state and delete the unread per-connection credential copy. Keep one 502 writer per path and restore the base token-cache handling. - Check the token endpoint after the cache lookup, still before any credential acquisition. - Document 429 and 5xx classification as implemented, and drop tests that repeat retained assertions through the same code path. Signed-off-by: Shiju <shiju@nvidia.com> * refactor(providers): trim token-grant failure tests and supervisor API Cut the token-grant failure tests to one test per distinct behavior across core, gateway, supervisor, CLI and Go, and replace the 794-line closure E2E with status assertions in the existing route-recovery E2E: the refused grant appears in sandbox status with the response's request ID, code, stage and upstream status, and the matching grant's later success clears it. - Pin the live provider snapshot with one helper used by inspected and fallback forwarding, and inject selector-matched grants through inject_for_selectors, which borrows the pinned context. Move the test-only wrapper into test_support. - Drop the 35-second wrappers around the gateway grant RPC. The shared channel bounds the connection attempt and the gateway bounds its token-service calls. - Log the token service's OAuth error and error_description, without control characters and limited to 256 characters each, with the request ID in the gateway or supervisor log. Status and the workload response still carry only the bounded cause. - Keep one check that an untrusted token-service certificate cannot assert a cause. Signed-off-by: Shiju <shiju@nvidia.com> * fix(providers): restore test import and features lockfile The injection tests named EndpointObservationSender through the parent module, which no longer imports it. The features suite lockfile kept the tonic TLS dependency that the removed E2E fixture added. Signed-off-by: Shiju <shiju@nvidia.com> * test(providers): fix body-bound fixture width and table type Pass the response-size width as a named argument; an implicitly captured constant panics at runtime. Name the mutation type in the validation table for Clippy. Signed-off-by: Shiju <shiju@nvidia.com> * test(providers): pad exact-bound body without a format width MAX_TOKEN_RESPONSE_BYTES exceeds u16::MAX, the largest format width, so the padded fixture panicked. Pad with repeat_n as before. Signed-off-by: Shiju <shiju@nvidia.com> * test(server): update public RPC schema hash after rebase Main added the ListProvidersRequest label selector. The merged public schema hash comes from the Branch Checks storage_proto test output. Signed-off-by: Shiju <shiju@nvidia.com> * fix(providers): keep token-service error text out of grant logs A token service can echo a submitted credential in its OAuth error or error_description. Log only the classified failure code, HTTP status and request ID, and cover the canary echo in a dedicated test binary. Signed-off-by: Shiju <shiju@nvidia.com> * docs(providers): tighten token grant failure documentation Signed-off-by: Shiju <shiju@nvidia.com> * docs(providers): condense token grant failure guidance Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com> --------- Signed-off-by: Shiju <shiju@nvidia.com> Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com> Co-authored-by: John Myers <9696606+johntmyers@users.noreply.github.com>
Protobuf API conventions
This directory defines OpenShell's gRPC contracts. These conventions are the source of truth for public protobuf API design. Apply them to new APIs and when changing existing APIs; generated SDK naming follows from these definitions.
Entity references
- Use
namefor the primary resource targeted by an RPC. - Use the resource's role for a related resource reference, such as
sandbox,provider,service, orrule. - Do not append
_nameto a canonical entity reference. Its value is already the canonical name. Descriptive values, local map keys, implementation labels, and configured registration names that are not entity references may retain the suffix. Examples includedisplay_name,file_name,driver_name,runtime_class_name,rule_name, andmiddleware_name. - Public callers reference entities by canonical name. Keep immutable IDs at authentication, persistence, compute-driver, and other internal boundaries.
For example:
message GetSandboxRequest {
openshell.datamodel.v1.WorkspaceSelector workspace_scope = 2;
string name = 1;
}
message ExposeServiceRequest {
openshell.datamodel.v1.WorkspaceSelector workspace_scope = 5;
string sandbox = 1;
string name = 2;
}
GetSandboxRequest.name identifies the RPC's primary resource.
ExposeServiceRequest.sandbox identifies a related sandbox while name
identifies the service being exposed.
Workspace scope
- Public workspace-scoped requests declare
workspace_scopebefore every other field. Existing wire field numbers do not need to follow declaration order. - Type
workspace_scopeasopenshell.datamodel.v1.WorkspaceSelector. - Requests operating in one workspace require a non-empty canonical
WorkspaceSelector.workspace. Thedefaultworkspace is an explicit name, not an omitted-value fallback. - Accept
WorkspaceSelector.all_workspacesonly on collection-list RPCs that explicitly document and authorize cross-workspace access. The supported public collections are sandboxes, sandbox templates, providers, and services. - Requests whose primary resource is a workspace use
name, notworkspace_scope. - Document every request that permits an omitted selector. Current exceptions are platform provider-profile scope and authenticated sandbox bootstrap.
Field and message design
- Prefer a dedicated request and response message for each RPC, including requests that are currently empty.
- Use
google.protobuf.Timestampfor absolute time andgoogle.protobuf.Durationfor elapsed time. - Use optional presence when omitted and explicitly empty values have different meanings. Do not infer presence from a protobuf scalar's default value.
- Keep public request fields in semantic reading order. Field numbers preserve wire identity and may therefore differ from declaration order.
- Document authorization-sensitive selector variants and omission semantics on the containing request.
Schema evolution
- Treat field numbers and fully qualified message names as durable wire identities.
- When removing or renaming a field, reserve its old number and source name. Do not reuse either for a different meaning.
- Review changes against both the public descriptor closure and durable stored
protobuf closure. The
public_and_durable_schema_inventories_are_completetest inopenshell-serverowns both inventories. - Regenerate Rust, Python, Go, and TypeScript bindings after contract changes.
Run
mise run pre-commit, the affected SDK checks, and relevant server tests before submitting the change.