Skip to content

Commit c841c70

Browse files
committed
feat(egress-gate): add attested Pi admission
1 parent 30b073f commit c841c70

21 files changed

Lines changed: 2406 additions & 50 deletions

projects/egress-gate/proto/supervisor_middleware.proto

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import "google/protobuf/empty.proto";
99
import "google/protobuf/struct.proto";
1010

1111
// SupervisorMiddleware lets an operator-run service inspect and transform
12-
// sandbox HTTP egress before OpenShell injects credentials.
12+
// sandbox HTTP egress or evaluate a supported agent-harness request.
1313
service SupervisorMiddleware {
1414
// Describe returns the service manifest and declared bindings.
1515
rpc Describe(google.protobuf.Empty) returns (MiddlewareManifest);
@@ -20,6 +20,10 @@ service SupervisorMiddleware {
2020
// EvaluateHttpRequest returns an allow, deny, or mutation decision for one
2121
// buffered HTTP request.
2222
rpc EvaluateHttpRequest(HttpRequestEvaluation) returns (HttpRequestResult);
23+
24+
// EvaluateAgentConversation returns an allow, deny, or replacement decision for
25+
// one versioned, harness-native request before the harness commits or sends it.
26+
rpc EvaluateAgentConversation(AgentConversationEvaluation) returns (AgentConversationResult);
2327
}
2428

2529
// MiddlewareManifest describes one middleware service and the bindings it
@@ -38,9 +42,9 @@ message MiddlewareManifest {
3842

3943
// MiddlewareBinding declares one operation and phase supported by a service.
4044
message MiddlewareBinding {
41-
// Supported operation. V1 supports HTTP_REQUEST.
45+
// Supported operation.
4246
SupervisorMiddlewareOperation operation = 1;
43-
// Supported evaluation phase. V1 supports PRE_CREDENTIALS.
47+
// Supported evaluation phase.
4448
SupervisorMiddlewarePhase phase = 2;
4549
// Maximum request or replacement body this binding can process.
4650
uint64 max_body_bytes = 3;
@@ -50,6 +54,12 @@ message MiddlewareBinding {
5054
// Values use an integer with an `ms` or `s` suffix and must be between
5155
// 10ms and 30s.
5256
string timeout = 4;
57+
// Agent harness supported by an AGENT_CONVERSATION binding. Empty for HTTP_REQUEST.
58+
string harness = 5;
59+
// Harness hook supported by an AGENT_CONVERSATION binding. Empty for HTTP_REQUEST.
60+
string hook = 6;
61+
// Version of the harness-native request schema. Empty for HTTP_REQUEST.
62+
string schema_version = 7;
5363
}
5464

5565
// ValidateConfigRequest contains one policy configuration to validate.
@@ -104,12 +114,14 @@ message HttpHeader {
104114
enum SupervisorMiddlewareOperation {
105115
SUPERVISOR_MIDDLEWARE_OPERATION_UNSPECIFIED = 0;
106116
SUPERVISOR_MIDDLEWARE_OPERATION_HTTP_REQUEST = 1;
117+
SUPERVISOR_MIDDLEWARE_OPERATION_AGENT_CONVERSATION = 2;
107118
}
108119

109120
// Ordered phase within a supervisor operation.
110121
enum SupervisorMiddlewarePhase {
111122
SUPERVISOR_MIDDLEWARE_PHASE_UNSPECIFIED = 0;
112123
SUPERVISOR_MIDDLEWARE_PHASE_PRE_CREDENTIALS = 1;
124+
SUPERVISOR_MIDDLEWARE_PHASE_AGENT_CONTEXT = 2;
113125
}
114126

115127
// RequestContext identifies the sandbox request being evaluated.
@@ -148,6 +160,51 @@ message Process {
148160
repeated string ancestors = 3;
149161
}
150162

163+
// AgentConversationTarget identifies the harness hook and provider destination for
164+
// which an allowed model request may receive a receipt.
165+
message AgentConversationTarget {
166+
string harness = 1;
167+
string harness_version = 2;
168+
string hook = 3;
169+
string schema_version = 4;
170+
string scheme = 5;
171+
string host = 6;
172+
uint32 port = 7;
173+
string path = 8;
174+
}
175+
176+
// AgentConversationEvaluation is stamped by the supervisor-owned bridge. Workload
177+
// callers supply only the harness request and untrusted request provenance.
178+
message AgentConversationEvaluation {
179+
SupervisorMiddlewarePhase phase = 1;
180+
RequestContext context = 2;
181+
google.protobuf.Struct config = 3;
182+
AgentConversationTarget target = 4;
183+
reserved 5;
184+
string middleware_name = 6;
185+
string session_id = 7;
186+
string turn_id = 8;
187+
bytes request_body = 9;
188+
string source = 10;
189+
string delivery = 11;
190+
string request_kind = 12;
191+
optional uint32 candidate_index = 13;
192+
}
193+
194+
// AgentConversationResult carries the authority decision, an optional complete
195+
// replacement body, and a model-request receipt opaque to OpenShell.
196+
message AgentConversationResult {
197+
Decision decision = 1;
198+
string reason = 2;
199+
reserved 3, 4;
200+
bytes attestation = 5;
201+
repeated Finding findings = 6;
202+
map<string, string> metadata = 7;
203+
string reason_code = 8;
204+
bytes replacement_body = 9;
205+
bool has_replacement_body = 10;
206+
}
207+
151208
// Decision controls whether OpenShell continues processing the request.
152209
enum Decision {
153210
// Invalid response value handled according to the policy failure mode.

projects/egress-gate/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ authors = [
1010
{ name = "NVIDIA CORPORATION & AFFILIATES" },
1111
]
1212
dependencies = [
13+
"cryptography>=50,<51",
1314
"grpcio>=1.81.1,<2",
1415
"protobuf>=6.33.5,<7",
1516
"pydantic>=2.11,<3",
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
"""First-class harness admission and attested-egress APIs."""
2+
3+
from egress_gate.admission.adapters import (
4+
HarnessAdapter,
5+
HarnessAdapterRegistry,
6+
OpenAIChatCompletionsV1Adapter,
7+
PiInputV1,
8+
PiV1Adapter,
9+
PreparedHarnessRequest,
10+
ProviderAdapterRegistry,
11+
ProviderRequestAdapter,
12+
create_pi_adapter_registry,
13+
create_provider_adapter_registry,
14+
)
15+
from egress_gate.admission.canonical import (
16+
CanonicalFunctionCallV1,
17+
CanonicalGenerationV1,
18+
CanonicalMessageV1,
19+
CanonicalRole,
20+
CanonicalToolChoiceV1,
21+
CanonicalToolV1,
22+
ModelRequestV1,
23+
canonical_json_bytes,
24+
)
25+
from egress_gate.admission.models import (
26+
PI_HARNESS_VERSION,
27+
AdmissionDecision,
28+
AdmissionHook,
29+
HarnessAdmissionContext,
30+
HarnessAdmissionRequest,
31+
HarnessAdmissionResult,
32+
PromptProvenance,
33+
)
34+
from egress_gate.admission.processor import (
35+
RECEIPT_HEADER,
36+
AttestedEgressProcessor,
37+
HarnessAdmissionProcessor,
38+
)
39+
from egress_gate.admission.receipts import ReceiptAuthority, ReceiptClaimsV1
40+
41+
__all__ = [
42+
"AdmissionDecision",
43+
"AdmissionHook",
44+
"AttestedEgressProcessor",
45+
"CanonicalFunctionCallV1",
46+
"CanonicalGenerationV1",
47+
"CanonicalMessageV1",
48+
"CanonicalRole",
49+
"CanonicalToolChoiceV1",
50+
"CanonicalToolV1",
51+
"HarnessAdapter",
52+
"HarnessAdapterRegistry",
53+
"HarnessAdmissionContext",
54+
"HarnessAdmissionProcessor",
55+
"HarnessAdmissionRequest",
56+
"HarnessAdmissionResult",
57+
"PromptProvenance",
58+
"PI_HARNESS_VERSION",
59+
"ModelRequestV1",
60+
"OpenAIChatCompletionsV1Adapter",
61+
"PiInputV1",
62+
"PiV1Adapter",
63+
"PreparedHarnessRequest",
64+
"ProviderAdapterRegistry",
65+
"ProviderRequestAdapter",
66+
"RECEIPT_HEADER",
67+
"ReceiptAuthority",
68+
"ReceiptClaimsV1",
69+
"canonical_json_bytes",
70+
"create_pi_adapter_registry",
71+
"create_provider_adapter_registry",
72+
]

0 commit comments

Comments
 (0)