* feat(middleware): define HTTP response pre-return interface
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* docs(middleware): clarify HTTP response interface
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* refactor(middleware): align response result actions
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* refactor(middleware): expose response reason codes
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* refactor(middleware): share session end reasons
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* feat(middleware)!: finalize HTTP response pre-return contract
Replace the separate body_end event with HttpResponseBodyUnit.end_of_stream.
Every body-inspecting stage receives exactly one flagged unit, which may be
empty; a zero-byte body is one empty flagged unit and OpenShell never reads
ahead to set the flag.
Defer response trailers from V1 and reserve their field numbers. HTTP/1.0
clients and Content-Length bodies cannot carry trailers and that behavior was
undefined.
Add HttpResponsePreflight.permitted_body_modes, computed once from the
original upstream head so every stage sees the same list, and make an
unlisted selection a failure rather than a downgrade. Add the block_delivery
preflight action as a successful decision enforced regardless of on_error.
Expose Content-Length, Content-Encoding, and Content-Range read-only in
preflight. Cap STREAM_BYTES input units at half of max_payload_bytes and
permit deferring bytes across replacements only for fail_closed bindings,
surfaced as deferral_permitted.
Split PEER_DISCONNECT into DOWNSTREAM_DISCONNECT and UPSTREAM_DISCONNECT and
attribute WebSocket relay failures by direction instead of a generic peer
error. Compile the content-guard example in lint and branch checks so proto
renames cannot break it silently.
BREAKING CHANGE: WebSocketSessionEndReason and WebSocketSessionEnd are
replaced by the shared MiddlewareSessionEndReason and MiddlewareSessionEnd.
NORMAL_CLOSE is now NORMAL, UPSTREAM_REJECTED is now UPSTREAM_FAILURE, and
PEER_DISCONNECT is split into DOWNSTREAM_DISCONNECT and UPSTREAM_DISCONNECT.
Enum numbers are unchanged so binary wire compatibility is preserved;
generated symbols and JSON names change.
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* docs(middleware): describe skip as opting out of inspection
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* feat(middleware): add body-phase block_delivery and skip_remaining actions
Body results may now stop delivery or opt out of inspecting the rest of the
response after a prefix. One HttpResponseBlockDelivery message is shared by
preflight and body results and documents the difference between blocking
before and after head commitment. Drop the field reservations, since nothing
in this contract has shipped, and renumber session_end to close the gap.
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* refactor(middleware): share HTTP body leaf messages across directions
HttpBodyUnit, HttpBodyPassThrough, HttpBodyTransform, HttpBodySkipRemaining,
and HttpBodyMode carry no response-specific semantics, so name them for reuse
by the streaming request hook. Envelopes, results, preflight, and
block_delivery stay response-specific because commitment semantics differ.
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* refactor(middleware): keep HTTP body leaf messages response-specific
Reverts the shared HttpBody* naming. A direction-specific payload such as a
response-only semantic mode would otherwise add unreachable variants to the
other direction or force a source-breaking fork after 0.1.0. The streaming
request hook defines its own HttpRequestBody* messages and copies the shape;
SDKs present a direction-neutral body handler over both.
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* docs(middleware): simplify response proto comments
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(middleware): reject undispatched response bindings
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* docs(middleware): simplify phase field comment
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* refactor(middleware): rename HTTP response preflight result
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* feat(middleware): add HTTP response trailer results
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* docs(middleware): define response block delivery
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* docs(middleware): define stage-local response body modes
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* docs(middleware): define final response body units
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* docs(middleware): define streaming response deferral
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* docs(middleware): defer whole-body accumulation timeout
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* docs(middleware): align response result diagnostics
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* test(middleware): cover upstream WebSocket disconnect
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(middleware): keep response streams unit-local
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* docs(middleware): trim disconnect compatibility note
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
---------
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* feat(middleware): broaden HTTP header mutation authority
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(middleware): protect response credential headers from mutation
Response middleware could write or remove Set-Cookie, WWW-Authenticate,
Authentication-Info, and Proxy-Authentication-Info, letting a stage plant
or strip credentials the sandbox client acts on. Protect them in both
directions, matching the request profile's treatment of Authorization and
Cookie, and reserve the x-openshell-credential prefix for responses too.
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(middleware): reject credential placeholder writes
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
---------
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(security): authenticate extension services
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* feat(extension-core): verify gateway JWTs
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* refactor(extension-core): keep inbound verification external
This should become an extension SDK package.
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(security): harden the extension authentication contract
Follow-up hardening on the alpha extension authentication mechanism.
Claim contract:
- Extension tokens carry an explicit `typ` of `openshell-ext+jwt`. They
share a signing key with sandbox-to-gateway admission tokens and were
otherwise separated by audience alone, so a verifier that neglects to
check `aud` could accept a gateway credential. The header is a second,
independent discriminator.
- Publish OIDC-shaped discovery at `/.well-known/openid-configuration`
so a service configured with only the gateway URL can learn the exact
expected issuer and the JWKS location. It is shaped, not compliant:
`issuer` is the gateway identity, not the serving URL.
Audience agreement:
- `MiddlewareManifest` and `InterceptorManifest` gain `expected_audience`.
The audience is otherwise configured independently on each side of the
boundary, where a mismatch surfaces only as an opaque authentication
failure on every call. OpenShell now compares the two and fails at
startup. An empty field keeps the check off for existing services.
Compatibility:
- Add `allow_insecure_transport` per registration. Enabling gateway JWT
signing previously made any plaintext endpoint a hard startup failure,
including the endpoint form used in our own documentation. The opt-out
attaches no credential, is refused by the gateway if a supervisor asks
for one, and warns at every startup.
- Make the transport requirement kind-aware. A middleware endpoint must
be reachable from every sandbox supervisor, so only interceptors may
use a gateway-local Unix socket.
Credential lifecycle:
- Replace the process-global slot map with a supervisor-owned
`ExtensionCredentialStore` shared explicitly across the gateway
connections the supervisor opens, removing test-order coupling.
- Rotate only when a credential is missing or has passed four fifths of
its lifetime. Configuration polling ran every ten seconds against
fifteen-minute credentials, so each poll re-ran gateway effective-policy
resolution and re-minted the gateway token.
- Bound credential minting per sandbox, since each request resolves the
caller's effective policy.
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* docs: record alpha extension authentication in RFC appendices
Restore the RFC 0009 and 0010 bodies to their accepted text and move
every extension-authentication update into appendices instead. An RFC
records a decision at a point in time; superseding detail belongs
alongside it rather than rewritten into it.
RFC 0009's appendix carries the shared contract: claims, authorization,
key distribution, the `allow_insecure_transport` replacement for the
body's `allow_insecure`, and residual risks. RFC 0010's records only
what differs for interceptors and links to it. The existing
protocol-extensions appendix, which parked the phase 2 transport
question, now points forward to what was built.
Also document the audience handshake, the discovery endpoint, the
`typ` requirement, and `jti` replay guidance in the extensibility and
gateway configuration pages, and correct the middleware transport
guidance: middleware endpoints must be reachable from sandbox
supervisors, so Unix sockets are not an option there.
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* refactor(extension-core): abstract extension server trust
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* docs(core): update middleware manifest example
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(extension-auth): preserve unsigned gateway compatibility
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(extension-auth): reject cross-domain token replay
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
---------
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
Establish the Phase 1 reference implementation proposed by RFC 0012
while retaining the existing Cargo and Mise workflows during evaluation.
- pin Bazel 9.1.1 and configure Bzlmod, rules_rs, LLVM, protobuf, and
Rust 1.95 toolchains
- import third-party crates from Cargo metadata and propagate the
workspace version into Bazel targets
- add library, binary, proc-macro, unit-test, and integration-test
targets across the supported Rust workspace crates and drivers
- generate protobuf Rust sources and descriptor sets under Bazel while
preserving Cargo-compatible generated-code imports
- annotate aws-lc-sys and zstd-sys native dependencies, build Z3 4.15.2
from source, and generate z3-sys bindings
- make CLI and procfs test fixtures available as explicit Bazel inputs
without relying on fixed host binary paths
- define optimized release targets for Linux x86_64 and aarch64 CLI,
sandbox, and gateway binaries, plus macOS aarch64 artifacts
- add Bazel, buildifier, and lcov to the Nix development environment
RFC: 0012 (rfc12 branch)
Refs: #2491
Signed-off-by: Simon Scatton <sscatton@nvidia.com>