feat: add request-state key rotation (#1128)
* feat: add request-state key rotation * docs: streamline request-state codec documentation * fix: harden request-state fallback verification * refactor: refine request-state keyring API * docs: make request-state rotation guidance self-contained * docs: streamline request-state keyring rustdocs * test: streamline request-state keyring coverage * docs: restore request-state key rotation doctest * chore: remove manual changelog entry
This commit is contained in:
parent
12db02833f
commit
3ef34e64e7
2 changed files with 897 additions and 61 deletions
20
README.md
20
README.md
|
|
@ -1363,11 +1363,21 @@ async fn call_tool(&self, request: CallToolRequestParams, _ctx: RequestContext<R
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
> **`requestState` is untrusted.** The client echoes it back verbatim, so a
|
> **`requestState` is untrusted.** [SEP-2322 requires servers to validate
|
||||||
> stateless server that stores meaningful data in it MUST verify integrity
|
> it](https://modelcontextprotocol.io/seps/2322-MRTR#protocol-requirements-for-ephemeral-workflow)
|
||||||
> first. Enable the `request-state` feature and use `RequestStateCodec` to seal
|
> because the client echoes it back verbatim. A stateless server that stores
|
||||||
> and open it (HMAC-tagged), or keep state server-side and use `requestState`
|
> meaningful data in it MUST verify integrity first. Enable the `request-state`
|
||||||
> only as an opaque handle.
|
> feature and use `RequestStateCodec` to seal and open it (HMAC-tagged), or keep
|
||||||
|
> state server-side and use `requestState` only as an opaque handle.
|
||||||
|
|
||||||
|
For multi-replica deployments, use `RequestStateCodec::new_with_keyring` to
|
||||||
|
rotate signing keys without invalidating in-flight requests:
|
||||||
|
|
||||||
|
1. Deploy the old and new keys everywhere, continuing to emit `rs1` with the
|
||||||
|
old key via `with_rs1_signing("old")`.
|
||||||
|
2. Start emitting `rs2` with the new key while retaining the old key via
|
||||||
|
`with_rs1_fallback("old")`.
|
||||||
|
3. After the maximum `requestState` lifetime has elapsed, remove the old key.
|
||||||
|
|
||||||
### Client-side
|
### Client-side
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue