Skip to content

Commit f213e9a

Browse files
authored
docs(middleware): reorganize and expand middleware guides (#3636)
* docs(extensibility): reorganize extensibility and middleware guides Add an extensibility overview that introduces the extension protocol and links every extension point, and move extension caller authentication to a shared page used by middleware and gateway interceptors. Split the supervisor middleware guide into an overview, a Configure and Operate guide, and a Middleware Operations reference for service authors. The overview explains when to use middleware, shows where it runs, lists current limitations, and defines the service contract. Configure and Operate covers policy attachment, service registration, failure behavior, and observability. Middleware Operations describes HTTP request, HTTP response, and WebSocket message operations with shared inputs and results, per-operation diagrams, and detail accordions. Pin page slugs so links resolve, redirect the replaced dev middleware URL, and update reference and architecture links. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * docs(middleware): clarify navigation and service contracts Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * docs(middleware): drop obsolete dev URL redirect Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> --------- Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
1 parent a00ea31 commit f213e9a

16 files changed

Lines changed: 707 additions & 270 deletions

‎architecture/sandbox-limits.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ budgets as new activity.
7272
Middleware also validates every non-body envelope component. Important examples
7373
include 64 KiB service config, 4 KiB request context, 32 KiB target data, 128
7474
request headers totaling 64 KiB, 64 header mutations, 32 findings per stage,
75-
and 64 metadata entries. The detailed external contract lives in
76-
[Supervisor Middleware](../docs/extensibility/supervisor-middleware.mdx).
75+
and 64 metadata entries. The external contract lives in
76+
`proto/supervisor_middleware.proto`, with service-author guidance in the
77+
[supported middleware operations](../docs/extensibility/supervisor-middleware/operations.mdx).
7778

7879
The work semaphore bounds aggregate buffered middleware input to approximately
7980
`32 × 4 MiB`, plus bounded envelope and parser overhead. It is a concurrency

‎architecture/sandbox.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,8 +442,9 @@ against body-aware L7 policy before later stages or the upstream can observe
442442
them. Requests, results, chain length, execution time, and diagnostics are
443443
bounded; external free-form diagnostic text is not exposed in responses or
444444
security logs. See
445-
[Supervisor Middleware](../docs/extensibility/supervisor-middleware.mdx) for
446-
configuration and protocol details.
445+
[Supervisor Middleware](../docs/extensibility/supervisor-middleware/index.mdx) for
446+
an introduction, or the [configuration guide](../docs/extensibility/supervisor-middleware/configure.mdx)
447+
for service registration and policy attachment.
447448

448449
Inference providers use the same egress path as other external services. An
449450
attached provider profile contributes endpoint and binary policy. The proxy

‎docs/about/overview.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ position: 1
1111
NVIDIA OpenShell is an open-source runtime for executing autonomous AI agents in sandboxed environments with kernel-level isolation. It combines sandbox runtime controls and a declarative YAML policy so teams can run agents without giving them unrestricted access to local files, credentials, and external networks.
1212

1313
<Note>
14-
New in OpenShell 0.1.0 is a [stable release cadence](/about/installation#release-cadence), a stronger [security model](/about/how-it-works), and an expanded [extension surface](/extensibility/extension-negotiation), along with much more.
14+
New in OpenShell 0.1.0 is a [stable release cadence](/about/installation#release-cadence), a stronger [security model](/about/how-it-works), and an expanded [extension surface](/extensibility/overview), along with much more.
1515

1616
See our [upgrade guide](/upgrade/0-1-0) for everything that's changed.
1717
</Note>

‎docs/extensibility/drivers.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,5 @@ Configure the active credential driver in the
3636

3737
Drivers exchange peer metadata with the gateway and advertise their extension
3838
family capability. Upgrade both peers together when the protocol version
39-
changes. Refer to [Extensibility Overview](/extensibility/extension-negotiation)
39+
changes. Refer to [Extension Protocol Negotiation](/extensibility/extension-negotiation)
4040
for the negotiation contract.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
---
2+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
# SPDX-License-Identifier: Apache-2.0
4+
title: "Extension Authentication"
5+
sidebar-title: "Authentication"
6+
slug: "extensibility/extension-authentication"
7+
description: "Verify that calls to your gateway interceptor or supervisor middleware service come from your OpenShell gateway."
8+
keywords: "OpenShell Extensions, Extension Authentication, JWT, JWKS, Audience, Gateway Interceptors, Supervisor Middleware"
9+
---
10+
11+
When the gateway has JWT signing configured, OpenShell attaches a short-lived bearer token to every call it makes to a [gateway interceptor](/extensibility/gateway-interceptors) or [supervisor middleware](/extensibility/supervisor-middleware) service. Your service validates this token to confirm that the call comes from your gateway or one of its sandboxes.
12+
13+
## Tokens OpenShell Sends
14+
15+
Each token is an EdDSA-signed JWT scoped to one service registration:
16+
17+
<ParamField path="iss" type="string">
18+
`openshell-gateway:<gateway_id>`.
19+
</ParamField>
20+
21+
<ParamField path="aud" type="string">
22+
The registration's `audience`. Defaults to `urn:openshell:extension:interceptor:<name>` or `urn:openshell:extension:middleware:<name>`.
23+
</ParamField>
24+
25+
<ParamField path="caller_kind" type="'gateway' | 'supervisor'">
26+
`gateway` for calls from the gateway, or `supervisor` for middleware calls from a sandbox supervisor.
27+
</ParamField>
28+
29+
<ParamField path="sandbox_id" type="string">
30+
The calling sandbox. Present only when `caller_kind` is `supervisor`.
31+
</ParamField>
32+
33+
Authenticated network services use `https://` endpoints. OpenShell verifies the service certificate against platform trust roots, or against the private CA in the registration's `tls_ca_cert_path`, and always checks the hostname.
34+
35+
## Establish Trust in the Gateway
36+
37+
Before your service can validate tokens, configure it with three values from the gateway operator:
38+
39+
- The gateway URL.
40+
- The gateway ID. Tokens use `openshell-gateway:<gateway_id>` as their issuer.
41+
- The gateway's public signing key or JWKS.
42+
43+
Configure these values directly instead of discovering them from the gateway. A key fetched from an unverified source does not prove which gateway it belongs to.
44+
45+
To pick up new keys later, fetch `/.well-known/openid-configuration` from the configured gateway URL over TLS, then fetch the keys from its `jwks_uri`. This document looks like OIDC discovery, but its `issuer` is `openshell-gateway:<gateway_id>` rather than the gateway URL. Compare the token's `iss` with that value, not with the URL.
46+
47+
## Validate Each Token
48+
49+
Cache keys by `kid` and check that:
50+
51+
- `typ` is exactly `openshell-ext+jwt`.
52+
- `alg` is `EdDSA`. Pin the algorithm instead of reading it from the token.
53+
- The signature, issuer, exact audience, and expiry are valid.
54+
- `caller_kind` is one your service accepts, and `sandbox_id` matches your expectations when your service scopes behavior per sandbox.
55+
56+
OpenShell reuses a token until it rotates, so do not reject a repeated `jti` as a replay.
57+
58+
## Confirm the Audience at Startup
59+
60+
Return the audience your service expects in the `expected_audience` field of its `Describe` manifest. After authentication succeeds, the gateway compares this value with the operator-configured `audience` and refuses to start when they differ. A strict service may reject a token with the wrong audience before returning its manifest, in which case gateway startup reports an authentication failure. Leave the field empty to skip this check.
61+
62+
## Run Without Authentication
63+
64+
Set `allow_insecure_transport = true` on a registration to use a plaintext `http://` endpoint. OpenShell then sends no token, and your service cannot distinguish OpenShell from any other client that can reach it. The gateway logs a warning for the registration at every startup.
65+
66+
Use this setting for local development, or on a network that already authenticates callers.
67+
68+
## Current Limitations
69+
70+
- Tokens are bearer credentials. A captured token remains valid until it expires unless your service adds proof of possession or request binding.
71+
- Extension tokens share a signing key with other tokens the gateway issues, so you cannot rotate or revoke extension credentials independently.
72+
- mTLS client authentication and overlapping signing-key rotation are not available.

‎docs/extensibility/extension-negotiation.mdx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
33
# SPDX-License-Identifier: Apache-2.0
44
title: "Extension Protocol Negotiation"
5-
sidebar-title: "Overview"
5+
sidebar-title: "Protocol Negotiation"
6+
slug: "extensibility/extension-negotiation"
67
description: "Implement version and capability negotiation for OpenShell extensions."
78
keywords: "OpenShell Extensions, Protocol Version, Capabilities, Version Skew, Migration"
89
---

‎docs/extensibility/gateway-interceptors.mdx‎

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
# SPDX-License-Identifier: Apache-2.0
44
title: "Gateway Interceptors"
55
sidebar-title: "Gateway Interceptors"
6+
slug: "extensibility/gateway-interceptors"
67
description: "Extend OpenShell gateway operations with deployment-specific governance and business logic."
78
keywords: "Generative AI, Cybersecurity, AI Agents, Gateway Interceptors, Extensibility, Governance"
89
---
910
Gateway interceptors let operators add deployment-specific governance to OpenShell control-plane operations without modifying the gateway. An external gRPC service can modify or validate selected API writes before the gateway handles them, then observe successful responses after commit.
1011

1112
See the [governance interceptor example](https://github.com/NVIDIA/OpenShell/tree/main/examples/governance-interceptor) for a complete service that vends provider profiles, applies a signed policy to new sandboxes, and rejects attempts to weaken that policy.
1213

13-
## Choose Gateway Interceptors
14+
## When to Use Gateway Interceptors
1415

1516
Use a gateway interceptor when an external service needs to govern gateway API operations. For example, an interceptor can:
1617

@@ -76,7 +77,7 @@ Start the interceptor before the gateway, then register it in gateway TOML:
7677
[[openshell.gateway.interceptors]]
7778
name = "policy-governance"
7879
grpc_endpoint = "https://governance.example:18081"
79-
tls_ca_cert_path = "/etc/openshell/governance-ca.pem"
80+
tls_ca_cert_path = "/path/to/governance-ca.pem"
8081
audience = "urn:example:governance"
8182
order = 10
8283
failure_policy = "fail_closed"
@@ -96,13 +97,7 @@ phases = ["validate"]
9697

9798
The gateway supports `http://`, `https://`, and `unix://` interceptor endpoints. When gateway JWT signing is configured, authenticated network interceptors use `https://`; Unix sockets remain available for local integrations. HTTPS uses platform trust roots unless `tls_ca_cert_path` supplies a private CA, and normal hostname verification remains enabled. The gateway calls `Describe` and builds an immutable execution plan during startup. An unavailable service, invalid manifest, missing credential, or unauthorized configured binding prevents the gateway from starting.
9899

99-
The gateway attaches a short-lived EdDSA bearer token to `Describe`, `Evaluate`, and provider-profile snapshot calls. The token uses the configured `audience` (defaulting to `urn:openshell:extension:interceptor:<name>`) and `caller_kind: gateway`.
100-
101-
Return your expected audience in the `expected_audience` field of your `Describe` manifest. After authenticated `Describe` succeeds, the gateway compares the advertised value with its operator-configured audience and refuses to start when they differ. This is a post-authentication consistency assertion, not audience discovery: a strict verifier may reject an incorrect audience before returning the manifest, in which case startup reports an authentication failure. Leave the field empty to skip the consistency check.
102-
103-
Provision the trusted gateway URL, expected gateway ID, and public key or JWKS through the deployment. This operator-provisioned key material is the authoritative cold-start trust anchor. The expected issuer is exactly `openshell-gateway:<gateway_id>`; fetching JWKS does not establish that identity by itself. After initial trust is established, `GET /.well-known/openid-configuration` and its `jwks_uri` provide steady-state key refresh and operational convenience. The document is OIDC-shaped rather than OIDC-compliant because `issuer` is the gateway identity rather than the serving URL; compare `iss` against the configured value and fetch updates only over authenticated TLS at the trusted gateway URL. Pin `alg` to `EdDSA`, require `typ` to be exactly `openshell-ext+jwt`, and validate `kid`, signature, expected issuer, exact audience, positive expiry, and caller kind.
104-
105-
Set `allow_insecure_transport = true` on an interceptor to keep a plaintext `http://` endpoint working with no credential attached. The gateway logs a warning naming the interceptor at every startup, and the service cannot distinguish the gateway from any other client that can reach it.
100+
When gateway JWT signing is configured, the gateway authenticates every call to the interceptor with a short-lived token. [Extension Authentication](/extensibility/extension-authentication) describes how your service validates it. Set `allow_insecure_transport = true` to use a plaintext `http://` endpoint without authentication, for local development or on a network that already authenticates callers.
106101

107102
Registration is static. Restart the gateway after adding, removing, or changing an interceptor. See [Gateway Configuration](/reference/gateway-config#gateway-interceptors) for the complete field reference.
108103

@@ -175,6 +170,5 @@ The gateway emits structured evaluation logs containing the interceptor name, bi
175170
- Only explicitly allowlisted unary write RPCs are interceptable. New gateway RPCs are non-interceptable until added to the allowlist.
176171
- `current_state` is available only in the `validate` contract. The gateway does not yet populate it with method-specific state.
177172
- Registration changes require a gateway restart.
178-
- mTLS client authentication, service health checks, runtime registration, and overlapping signing-key rotation are not available.
179-
- Extension tokens and sandbox-to-gateway tokens are signed by the same key, separated by audience and `typ`. The extension credential path cannot yet be rotated or revoked independently of sandbox admission.
173+
- Service health checks and runtime registration are not available. [Extension Authentication](/extensibility/extension-authentication#current-limitations) lists authentication limitations.
180174
- Interceptors cannot receive or mutate protobuf fields marked secret.

‎docs/extensibility/overview.mdx‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
# SPDX-License-Identifier: Apache-2.0
4+
title: "Extensibility"
5+
sidebar-title: "Overview"
6+
slug: "extensibility/overview"
7+
description: "Extend OpenShell with custom traffic checks, gateway governance, drivers, and isolation backends."
8+
keywords: "OpenShell Extensions, Protocol Negotiation, Supervisor Middleware, Gateway Interceptors, Compute Drivers, Credential Drivers, Isolation Backends"
9+
---
10+
11+
OpenShell has several extension points that let you connect your own services and runtimes without changing OpenShell. Choose an extension point based on what you need to control, then implement the shared extension protocol that every extension service uses.
12+
13+
## Extension Protocol
14+
15+
Before OpenShell uses an extension service, both peers exchange their protocol version and supported capabilities. This lets OpenShell and your service detect incompatible versions at startup instead of failing on live traffic. [Extension Protocol Negotiation](/extensibility/extension-negotiation) describes the metadata to exchange and the version-skew policy.
16+
17+
Extension services reachable over the network also need to know that a call comes from your OpenShell gateway. [Extension Authentication](/extensibility/extension-authentication) describes the tokens OpenShell attaches and how your service validates them.
18+
19+
## Extension Points
20+
21+
<Cards>
22+
23+
<Card title="Supervisor Middleware" href="/extensibility/supervisor-middleware">
24+
25+
Check or change the content an agent sends and receives over the network, such as redacting API tokens from outgoing requests or blocking prohibited content.
26+
</Card>
27+
28+
<Card title="Gateway Interceptors" href="/extensibility/gateway-interceptors">
29+
30+
Enforce rules on how people and applications manage OpenShell resources, such as applying an approved policy to new sandboxes or auditing completed operations.
31+
</Card>
32+
33+
<Card title="Drivers" href="/extensibility/drivers">
34+
35+
Connect the gateway to the runtimes that host sandbox workloads and to the stores that hold provider credentials.
36+
</Card>
37+
38+
<Card title="Isolation Backends" href="/extensibility/isolation-backends">
39+
40+
Understand the runtime boundary the supervisor uses to launch and control processes inside a sandbox.
41+
</Card>
42+
43+
</Cards>

0 commit comments

Comments
 (0)