From dfca6f638e9a90311ec4627765b53e07fc73c6bb Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Tue, 13 Oct 2026 10:33:58 +0000 Subject: [PATCH] =?UTF-8?q?[Automated]=20Draft=20docs=20(kagent):=20fix:?= =?UTF-8?q?=20make=20push=20notification=20JWT=20signing=20optional=20with?= =?UTF-8?q?=20operator-managed=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: GitHub Action --- .../operations/operational-considerations.md | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/docs-site/content/kagent/1.x/operations/operational-considerations.md b/docs-site/content/kagent/1.x/operations/operational-considerations.md index b64da518..80a00847 100644 --- a/docs-site/content/kagent/1.x/operations/operational-considerations.md +++ b/docs-site/content/kagent/1.x/operations/operational-considerations.md @@ -91,6 +91,49 @@ Leader election keeps the replicas from conflicting. One replica holds a Kuberne PostgreSQL supports multiple controller replicas without further configuration. The bundled instance is still a single pod backed by one PVC, so an installation that runs several controllers for availability, against a bundled database, has only moved the single point of failure. +## Sign push notification callbacks + +Agent-to-Agent (A2A) push notifications are unsigned by default. Callbacks include no `Authorization` header unless you provide an Ed25519 signing key. Without a key, push notifications still work, and the JSON Web Key Sets (JWKS) endpoint returns 404. To let receivers verify callbacks, store one unencrypted PKCS#8 PEM key in a Kubernetes Secret and reference the Secret in Helm. + +1. Generate the signing key once. + ```bash + openssl genpkey -algorithm ED25519 -out private-key.pem + ``` + +2. Store the signing key in the kagent namespace. The Secret must contain a `private-key.pem` key. + ```bash + kubectl create secret generic kagent-push-signing -n kagent \ + --from-file=private-key.pem + ``` + +3. Add the Secret name and issuer to your `kagent.yaml` Helm values file. + ```yaml + controller: + push: + signing: + secretName: kagent-push-signing + issuer: https://kagent.example.com + ``` + + | Setting | Description | + | ------- | ----------- | + | `controller.push.signing.secretName` | Name of the Secret that contains `private-key.pem`. Leave empty to send push notifications without JSON Web Token (JWT) authentication. Helm references the Secret that you provide and does not generate or manage signing keys. An invalid key prevents controller startup. | + | `controller.push.signing.issuer` | Stable URL that webhook receivers trust as the JWT issuer. If empty, `controller.push.signing.issuer` uses `ui.externalUrl`, then the in-cluster A2A gateway URL. | + +4. Apply the values to the kagent Helm release. + ```bash + helm upgrade kagent \ + {{< reuse "kagent-docs/snippets/helm-path.md" >}}/{{< reuse "kagent-docs/snippets/helm-kagent.md" >}} \ + --version {{< reuse "kagent-docs/versions/kagent.md" >}} \ + --namespace kagent \ + --reuse-values \ + --values kagent.yaml + ``` + +When a signing key is configured, each callback attempt includes a fresh five-minute Ed25519 JWT as `Authorization: Bearer `. The `/.well-known/jwks.json` endpoint publishes the public key. + +All controller replicas must use the same key. After key rotation, restart all controller pods together so that replicas do not publish different JSON Web Key Sets. + ## Reserve node pools for Workers {{< gloss "Worker" >}}Workers{{< /gloss >}} hold running {{< gloss "Actor" >}}Actors{{< /gloss >}}. An Actor that loses its node before it suspends loses its conversation, so the node pools that run Workers need stricter rules than the rest of the cluster.