Forwarding Signals with Dynamic Label Interpolation
Overview
Domain expertise for forwarding AWS WAF signals to the origin with a single rule using dynamic label
interpolation, instead of one custom rule per label. Covers the ${namespace:} placeholder syntax
that resolves at evaluation time, the synthetic values for client IP and TLS fingerprints, the
10-placeholder-per-string limit and the fully-qualified-namespace rule, and the mandatory
inbound-header-stripping companion.
Does not cover turning Bot Control on, collapsing labels into a confidence signal (its own reference), or the application's response. Those are separate references.
Execute commands using the AWS MCP server when connected (sandboxed execution, audit logging, observability). Fall back to the AWS CLI otherwise.
Table of Contents
- Overview
- Workflow
- One rule forwards a whole namespace
- Synthetic values
- Limits and the fully-qualified-namespace rule
- Strip inbound headers
- Troubleshooting
- Procedure
- Security Considerations
- Additional Resources
Workflow
To forward signals with interpolation end to end, follow the procedure exactly. See the Procedure section below.
The procedure covers:
- Adding one custom-header rule that interpolates a label namespace
- Adding synthetic values (client IP, TLS fingerprints, request ID) where wanted
- Staying within the placeholder limit and namespace rules
- Adding the inbound-header-stripping rule
One rule forwards a whole namespace
The one-rule-per-label approach is unmaintainable; every new managed label means another web ACL edit. Interpolation forwards an entire namespace in a single custom header.
Constraints:
- You MUST use the
${namespace:}placeholder, which resolves at evaluation time, to forward a whole namespace in one rule rather than adding a rule per label - You SHOULD note a single label resolves to a terminal value, multiple labels to a comma-separated list, and no match to an empty string
Synthetic values
Interpolation exposes values that resolve from request context, not the label store, so the customer does not have to reconstruct them downstream.
Constraints:
- You SHOULD forward
${awswaf:ip:}(client IP),${awswaf:ja3:}and${awswaf:ja4:}(TLS fingerprints), and${awswaf:request_id:}through interpolation when the origin needs them, rather than parsing them by hand
Limits and the fully-qualified-namespace rule
Two traps cause interpolation to not resolve as expected.
Constraints:
- You MUST keep to at most 10 placeholders per string value
- You MUST use the fully qualified namespace in interpolation for custom labels, even though label-match statements accept the short name
Strip inbound headers
The forwarded values arrive as x-amzn-waf-* headers, which an attacker can set inbound unless
they are stripped first.
Constraints:
- You MUST pair this workflow with the inbound-header-stripping rule (see stripping-inbound-waf-headers-before-trusting-them), placed before the forwarding rule
- You MUST forward the
x-amzn-waf-*signals only to an HTTPS-only origin, and the application MUST validate the origin's TLS certificate, so the signals are not exposed in cleartext. You SHOULD use AWS Certificate Manager (ACM) to provision and manage the origin's TLS certificate (for example on an Application Load Balancer), so the certificate is validated and automatically renewed
Troubleshooting
A custom label does not resolve in interpolation
The short name was used. Use the fully qualified namespace (Limits and the fully-qualified-namespace rule).
A header value is truncated or missing placeholders
The string exceeds 10 placeholders. Split the forwarding across values (Limits and the fully-qualified-namespace rule).
The origin receives a spoofed forwarded value
No inbound stripping rule is in place. Add it before the forwarding rule (Strip inbound headers).
Procedure
Overview
This procedure adds an interpolation-based forwarding rule, strips spoofed inbound headers, and surfaces the console link.
Parameters
- web_acl_name, web_acl_id, scope (required): Identify the web ACL.
- namespace (required): The label namespace to forward.
- synthetic_values (optional): Which of client IP, JA3, JA4, request ID to include.
Constraints for parameter acquisition:
- You MUST ask for all required parameters upfront in a single prompt
- You MUST confirm the labeling rules that produce the namespace run before the forwarding rule
Steps
1. Verify dependencies
Constraints:
- You MUST confirm credentials with
aws sts get-caller-identity - You MUST confirm the labels to forward are actually being produced by an earlier rule or group
2. Add the interpolation forwarding rule
Constraints:
You MUST add a custom-header rule that interpolates the namespace with
${namespace:}, staying within 10 placeholders per string and using the fully qualified namespace for custom labelsYou MUST fetch the current
LockTokenbeforeupdate-web-acland pass the full rule setYou MUST preserve the web ACL's existing
DefaultActionfrom theget-web-aclresponse and pass it back as{default_action}; do not assumeAllow={}, since that would silently open all unmatched traffic on a web ACL whose default action isBlock. For example, a Count rule that interpolates the namespace into a custom header sent to the origin:aws wafv2 get-web-acl --name {web_acl_name} --scope {scope} --id {web_acl_id} --region {region} aws wafv2 update-web-acl --name {web_acl_name} --scope {scope} --id {web_acl_id} \ --lock-token {lock_token} --default-action {default_action} \ --rules '[{"Name":"ForwardBotCategory","Priority":10,"Action":{"Count":{"CustomRequestHandling":{"InsertHeaders":[{"Name":"x-amzn-waf-bot-category","Value":"${awswaf:managed:aws:bot-control:bot:category:}"}]}}},"Statement":{"LabelMatchStatement":{"Scope":"NAMESPACE","Key":"awswaf:managed:aws:bot-control:bot:category:"}},"VisibilityConfig":{"SampledRequestsEnabled":true,"CloudWatchMetricsEnabled":true,"MetricName":"ForwardBotCategory"}}]' \ --visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName={web_acl_name} \ --region {region}
3. Strip inbound headers and surface the console link
Constraints:
You MUST add the inbound
x-amzn-waf-*stripping rule before the forwarding ruleYou MUST present the web ACL console link and tell the customer to confirm the rule order:
https://us-east-1.console.aws.amazon.com/wafv2/homev2/web-acls?region={region}
Example
Example input
{
"web_acl_name": "example-webacl",
"web_acl_id": "abc",
"scope": "REGIONAL",
"namespace": "awswaf:managed:aws:bot-control:bot:category:",
"synthetic_values": ["ip", "ja4"]
}Example output
Added one rule forwarding the bot-category namespace plus ${awswaf:ip:} and ${awswaf:ja4:} to the origin.
Added an inbound x-amzn-waf-* strip rule before it.
Open the web ACL and confirm the rule order:
https://us-east-1.console.aws.amazon.com/wafv2/homev2/web-acls?region=us-east-1Troubleshooting
A custom label does not resolve
Use the fully qualified namespace (Step 2).
Placeholders missing from the header
The string exceeds 10 placeholders. Split across values (Step 2).
Security Considerations
This procedure modifies a security control, so misconfiguration directly weakens the application's defenses.
- Least-privilege IAM. You MUST grant only the specific
wafv2:actions a task needs (for examplewafv2:GetWebACLandwafv2:UpdateWebACL) rather thanwafv2:*or theAWSWAFFullAccessmanaged policy. - Ephemeral credentials. You MUST use IAM roles with temporary credentials (such as an EC2 instance profile, SSO session, or
aws sts assume-role) rather than long-lived IAM user access keys when running these WAF CLI commands. - Monitor configuration changes. You SHOULD enable AWS CloudTrail on
wafv2management events and set CloudWatch alarms on critical web ACL configuration changes (such asDeleteWebACLandUpdateWebACLrule removals) and on the web ACL'sBlockedRequestsandCountedRequestsmetrics, so rule changes and sudden spikes in blocked or counted traffic are detected. - Header-spoofing risk. Any
x-amzn-waf-*signal forwarded to the origin can be forged inbound. You MUST add the inbound-header-stripping rule whenever a signal or client IP is forwarded (see stripping-inbound-waf-headers-before-trusting-them); without it the origin trusts a spoofable value. - Encrypted transport. You MUST forward the signal only to an HTTPS-only origin and the application MUST validate the origin's TLS certificate, so the signal is not exposed in cleartext. You SHOULD use AWS Certificate Manager (ACM) to provision and manage the origin's TLS certificate (for example on an Application Load Balancer), so the certificate is validated and automatically renewed.
- Defense in depth. You SHOULD treat the forwarded signal as one input among several, not a sole gate; over-relying on a single signal without defense in depth leaves the application exposed if the signal is evaded or degraded.