|
| 1 | +// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. |
| 2 | +// SPDX-License-Identifier: Apache-2.0 |
| 3 | + |
| 4 | +syntax = "proto3"; |
| 5 | + |
| 6 | +package openshell.isolation.backend.v1; |
| 7 | + |
| 8 | +import "extension.proto"; |
| 9 | +import "options.proto"; |
| 10 | + |
| 11 | +// Draft external Isolation Backend control contract. The supervisor uses this |
| 12 | +// service on an operator-configured, authenticated endpoint. Workload control, |
| 13 | +// network mediation, and byte streams remain on the Sandbox Protocol. |
| 14 | +// PeerMetadata negotiates the base, boundary-routing, and suspend/resume |
| 15 | +// capabilities independently; suspend/resume is optional for a backend. |
| 16 | +service IsolationBackend { |
| 17 | + // Negotiate the isolation contract before opening a boundary. This call |
| 18 | + // conveys no sandbox credentials or driver descriptor. |
| 19 | + rpc GetCapabilities(GetIsolationCapabilitiesRequest) returns (GetIsolationCapabilitiesResponse); |
| 20 | + |
| 21 | + // Bind a driver-provisioned resource to one fresh sandbox launch. The |
| 22 | + // caller credential must match sandbox_id and generation_id. This call must |
| 23 | + // not run untrusted workload code. The subsequent Sandbox Protocol attach, |
| 24 | + // confirm, and start sequence remains mandatory. |
| 25 | + rpc OpenBoundary(OpenBoundaryRequest) returns (OpenBoundaryResponse); |
| 26 | + |
| 27 | + // Freeze the workload, retain its state, and fence the old generation before |
| 28 | + // returning. The caller credential must match the active boundary. The |
| 29 | + // compute driver owns storage and handoff of the reference. |
| 30 | + rpc SuspendBoundary(SuspendBoundaryRequest) returns (SuspendBoundaryResponse); |
| 31 | + |
| 32 | + // Restore a suspended boundary into a fresh launch session and generation. |
| 33 | + // The restored workload remains frozen until attach, confirm, and start |
| 34 | + // complete under the new supervisor. A permitted cold start is reported. |
| 35 | + rpc ResumeBoundary(ResumeBoundaryRequest) returns (OpenBoundaryResponse); |
| 36 | +} |
| 37 | + |
| 38 | +message GetIsolationCapabilitiesRequest { |
| 39 | + openshell.extension.v1.PeerMetadata supervisor = 1; |
| 40 | +} |
| 41 | + |
| 42 | +message GetIsolationCapabilitiesResponse { |
| 43 | + openshell.extension.v1.PeerMetadata backend = 1; |
| 44 | +} |
| 45 | + |
| 46 | +message OpenBoundaryRequest { |
| 47 | + // Stable gateway-assigned sandbox identity, not a public resource name. |
| 48 | + string sandbox_id = 1; |
| 49 | + // Fresh for each launch and unchanged for retries of that launch. |
| 50 | + string session_id = 2; |
| 51 | + // Fresh runtime generation bound to the supervisor's launch credential. |
| 52 | + string generation_id = 3; |
| 53 | + // Must match trusted admission and the configured endpoint registration. |
| 54 | + string backend_name = 4; |
| 55 | + // Opaque descriptor from the trusted compute driver. The backend validates |
| 56 | + // its resource binding; workload-controlled input must not select it. |
| 57 | + bytes driver_descriptor = 5 [(openshell.options.v1.secret) = true]; |
| 58 | + // Stable idempotency key for this launch transition. |
| 59 | + string request_id = 6; |
| 60 | +} |
| 61 | + |
| 62 | +message OpenBoundaryResponse { |
| 63 | + // Opaque handle scoped to this sandbox and runtime generation. The supervisor |
| 64 | + // presents it when opening Sandbox Protocol streams. |
| 65 | + string boundary_id = 1; |
| 66 | + |
| 67 | + enum LaunchOutcome { |
| 68 | + LAUNCH_OUTCOME_UNSPECIFIED = 0; |
| 69 | + LAUNCH_OUTCOME_FRESH = 1; |
| 70 | + LAUNCH_OUTCOME_RESTORED = 2; |
| 71 | + LAUNCH_OUTCOME_COLD_START_FALLBACK = 3; |
| 72 | + } |
| 73 | + |
| 74 | + // Required. A restoration result remains frozen until the new supervisor |
| 75 | + // authenticates, confirms enforcement, installs current policy and secrets, |
| 76 | + // and explicitly starts the boundary. Fallback must be visible to callers. |
| 77 | + LaunchOutcome outcome = 2; |
| 78 | +} |
| 79 | + |
| 80 | +message SuspendBoundaryRequest { |
| 81 | + string boundary_id = 1; |
| 82 | + string session_id = 2; |
| 83 | + string generation_id = 3; |
| 84 | + // Replays of this request return the same reference or a terminal error. |
| 85 | + string request_id = 4; |
| 86 | +} |
| 87 | + |
| 88 | +message SuspendBoundaryResponse { |
| 89 | + // Opaque protected state reference. It may be used only with an authorized |
| 90 | + // ResumeBoundary request for the same sandbox and a fresh generation. |
| 91 | + bytes restore_reference = 1 [(openshell.options.v1.secret) = true]; |
| 92 | +} |
| 93 | + |
| 94 | +message ResumeBoundaryRequest { |
| 95 | + // Fresh launch identity and trusted driver descriptor. Replays reuse the |
| 96 | + // same launch request; the old session and generation are never reused. |
| 97 | + OpenBoundaryRequest launch = 1; |
| 98 | + // Reference returned by SuspendBoundary for this sandbox. It carries no |
| 99 | + // authority without the new authenticated launch credential. |
| 100 | + bytes restore_reference = 2 [(openshell.options.v1.secret) = true]; |
| 101 | + // If false, fail when the memory image cannot be restored. If true, a clean |
| 102 | + // boot from the image and persistent volumes is permitted and reported as |
| 103 | + // LAUNCH_OUTCOME_COLD_START_FALLBACK. |
| 104 | + bool allow_cold_start_fallback = 3; |
| 105 | +} |
0 commit comments