Skip to content

Commit feb7e32

Browse files
committed
feat(isolation): define delegated backend wire contract
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
1 parent 0ea0d31 commit feb7e32

2 files changed

Lines changed: 125 additions & 0 deletions

File tree

‎crates/openshell-sandbox-backend/proto/openshell_sandbox.proto‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,23 @@ service IsolationBoundary {
1818
message BoundaryChunk {
1919
bytes data = 1;
2020
}
21+
22+
// Draft stream entrypoint for a shared out-of-process Isolation Backend.
23+
// Each client stream starts with a boundary_id frame. The backend checks that
24+
// handle against the authenticated sandbox and generation before accepting any
25+
// data. Subsequent data fragments carry the existing Sandbox Protocol bytes.
26+
// This service does not change the first-party IsolationBoundary RPCs.
27+
service DelegatedIsolationBoundary {
28+
rpc Exchange(stream DelegatedBoundaryChunk) returns (stream DelegatedBoundaryChunk);
29+
rpc Mediate(stream DelegatedBoundaryChunk) returns (stream DelegatedBoundaryChunk);
30+
}
31+
32+
message DelegatedBoundaryChunk {
33+
oneof payload {
34+
// Required as the first client frame; forbidden on later frames.
35+
string boundary_id = 1;
36+
// Ordered fragment of the existing Sandbox Protocol. Response frames only
37+
// use data. Empty data is allowed and does not bind a stream.
38+
bytes data = 2;
39+
}
40+
}

‎proto/isolation_backend.proto‎

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
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

Comments
 (0)