mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-02 07:34:45 +08:00
* feat(extensions)!: normalize protocol negotiation Closes #3057 Introduce a shared extension handshake, enforce protocol and capability compatibility across extension families, and expose immutable negotiated snapshots through gateway info and the Go SDK. Signed-off-by: Seth Jennings <sjenning@redhat.com> * fix(credentials): fail fast on negotiation errors Signed-off-by: Seth Jennings <sjenning@redhat.com> * fix(extensions): validate gateway handshake metadata Signed-off-by: Seth Jennings <sjenning@redhat.com> * fix(go-sdk): re-export extension kind constants Signed-off-by: Seth Jennings <sjenning@redhat.com> * fix(extensions): fail fast on credential handshake rejection Signed-off-by: Seth Jennings <sjenning@redhat.com> --------- Signed-off-by: Seth Jennings <sjenning@redhat.com>
152 lines
5.5 KiB
Protocol Buffer
152 lines
5.5 KiB
Protocol Buffer
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
syntax = "proto3";
|
|
|
|
package openshell.gateway_interceptor.v1;
|
|
|
|
import "google/protobuf/struct.proto";
|
|
import "extension.proto";
|
|
import "openshell.proto";
|
|
|
|
// GatewayInterceptor lets an external governance service evaluate gateway
|
|
// control-plane operations after OpenShell admission and before or after the
|
|
// gateway applies the operation.
|
|
service GatewayInterceptor {
|
|
// Describe returns the interceptor manifest and declared bindings.
|
|
rpc Describe(DescribeRequest) returns (InterceptorManifest);
|
|
|
|
// SnapshotProviderProfiles returns the interceptor's current provider
|
|
// profile snapshot when the manifest advertises provider_profiles = true.
|
|
rpc SnapshotProviderProfiles(ProviderProfileSnapshotRequest)
|
|
returns (ProviderProfileSnapshot);
|
|
|
|
// Evaluate returns an allow, deny, or mutation decision for one operation
|
|
// phase.
|
|
rpc Evaluate(InterceptorEvaluation) returns (InterceptorResult);
|
|
}
|
|
|
|
message DescribeRequest {
|
|
// Gateway protocol metadata. Interceptors must reject unmet requirements.
|
|
openshell.extension.v1.PeerMetadata gateway = 1;
|
|
}
|
|
|
|
message ProviderProfileSnapshotRequest {}
|
|
|
|
enum GatewayInterceptorPhase {
|
|
GATEWAY_INTERCEPTOR_PHASE_UNSPECIFIED = 0;
|
|
GATEWAY_INTERCEPTOR_PHASE_MODIFY_OPERATION = 2;
|
|
GATEWAY_INTERCEPTOR_PHASE_VALIDATE = 3;
|
|
GATEWAY_INTERCEPTOR_PHASE_POST_COMMIT = 4;
|
|
}
|
|
|
|
message InterceptorEvaluation {
|
|
// Configured interceptor instance name.
|
|
string interceptor_name = 1;
|
|
// Manifest binding id selected for this evaluation.
|
|
string binding_id = 2;
|
|
// Public gRPC service name, e.g. "openshell.v1.OpenShell".
|
|
string service = 3;
|
|
// Public gRPC method name, e.g. "CreateSandbox".
|
|
string method = 4;
|
|
// Caller identity summary. Values are intentionally non-secret.
|
|
map<string, string> principal = 5;
|
|
|
|
// Exactly one phase payload is set for each evaluation.
|
|
oneof phase {
|
|
// Evaluation that may modify the prepared gateway operation.
|
|
ModifyOperationEvaluation modify_operation = 6;
|
|
// Evaluation that may reject, but not mutate, the prepared operation.
|
|
ValidateEvaluation validate = 7;
|
|
// Evaluation after the gateway operation has completed successfully.
|
|
PostCommitEvaluation post_commit = 8;
|
|
}
|
|
}
|
|
|
|
message ModifyOperationEvaluation {
|
|
// Gateway-prepared operation the gateway proposes to execute.
|
|
google.protobuf.Struct proposed_operation = 1;
|
|
}
|
|
|
|
message ValidateEvaluation {
|
|
// Gateway-prepared operation after earlier interceptor modifications.
|
|
google.protobuf.Struct proposed_operation = 1;
|
|
// Optional read-only gateway state loaded before applying the operation.
|
|
google.protobuf.Struct current_state = 2;
|
|
}
|
|
|
|
message PostCommitEvaluation {
|
|
// Protobuf JSON-shaped response returned by the committed gateway operation.
|
|
google.protobuf.Struct committed_response = 1;
|
|
}
|
|
|
|
message InterceptorResult {
|
|
// False denies the operation before side effects for modify_operation and
|
|
// validate. Post-commit denial is invalid.
|
|
bool allowed = 1;
|
|
// Human-readable reason for logs and denied gRPC status messages.
|
|
string reason = 2;
|
|
// Optional gRPC status code name for denials, e.g. "PERMISSION_DENIED".
|
|
string status_code = 3;
|
|
// RFC 6902 JSON patches. Only valid during modify_operation.
|
|
repeated JsonPatch patches = 4;
|
|
// Non-secret annotations included in gateway logs.
|
|
map<string, string> log_annotations = 5;
|
|
}
|
|
|
|
message InterceptorManifest {
|
|
// Human-readable interceptor name declared by the service.
|
|
string name = 1;
|
|
// Bindings declared by the interceptor service.
|
|
repeated InterceptorBinding bindings = 2;
|
|
// Optional default failure policy for bindings without their own policy.
|
|
// Supported values are "fail_closed" and "fail_open".
|
|
string failure_policy = 3;
|
|
// True when this interceptor implements SnapshotProviderProfiles.
|
|
bool provider_profiles = 4;
|
|
// Exact JWT audience this service verifies on inbound OpenShell calls.
|
|
// After authenticated Describe succeeds, the gateway refuses to start unless
|
|
// this matches the operator-configured audience. A strict verifier may reject
|
|
// an incorrect audience before returning this manifest. Empty skips this
|
|
// post-authentication consistency check.
|
|
string expected_audience = 5;
|
|
// Gateway-interceptor protocol metadata. Required for negotiation.
|
|
openshell.extension.v1.PeerMetadata extension = 6;
|
|
}
|
|
|
|
message ProviderProfileSnapshot {
|
|
// Opaque source revision used for cache freshness and sandbox reload checks.
|
|
string revision = 1;
|
|
// Complete profile snapshot vended by this source.
|
|
repeated openshell.v1.ProviderProfile profiles = 2;
|
|
}
|
|
|
|
message InterceptorBinding {
|
|
// Stable binding id used for config overrides and audit logs.
|
|
string id = 1;
|
|
// RPC selector. Selectors are intentionally tied to the public API shape.
|
|
InterceptorSelector selector = 2;
|
|
// Phases this binding wants to evaluate.
|
|
repeated GatewayInterceptorPhase phases = 3;
|
|
// Optional binding-specific failure policy.
|
|
// Supported values are "fail_closed" and "fail_open".
|
|
// Bindings that include post_commit must resolve to "fail_open" because the
|
|
// gateway operation has already committed before that phase runs.
|
|
string failure_policy = 4;
|
|
}
|
|
|
|
message InterceptorSelector {
|
|
// Full selector form: "openshell.v1.OpenShell/CreateSandbox".
|
|
string rpc = 1;
|
|
// Structured service/method form. If rpc is set, it takes precedence.
|
|
string service = 2;
|
|
string method = 3;
|
|
}
|
|
|
|
message JsonPatch {
|
|
string op = 1;
|
|
string path = 2;
|
|
google.protobuf.Value value = 3;
|
|
string from = 4;
|
|
}
|