Skip to content

Conversation

@michalskalski
Copy link
Contributor

What type of PR is this?

Feature - adds new API field and functionality

What this PR does / why we need it:

This PR adds support for the addIfAbsent header action in HTTPHeaderFilter, which adds headers only if they don't already exist. This maps to Envoy's ADD_IF_ABSENT action.

Use Case:

Set default headers (e.g., Content-Security-Policy, X-Frame-Options) at the gateway level that can be overridden by backend responses. Unlike add which appends to existing headers, or set which overwrites them, addIfAbsent is a no-op if the header is already present.

Changes:

  • Added AddIfAbsent field to HTTPHeaderFilter in api/v1alpha1/shared_types.go
  • Added AddIfAbsent field to IR AddHeader struct in internal/ir/xds.go
  • Updated translateHeaderModifier() in internal/gatewayapi/clienttrafficpolicy.go
  • Updated buildXdsAddedHeaders() in internal/xds/translator/route.go
  • Updated buildHeaderMutationRules() in internal/xds/translator/header_mutation.go
  • Added documentation in site/content/en/latest/tasks/traffic/http-response-headers.md
  • Added testdata files for Gateway API and XDS translator tests

Example usage:

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
  name: default-headers
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: Gateway
    name: eg
  headers:
    lateResponseHeaders:
      addIfAbsent:
        - name: "content-security-policy"
          value: "default-src 'self'"

Which issue(s) this PR fixes:

Fixes #7656

Release Notes: Yes

**What type of PR is this?**

Feature - adds new API field and functionality

**What this PR does / why we need it**:

This PR adds support for the `addIfAbsent` header action in `HTTPHeaderFilter`, which adds headers only if they don't already exist. This maps to Envoy's
[`ADD_IF_ABSENT`](https://www.envoyproxy.io/docs/envoy/v1.36.2/api-v3/config/core/v3/base.proto#enum-config-core-v3-headervalueoption-headerappendaction) action.

**Use Case:**

Set default headers (e.g., `Content-Security-Policy`, `X-Frame-Options`) at the gateway level that can be overridden by backend responses.
Unlike `add` which appends to existing headers, or `set` which overwrites them, `addIfAbsent` is a no-op if the header is already present.

**Changes:**

- Added `AddIfAbsent` field to `HTTPHeaderFilter` in `api/v1alpha1/shared_types.go`
- Added `AddIfAbsent` field to IR `AddHeader` struct in `internal/ir/xds.go`
- Updated `translateHeaderModifier()` in `internal/gatewayapi/clienttrafficpolicy.go`
- Updated `buildXdsAddedHeaders()` in `internal/xds/translator/route.go`
- Updated `buildHeaderMutationRules()` in `internal/xds/translator/header_mutation.go`
- Added documentation in `site/content/en/latest/tasks/traffic/http-response-headers.md`
- Added testdata files for Gateway API and XDS translator tests

**Example usage:**

```yaml
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
  name: default-headers
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: Gateway
    name: eg
  headers:
    lateResponseHeaders:
      addIfAbsent:
        - name: "content-security-policy"
          value: "default-src 'self'"
```

Which issue(s) this PR fixes:

Fixes envoyproxy#7656

Release Notes: Yes

Signed-off-by: Michal Skalski <michal@skalski.org>
@michalskalski michalskalski requested a review from a team as a code owner January 16, 2026 15:19
@netlify
Copy link

netlify bot commented Jan 16, 2026

Deploy Preview for cerulean-figolla-1f9435 canceled.

Name Link
🔨 Latest commit 7c234f2
🔍 Latest deploy log https://app.netlify.com/projects/cerulean-figolla-1f9435/deploys/696c3ce43563b400080febf1

@codecov
Copy link

codecov bot commented Jan 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.83%. Comparing base (d82eece) to head (7c234f2).
⚠️ Report is 7 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7978      +/-   ##
==========================================
+ Coverage   72.81%   72.83%   +0.01%     
==========================================
  Files         237      237              
  Lines       35475    35505      +30     
==========================================
+ Hits        25832    25859      +27     
- Misses       7801     7805       +4     
+ Partials     1842     1841       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Signed-off-by: Michal Skalski <michal@skalski.org>
Signed-off-by: Michal Skalski <michal@skalski.org>
Signed-off-by: Michal Skalski <michal@skalski.org>
@michalskalski
Copy link
Contributor Author

/retest

port: 10080
hostnames:
- "*"
headers:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we also add an example for earlyRequestHeaders

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added in 7c234f2

namespace: envoy-gateway
name: target-gateway-1
spec:
headers:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we also add an example for earlyRequestHeaders

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added in 7c234f2

@arkodg arkodg added this to the v1.7.0-rc.1 Release milestone Jan 17, 2026
@arkodg
Copy link
Contributor

arkodg commented Jan 17, 2026

hey PR looks great, added a minor comment to add 1 more test case to make sure this also works for earlyRequestHeaders

Signed-off-by: Michal Skalski <michal@skalski.org>
@zirain
Copy link
Member

zirain commented Jan 18, 2026

can you add release notes for this?

Copy link
Contributor

@arkodg arkodg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM thanks

@michalskalski
Copy link
Contributor Author

can you add release notes for this?

Added in release-notes/current.yaml:29. Happy to adjust the wording if needed.

@michalskalski
Copy link
Contributor Author

/retest

@zirain
Copy link
Member

zirain commented Jan 18, 2026

can you add release notes for this?

Added in release-notes/current.yaml:29. Happy to adjust the wording if needed.

my bad, I missed it.

@zirain zirain merged commit a658c6f into envoyproxy:main Jan 18, 2026
58 of 62 checks passed
@lboynton
Copy link
Contributor

Thanks @michalskalski, this is going to be really useful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support adding response header if not present in the ClientTrafficPolicy

4 participants