Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ SDKs connect applications to an OpenShell gateway. They do not install the CLI.
| Python | `uv add openshell` | [README](python/openshell/) |
| TypeScript | `npm install @nvidia/openshell-sdk` (GitHub Packages) | [README](sdk/typescript/README.md) |
| Go | `go get github.com/NVIDIA/OpenShell/sdk/go@latest` | [README](sdk/go/README.md) |
| Rust | Git dependency pinned to a release tag | [README](crates/openshell-sdk/README.md) |
| Rust | `cargo add openshell-sdk --git https://github.com/NVIDIA/OpenShell --tag <release-tag>` | [Installation and usage](docs/sdk/rust.mdx) |

## Community

Expand Down
145 changes: 63 additions & 82 deletions docs/about/architecture.mdx

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/extensibility/gateway-interceptors.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ phases = ["validate"]

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.

When gateway JWT signing is configured, the gateway authenticates every call to the interceptor with a short-lived token. [Extension Authentication](/extensibility/overview#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.
When gateway JWT signing is configured, the gateway authenticates every call to the interceptor with a short-lived token. [Authenticating Extensions](/extensibility/overview#authenticating-extensions) 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.

Registration is static. Restart the gateway after adding, removing, or changing an interceptor. See [Gateway Configuration](/how-it-works/gateways/configuration#gateway-interceptors) for the complete field reference.

Expand Down
92 changes: 50 additions & 42 deletions docs/extensibility/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,21 @@ description: "Understand how OpenShell adapts to deployment-specific infrastruct
keywords: "OpenShell Extensions, Middleware, Interceptors, Drivers, Isolation Backends, Protocol Negotiation"
---

![OpenShell extension points across the gateway and runtime: gateway interceptors, compute and credential drivers, supervisor middleware, and isolation backends.](../images/openshell-extension-points.svg)
![OpenShell extension points. Data plane: the sandboxed agent reaches the supervisor through the isolation backend, and supervisor middleware processes requests before they reach models and APIs. Control plane: you reach the gateway through interceptors, and gateway drivers connect it to runtimes and secret stores.](../images/openshell-extension-points.svg)

Extensibility sits at the core of OpenShell. OpenShell is designed to run
everywhere and adapt to the infrastructure, governance, and workload
requirements of each deployment. Its extension points add deployment-specific
behavior while preserving the same API, policy model, and security boundaries.

You can extend each layer of OpenShell:

- **Control plane:** Gateway interceptors govern API operations.
- **Data plane:** Middleware processes agent traffic, and isolation backends
control the sandboxed workload.
- **Infrastructure:** Drivers connect OpenShell to compute runtimes and secret
stores.

## Extension Points

### [Middleware](/extensibility/supervisor-middleware)
Expand Down Expand Up @@ -42,46 +50,6 @@ Isolation backends connect the supervisor to the sandbox runtime. They provide
a consistent contract for process launch, terminal streams, signals, status,
and runtime-specific isolation inside the provisioned workload.

## Authentication

When the gateway has JWT signing configured, OpenShell sends a short-lived bearer token with every call to a [gateway interceptor](/extensibility/gateway-interceptors) or [supervisor middleware](/extensibility/supervisor-middleware) service. Validate it to confirm the call comes from your gateway or one of its sandboxes.

| Claim | Value |
|---|---|
| `iss` | `openshell-gateway:<gateway_id>` |
| `aud` | The registration's `audience`. Defaults to `urn:openshell:extension:interceptor:<name>` or `urn:openshell:extension:middleware:<name>`. |
| `caller_kind` | `gateway`, or `supervisor` for middleware calls from a sandbox. |
| `sandbox_id` | The calling sandbox, when `caller_kind` is `supervisor`. |

### Validate Each Token

Get the gateway ID and public signing key (or JWKS) from the gateway operator and configure them in your service. Don't trust a key discovered from an unverified source. To pick up rotated keys, fetch `/.well-known/openid-configuration` from the gateway over TLS and follow its `jwks_uri`.

For each request, check that:

- `typ` is `openshell-ext+jwt` and `alg` is `EdDSA`. Pin the algorithm; don't read it from the token.
- The signature, expiry, and exact audience are valid.
- `iss` is `openshell-gateway:<gateway_id>`, not the gateway URL.
- `caller_kind` and `sandbox_id` match what your service accepts.

OpenShell reuses a token until it rotates, so don't reject a repeated `jti`.

Services must use `https://` endpoints. OpenShell verifies the certificate and hostname against platform roots, or against `tls_ca_cert_path` for a private CA.

### Confirm the Audience at Startup

Return your expected audience in the `expected_audience` field of your `Describe` manifest. The gateway refuses to start if it doesn't match the configured `audience`. Leave it empty to skip the check.

### Run Without Authentication

Set `allow_insecure_transport = true` on a registration to use a plaintext `http://` endpoint with no token. Your service then can't tell OpenShell apart from any other client, and the gateway logs a warning at every startup. Use this only for local development or on a network that already authenticates callers.

### Current Limitations

- Tokens are bearer credentials: a captured token works until it expires.
- Extension tokens share the gateway's signing key, so you can't rotate or revoke them separately.
- mTLS client authentication and overlapping key rotation aren't available.

## Building Extensions

Start with the narrowest extension point that owns the behavior you need. Keep
Expand Down Expand Up @@ -112,7 +80,7 @@ Use Unix domain sockets when the gateway and extension share a host. Use
`https://` when a service crosses a host or pod boundary. Plaintext `http://`
is intended for explicitly enabled development deployments; authenticated
network extensions use TLS and short-lived gateway-issued credentials. Refer
to [Authentication](#authentication) for how services validate those credentials.
to [Authenticating Extensions](#authenticating-extensions) for how services validate those credentials.

The [governance interceptor example](https://github.com/NVIDIA/OpenShell/tree/main/examples/governance-interceptor)
and [content guard middleware example](https://github.com/NVIDIA/OpenShell/tree/main/examples/supervisor-middleware-content-guard)
Expand All @@ -137,3 +105,43 @@ extensions follow the same compatibility checks.
Use `openshell gateway info` to inspect the negotiated extension families,
implementation versions, protocol versions, and capabilities active on a
gateway.

## Authenticating Extensions

When the gateway has JWT signing configured, OpenShell sends a short-lived bearer token with every call to a [gateway interceptor](/extensibility/gateway-interceptors) or [supervisor middleware](/extensibility/supervisor-middleware) service. Validate it to confirm the call comes from your gateway or one of its sandboxes.

| Claim | Value |
|---|---|
| `iss` | `openshell-gateway:<gateway_id>` |
| `aud` | The registration's `audience`. Defaults to `urn:openshell:extension:interceptor:<name>` or `urn:openshell:extension:middleware:<name>`. |
| `caller_kind` | `gateway`, or `supervisor` for middleware calls from a sandbox. |
| `sandbox_id` | The calling sandbox, when `caller_kind` is `supervisor`. |

### Validate Each Token

Get the gateway ID and public signing key (or JWKS) from the gateway operator and configure them in your service. Don't trust a key discovered from an unverified source. To pick up rotated keys, fetch `/.well-known/openid-configuration` from the gateway over TLS and follow its `jwks_uri`.

For each request, check that:

- `typ` is `openshell-ext+jwt` and `alg` is `EdDSA`. Pin the algorithm; don't read it from the token.
- The signature, expiry, and exact audience are valid.
- `iss` is `openshell-gateway:<gateway_id>`, not the gateway URL.
- `caller_kind` and `sandbox_id` match what your service accepts.

OpenShell reuses a token until it rotates, so don't reject a repeated `jti`.

Services must use `https://` endpoints. OpenShell verifies the certificate and hostname against platform roots, or against `tls_ca_cert_path` for a private CA.

### Confirm the Audience at Startup

Return your expected audience in the `expected_audience` field of your `Describe` manifest. The gateway refuses to start if it doesn't match the configured `audience`. Leave it empty to skip the check.

### Run Without Authentication

Set `allow_insecure_transport = true` on a registration to use a plaintext `http://` endpoint with no token. Your service then can't tell OpenShell apart from any other client, and the gateway logs a warning at every startup. Use this only for local development or on a network that already authenticates callers.

### Current Limitations

- Tokens are bearer credentials: a captured token works until it expires.
- Extension tokens share the gateway's signing key, so you can't rotate or revoke them separately.
- mTLS client authentication and overlapping key rotation aren't available.
4 changes: 2 additions & 2 deletions docs/extensibility/supervisor-middleware/configure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ timeout = "500ms"
</ParamField>

<ParamField path="audience" type="string" default="urn:openshell:extension:middleware:<name>">
Token audience. Refer to [Extension Authentication](/extensibility/overview#authentication).
Token audience. Refer to [Authenticating Extensions](/extensibility/overview#authenticating-extensions).
</ParamField>

<ParamField path="allow_insecure_transport" type="boolean" default="false">
Expand All @@ -62,7 +62,7 @@ timeout = "500ms"

At startup, the gateway contacts every registered service to read its capabilities and verify [protocol compatibility](/extensibility/overview#protocol-negotiation). The gateway does not start if a service is unavailable or incompatible. [Gateway Configuration](/how-it-works/gateways/configuration#supervisor-middleware-services) describes the full TOML context.

When the gateway has JWT signing configured, OpenShell authenticates every call to your service with a short-lived token. [Extension Authentication](/extensibility/overview#authentication) describes how your service validates it.
When the gateway has JWT signing configured, OpenShell authenticates every call to your service with a short-lived token. [Authenticating Extensions](/extensibility/overview#authenticating-extensions) describes how your service validates it.

## Attach Middleware in Policy

Expand Down
2 changes: 1 addition & 1 deletion docs/extensibility/supervisor-middleware/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ These guides cover the rest of the service contract:
When OpenShell calls your service, what it receives, and what it can return for HTTP requests, HTTP responses, and WebSocket messages.
</Card>

<Card title="Extension Authentication" href="/extensibility/overview#authentication">
<Card title="Authenticating Extensions" href="/extensibility/overview#authenticating-extensions">

How to verify that calls to your service come from your OpenShell gateway.
</Card>
Expand Down
Loading
Loading