From 06952a4153a79c40f0a8edec2c710f6d9dcc0829 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 25 Sep 2026 14:34:59 +0000 Subject: [PATCH 1/2] [Automated] Draft docs (agentgateway): feat(controller): select the CA bundle key in AgentgatewayPolicy CA refs (+2 related) Signed-off-by: GitHub Action --- .../pages/security/backend-authn-aws-standalone.md | 4 ++++ assets/agw-docs/pages/security/backend-authn-aws.md | 4 ++++ .../main/documentation/llm/guardrails/overview.md | 6 ++++++ .../docs/kubernetes/main/release-notes/release-notes.md | 8 ++++++++ .../main/documentation/llm/prompt-guards/overview.md | 6 ++++++ 5 files changed, 28 insertions(+) diff --git a/assets/agw-docs/pages/security/backend-authn-aws-standalone.md b/assets/agw-docs/pages/security/backend-authn-aws-standalone.md index e55c6a093..100c13dde 100644 --- a/assets/agw-docs/pages/security/backend-authn-aws-standalone.md +++ b/assets/agw-docs/pages/security/backend-authn-aws-standalone.md @@ -56,6 +56,8 @@ backendAuth: serviceName: bedrock assumeRole: roleArn: arn:aws:iam::123456789012:role/agentgateway-bedrock +{{< version exclude-if="1.5.x" >}} externalId: tenant-a:prod/12345 +{{< /version >}} sessionName: expression: jwt.sub tags: @@ -70,6 +72,8 @@ backendAuth: | Field | Description | | -- | -- | | `assumeRole.roleArn` | Required ARN of the IAM role to assume. | +{{< version exclude-if="1.5.x" >}}| `assumeRole.externalId` | External ID to pass to STS when the role trust policy requires `sts:ExternalId`. The value must be 2-1224 characters and match `[\w+=,.@:/-]`. The value is part of the assumed-credential cache key. | +{{< /version >}} | `assumeRole.sessionName` | Session name (`RoleSessionName`) that appears in AWS CloudTrail and in the Cost and Usage Report. Either a static string, or `{expression: }`. Two to 64 characters, matching `[\w+=,.@-]`. Omit the field and AWS generates a random name. | | `assumeRole.tags` | Session tags that agentgateway passes to STS. Each tag sets `key`, plus exactly one of `value` for a static value or `expression` for a CEL expression. STS allows at most 50 tags for one role session. | diff --git a/assets/agw-docs/pages/security/backend-authn-aws.md b/assets/agw-docs/pages/security/backend-authn-aws.md index 3556e98d5..4d579fa4a 100644 --- a/assets/agw-docs/pages/security/backend-authn-aws.md +++ b/assets/agw-docs/pages/security/backend-authn-aws.md @@ -154,6 +154,8 @@ spec: serviceName: bedrock assumeRole: roleArn: arn:aws:iam::123456789012:role/agentgateway-bedrock +{{< version exclude-if="1.4.x,1.5.x" >}} externalId: tenant-a:prod/12345 +{{< /version >}} sessionNameExpression: jwt.sub tags: - key: team @@ -168,6 +170,8 @@ EOF | Field | Description | | -- | -- | | `assumeRole.roleArn` | Required ARN of the IAM role to assume. | +{{< version exclude-if="1.4.x,1.5.x" >}}| `assumeRole.externalId` | External ID to pass to STS when the role trust policy requires `sts:ExternalId`. The value must be 2-1224 characters and match `[\w+=,.@:/-]`. The value is part of the assumed-credential cache key. | +{{< /version >}} | `assumeRole.sessionName` | Static session name (`RoleSessionName`), which appears in AWS CloudTrail and in the Cost and Usage Report. Two to 64 characters, matching `[\w+=,.@-]`. Omit the field and AWS generates a random name. | | `assumeRole.sessionNameExpression` | CEL expression that the gateway evaluates against each request to produce the session name, such as `jwt.sub`. Cannot be combined with `sessionName`. | | `assumeRole.tags` | Session tags that the gateway passes to STS. Each tag sets `key`, plus exactly one of `value` for a static value or `expression` for a CEL expression. STS allows at most 50 tags for one role session. | diff --git a/content/docs/kubernetes/main/documentation/llm/guardrails/overview.md b/content/docs/kubernetes/main/documentation/llm/guardrails/overview.md index 608d7af44..b31048b6e 100644 --- a/content/docs/kubernetes/main/documentation/llm/guardrails/overview.md +++ b/content/docs/kubernetes/main/documentation/llm/guardrails/overview.md @@ -71,6 +71,12 @@ The values that `action` takes depend on the guard, because a regex guard can ma | `bedrockGuardrails` | `Reject`, `Audit` | `Reject` | | `googleModelArmor` | `Reject`, `Audit` | `Reject` | +## Provider failures {#provider-failures} + +Use `failureMode` on a custom webhook or external provider guard to choose what happens when the provider is unreachable or returns an error. The default is `FailClosed`, which rejects the request. Set `failureMode: FailOpen` on `webhook`, `openAIModeration`, `bedrockGuardrails`, or `googleModelArmor` to let the request continue. + +`action: Audit` changes only whether the gateway enforces the provider verdict. A provider error still follows `failureMode`, so an audit guard with `failureMode: FailClosed` rejects traffic when the provider call fails. + ## Audit mode {#audit} By default, a guard enforces the verdict that it reaches. A regex guard masks the content that matches, and an external guard rejects the request that its provider flags. Set `action: Audit` to make a guard observe instead. The guard still runs, and it still records what it detected in metrics and in the structured access log, but the content always passes through unchanged. diff --git a/content/docs/kubernetes/main/release-notes/release-notes.md b/content/docs/kubernetes/main/release-notes/release-notes.md index 15a902185..315a2ac73 100644 --- a/content/docs/kubernetes/main/release-notes/release-notes.md +++ b/content/docs/kubernetes/main/release-notes/release-notes.md @@ -106,3 +106,11 @@ Now, the `destination.address`, `destination.port`, and `destination.hostname` C `destination.hostname` is set only on Gateway listeners with `protocol: TLS`. It is unset on HTTP and HTTPS listeners, even when the client sends SNI, and for clients that send no SNI. A `Require` policy that references it denies every such connection, so apply it only to Gateways whose listeners use `protocol: TLS`. For an example, see [Restrict network access by TLS SNI]({{< link-hextra path="/documentation/security/authorization/#restrict-network-access-by-tls-sni" >}}). + +#### Backend authentication and guardrail controls {#v16-backend-auth-guardrail-controls} + +Backend TLS CA certificate references can now set `key` to read a CA bundle from a Secret or ConfigMap key other than `ca.crt`. Omitting the field still reads `ca.crt`. + +AWS backend authentication can now set `assumeRole.externalId` when an AWS Security Token Service (STS) AssumeRole trust policy requires `sts:ExternalId`. The value is validated against the STS length and character limits and is part of the assumed-credential cache key. + +Cloud provider guardrails can now set `failureMode` to choose whether provider errors fail open or closed. These guardrails now fail closed by default instead of allowing traffic on provider errors. diff --git a/content/docs/standalone/main/documentation/llm/prompt-guards/overview.md b/content/docs/standalone/main/documentation/llm/prompt-guards/overview.md index d4ef869d7..0927de501 100644 --- a/content/docs/standalone/main/documentation/llm/prompt-guards/overview.md +++ b/content/docs/standalone/main/documentation/llm/prompt-guards/overview.md @@ -72,6 +72,12 @@ The values that `action` takes depend on the guard, because a regex guard can ma | `googleModelArmor` | `reject`, `audit` | `reject` | | `azureContentSafety` | `reject`, `audit` | `reject` | +## Provider failures {#provider-failures} + +Use `failureMode` on a custom webhook or external provider guard to choose what happens when the provider is unreachable or returns an error. The default is `failClosed`, which rejects the request. Set `failureMode: failOpen` on `webhook`, `openAIModeration`, `bedrockGuardrails`, `googleModelArmor`, or `azureContentSafety` to let the request continue. + +`action: audit` changes only whether the gateway enforces the provider verdict. A provider error still follows `failureMode`, so an audit guard with `failureMode: failClosed` rejects traffic when the provider call fails. + ## Audit mode {#audit} By default, a guard enforces the verdict that it reaches. A regex guard masks the content that matches, and an external guard rejects the request that its provider flags. Set `action: audit` to make a guard observe instead. The guard still runs, and it still records what it detected in metrics and in the structured access log, but the content always passes through unchanged. From fcffc1870856eacb0295f6865f18e252f3a27da3 Mon Sep 17 00:00:00 2001 From: Kristin Brown Date: Fri, 25 Sep 2026 11:26:05 -0400 Subject: [PATCH 2/2] Tweaks Signed-off-by: Kristin Brown --- .../security/backend-authn-aws-standalone.md | 4 ---- .../pages/security/backend-authn-aws.md | 4 ---- .../documentation/llm/guardrails/overview.md | 12 +++++------ .../main/release-notes/release-notes.md | 20 +++++++++++++++---- .../llm/prompt-guards/overview.md | 12 +++++------ .../main/release-notes/release-notes.md | 12 +++++++++++ 6 files changed, 40 insertions(+), 24 deletions(-) diff --git a/assets/agw-docs/pages/security/backend-authn-aws-standalone.md b/assets/agw-docs/pages/security/backend-authn-aws-standalone.md index 100c13dde..e55c6a093 100644 --- a/assets/agw-docs/pages/security/backend-authn-aws-standalone.md +++ b/assets/agw-docs/pages/security/backend-authn-aws-standalone.md @@ -56,8 +56,6 @@ backendAuth: serviceName: bedrock assumeRole: roleArn: arn:aws:iam::123456789012:role/agentgateway-bedrock -{{< version exclude-if="1.5.x" >}} externalId: tenant-a:prod/12345 -{{< /version >}} sessionName: expression: jwt.sub tags: @@ -72,8 +70,6 @@ backendAuth: | Field | Description | | -- | -- | | `assumeRole.roleArn` | Required ARN of the IAM role to assume. | -{{< version exclude-if="1.5.x" >}}| `assumeRole.externalId` | External ID to pass to STS when the role trust policy requires `sts:ExternalId`. The value must be 2-1224 characters and match `[\w+=,.@:/-]`. The value is part of the assumed-credential cache key. | -{{< /version >}} | `assumeRole.sessionName` | Session name (`RoleSessionName`) that appears in AWS CloudTrail and in the Cost and Usage Report. Either a static string, or `{expression: }`. Two to 64 characters, matching `[\w+=,.@-]`. Omit the field and AWS generates a random name. | | `assumeRole.tags` | Session tags that agentgateway passes to STS. Each tag sets `key`, plus exactly one of `value` for a static value or `expression` for a CEL expression. STS allows at most 50 tags for one role session. | diff --git a/assets/agw-docs/pages/security/backend-authn-aws.md b/assets/agw-docs/pages/security/backend-authn-aws.md index 4d579fa4a..3556e98d5 100644 --- a/assets/agw-docs/pages/security/backend-authn-aws.md +++ b/assets/agw-docs/pages/security/backend-authn-aws.md @@ -154,8 +154,6 @@ spec: serviceName: bedrock assumeRole: roleArn: arn:aws:iam::123456789012:role/agentgateway-bedrock -{{< version exclude-if="1.4.x,1.5.x" >}} externalId: tenant-a:prod/12345 -{{< /version >}} sessionNameExpression: jwt.sub tags: - key: team @@ -170,8 +168,6 @@ EOF | Field | Description | | -- | -- | | `assumeRole.roleArn` | Required ARN of the IAM role to assume. | -{{< version exclude-if="1.4.x,1.5.x" >}}| `assumeRole.externalId` | External ID to pass to STS when the role trust policy requires `sts:ExternalId`. The value must be 2-1224 characters and match `[\w+=,.@:/-]`. The value is part of the assumed-credential cache key. | -{{< /version >}} | `assumeRole.sessionName` | Static session name (`RoleSessionName`), which appears in AWS CloudTrail and in the Cost and Usage Report. Two to 64 characters, matching `[\w+=,.@-]`. Omit the field and AWS generates a random name. | | `assumeRole.sessionNameExpression` | CEL expression that the gateway evaluates against each request to produce the session name, such as `jwt.sub`. Cannot be combined with `sessionName`. | | `assumeRole.tags` | Session tags that the gateway passes to STS. Each tag sets `key`, plus exactly one of `value` for a static value or `expression` for a CEL expression. STS allows at most 50 tags for one role session. | diff --git a/content/docs/kubernetes/main/documentation/llm/guardrails/overview.md b/content/docs/kubernetes/main/documentation/llm/guardrails/overview.md index b31048b6e..f1860b9bd 100644 --- a/content/docs/kubernetes/main/documentation/llm/guardrails/overview.md +++ b/content/docs/kubernetes/main/documentation/llm/guardrails/overview.md @@ -71,12 +71,6 @@ The values that `action` takes depend on the guard, because a regex guard can ma | `bedrockGuardrails` | `Reject`, `Audit` | `Reject` | | `googleModelArmor` | `Reject`, `Audit` | `Reject` | -## Provider failures {#provider-failures} - -Use `failureMode` on a custom webhook or external provider guard to choose what happens when the provider is unreachable or returns an error. The default is `FailClosed`, which rejects the request. Set `failureMode: FailOpen` on `webhook`, `openAIModeration`, `bedrockGuardrails`, or `googleModelArmor` to let the request continue. - -`action: Audit` changes only whether the gateway enforces the provider verdict. A provider error still follows `failureMode`, so an audit guard with `failureMode: FailClosed` rejects traffic when the provider call fails. - ## Audit mode {#audit} By default, a guard enforces the verdict that it reaches. A regex guard masks the content that matches, and an external guard rejects the request that its provider flags. Set `action: Audit` to make a guard observe instead. The guard still runs, and it still records what it detected in metrics and in the structured access log, but the content always passes through unchanged. @@ -113,6 +107,12 @@ spec: EOF ``` +## Provider failures + +Set `failureMode` on a `webhook`, `openAIModeration`, `bedrockGuardrails`, or `googleModelArmor` guard to choose what happens when the provider is unreachable or returns an error. The default, `FailClosed`, rejects the request or response. Set `failureMode: FailOpen` to let the content continue unchanged instead. + +A provider error is not a verdict, so `action: Audit` does not change how an error is handled. An audit guard with the default `failureMode` still rejects traffic when the provider call fails. + ## Guard scope {#scope} A request guard does not inspect the whole request. By default, a guard reads the system prompt and the text of regular user and assistant messages. Tool call content is left alone, so a Social Security number that a tool returns to the model reaches the provider unmasked. diff --git a/content/docs/kubernetes/main/release-notes/release-notes.md b/content/docs/kubernetes/main/release-notes/release-notes.md index 315a2ac73..975d1aa22 100644 --- a/content/docs/kubernetes/main/release-notes/release-notes.md +++ b/content/docs/kubernetes/main/release-notes/release-notes.md @@ -107,10 +107,22 @@ Now, the `destination.address`, `destination.port`, and `destination.hostname` C For an example, see [Restrict network access by TLS SNI]({{< link-hextra path="/documentation/security/authorization/#restrict-network-access-by-tls-sni" >}}). -#### Backend authentication and guardrail controls {#v16-backend-auth-guardrail-controls} +#### Custom key for CA certificate references {#v16-ca-cert-ref-key} -Backend TLS CA certificate references can now set `key` to read a CA bundle from a Secret or ConfigMap key other than `ca.crt`. Omitting the field still reads `ca.crt`. + -AWS backend authentication can now set `assumeRole.externalId` when an AWS Security Token Service (STS) AssumeRole trust policy requires `sts:ExternalId`. The value is validated against the STS length and character limits and is part of the assumed-credential cache key. +A `caCertificateRefs` entry in the backend TLS settings of an {{< reuse "agw-docs/snippets/policy.md" >}}, {{< reuse "agw-docs/snippets/backend.md" >}}, or {{< reuse "agw-docs/snippets/agentgatewaymodel.md" >}} now takes an optional `key` field. Set it to read the CA bundle from a key other than `ca.crt` in the referenced ConfigMap or Secret, such as a key that trust-manager or an external secret store writes. Omit the field to keep reading `ca.crt`. -Cloud provider guardrails can now set `failureMode` to choose whether provider errors fail open or closed. These guardrails now fail closed by default instead of allowing traffic on provider errors. +The field does not apply to a BackendTLSPolicy or to the `frontendValidation` field of a Gateway listener, which still read `ca.crt`. For an example, see [CA certificate in a Secret]({{< link-hextra path="/documentation/security/backendtls/#secret-ca" >}}). + +### LLM {#v16-features-llm} + +#### Failure mode for provider guardrails {#v16-guardrail-failure-mode} + + + +The `failureMode` field, which was previously available only on `webhook` guards, is now available on `openAIModeration`, `bedrockGuardrails`, and `googleModelArmor` guards. The field sets what happens when the provider is unreachable or returns an error. The default, `FailClosed`, rejects the request or response. Set `failureMode: FailOpen` to let the content continue unchanged instead. + +For most traffic, the default keeps the 1.5.x behavior, because a provider error already rejected the request or response. Two paths change. On a realtime WebSocket connection, and for streaming responses that are evaluated as they arrive, a provider error from one of these guards used to let the content through. It now rejects the content, unless you set `failureMode: FailOpen`. + +For more information, see [Provider failures]({{< link-hextra path="/documentation/llm/guardrails/overview/#provider-failures" >}}). diff --git a/content/docs/standalone/main/documentation/llm/prompt-guards/overview.md b/content/docs/standalone/main/documentation/llm/prompt-guards/overview.md index 0927de501..766421705 100644 --- a/content/docs/standalone/main/documentation/llm/prompt-guards/overview.md +++ b/content/docs/standalone/main/documentation/llm/prompt-guards/overview.md @@ -72,12 +72,6 @@ The values that `action` takes depend on the guard, because a regex guard can ma | `googleModelArmor` | `reject`, `audit` | `reject` | | `azureContentSafety` | `reject`, `audit` | `reject` | -## Provider failures {#provider-failures} - -Use `failureMode` on a custom webhook or external provider guard to choose what happens when the provider is unreachable or returns an error. The default is `failClosed`, which rejects the request. Set `failureMode: failOpen` on `webhook`, `openAIModeration`, `bedrockGuardrails`, `googleModelArmor`, or `azureContentSafety` to let the request continue. - -`action: audit` changes only whether the gateway enforces the provider verdict. A provider error still follows `failureMode`, so an audit guard with `failureMode: failClosed` rejects traffic when the provider call fails. - ## Audit mode {#audit} By default, a guard enforces the verdict that it reaches. A regex guard masks the content that matches, and an external guard rejects the request that its provider flags. Set `action: audit` to make a guard observe instead. The guard still runs, and it still records what it detected in metrics and in the structured access log, but the content always passes through unchanged. @@ -110,6 +104,12 @@ llm: action: audit ``` +## Provider failures + +Set `failureMode` on a `webhook`, `openAIModeration`, `bedrockGuardrails`, `googleModelArmor`, or `azureContentSafety` guard to choose what happens when the provider is unreachable or returns an error. The default, `failClosed`, rejects the request or response. Set `failureMode: failOpen` to let the content continue unchanged instead. + +A provider error is not a verdict, so `action: audit` does not change how an error is handled. An audit guard with the default `failureMode` still rejects traffic when the provider call fails. + ## Guard scope {#scope} A request guard does not inspect the whole request. By default, a guard reads the system prompt and the text of regular user and assistant messages. Tool call content is left alone, so a Social Security number that a tool returns to the model reaches the provider unmasked. diff --git a/content/docs/standalone/main/release-notes/release-notes.md b/content/docs/standalone/main/release-notes/release-notes.md index a705f42f5..286483b60 100644 --- a/content/docs/standalone/main/release-notes/release-notes.md +++ b/content/docs/standalone/main/release-notes/release-notes.md @@ -121,3 +121,15 @@ Now, the `destination.address`, `destination.port`, and `destination.hostname` C `destination.hostname` is set only on listeners with the `TLS` protocol. It is unset on HTTP and HTTPS listeners, even when the client sends SNI, and for clients that send no SNI. A `require` rule that references it rejects every such connection, so apply it only to `TLS` listeners. For the variables and an example, see [Require TLS SNI]({{< link-hextra path="/documentation/configuration/security/network-authz/#require-tls-sni" >}}). + +### LLM {#v16-features-llm} + +#### Failure mode for provider guardrails {#v16-guardrail-failure-mode} + + + +The `failureMode` field, which was previously available only on `webhook` guards, is now available on `openAIModeration`, `bedrockGuardrails`, `googleModelArmor`, and `azureContentSafety` guards. The field sets what happens when the provider is unreachable or returns an error. The default, `failClosed`, rejects the request or response. Set `failureMode: failOpen` to let the content continue unchanged instead. + +For most traffic, the default keeps the 1.5.x behavior, because a provider error already rejected the request or response. Two paths change. On a realtime WebSocket connection, and for streaming responses that are evaluated as they arrive, a provider error from one of these guards used to let the content through. It now rejects the content, unless you set `failureMode: failOpen`. + +For more information, see [Provider failures]({{< link-hextra path="/documentation/llm/prompt-guards/overview/#provider-failures" >}}).