config: add rewrite_response_headers option (#1961)

* add lua script to rewrite response headers

* add policy config

* update docs
This commit is contained in:
Caleb Doxsey 2021-03-05 09:40:17 -07:00 committed by GitHub
parent b6ec01f377
commit 7f6107051f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 348 additions and 35 deletions

View file

@ -148,6 +148,16 @@ type Policy struct {
SubPolicies []SubPolicy `mapstructure:"sub_policies" yaml:"sub_policies,omitempty" json:"sub_policies,omitempty"` SubPolicies []SubPolicy `mapstructure:"sub_policies" yaml:"sub_policies,omitempty" json:"sub_policies,omitempty"`
EnvoyOpts *envoy_config_cluster_v3.Cluster `mapstructure:"_envoy_opts" yaml:"-" json:"-"` EnvoyOpts *envoy_config_cluster_v3.Cluster `mapstructure:"_envoy_opts" yaml:"-" json:"-"`
// RewriteResponseHeaders rewrites response headers. This can be used to change the Location header.
RewriteResponseHeaders []RewriteHeader `mapstructure:"rewrite_response_headers" yaml:"rewrite_response_headers,omitempty" json:"rewrite_response_headers,omitempty"` //nolint
}
// RewriteHeader is a policy configuration option to rewrite an HTTP header.
type RewriteHeader struct {
Header string `mapstructure:"header" yaml:"header" json:"header"`
Prefix string `mapstructure:"prefix" yaml:"prefix,omitempty" json:"prefix,omitempty"`
Value string `mapstructure:"value" yaml:"value,omitempty" json:"value,omitempty"`
} }
// A SubPolicy is a protobuf Policy within a protobuf Route. // A SubPolicy is a protobuf Policy within a protobuf Route.

View file

@ -1294,6 +1294,30 @@ Remove Request Headers allows you to remove given request headers. This can be u
``` ```
### Rewrite Response Headers
- Config File Key: `rewrite_response_headers`
- Type: `object`
- Optional
- Example: `[{ "header": "Location", "prefix": "http://localhost:8000/two/", "value": "http://frontend/one/" }]`
Rewrite Response Headers allows you to modify response headers before they are returned to the client. The `header` field will match the HTTP header name, and `prefix` will be replaced with `value`. For example, if the downstream server returns a header:
```text
Location: http://localhost:8000/two/some/path/
```
And the policy has this config:
```yaml
rewrite_response_headers:
- header: Location
prefix: http://localhost:8000/two/
value: http://frontend/one/
```
The browser would be redirected to: `http://frontend/one/some/path/`. This is similar to nginx's [`proxy_redirect` option](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect), but can be used for any header.
### Redirect ### Redirect
- `yaml`/`json` setting: 'redirect' - `yaml`/`json` setting: 'redirect'
- Type: object - Type: object

View file

@ -1427,6 +1427,30 @@ settings:
- X-Email - X-Email
- X-Username - X-Username
``` ```
- name: "Rewrite Response Headers"
keys: ["rewrite_response_headers"]
attributes: |
- Config File Key: `rewrite_response_headers`
- Type: `object`
- Optional
- Example: `[{ "header": "Location", "prefix": "http://localhost:8000/two/", "value": "http://frontend/one/" }]`
doc: |
Rewrite Response Headers allows you to modify response headers before they are returned to the client. The `header` field will match the HTTP header name, and `prefix` will be replaced with `value`. For example, if the downstream server returns a header:
```text
Location: http://localhost:8000/two/some/path/
```
And the policy has this config:
```yaml
rewrite_response_headers:
- header: Location
prefix: http://localhost:8000/two/
value: http://frontend/one/
```
The browser would be redirected to: `http://frontend/one/some/path/`. This is similar to nginx's [`proxy_redirect` option](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect), but can be used for any header.
- name: "Redirect" - name: "Redirect"
keys: ["redirect"] keys: ["redirect"]
attributes: | attributes: |

1
go.mod
View file

@ -56,6 +56,7 @@ require (
github.com/spf13/viper v1.7.1 github.com/spf13/viper v1.7.1
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80
github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da
go.opencensus.io v0.23.0 go.opencensus.io v0.23.0
go.uber.org/zap v1.16.0 go.uber.org/zap v1.16.0
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83

3
go.sum
View file

@ -618,6 +618,8 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da h1:NimzV1aGyq29m5ukMK0AMWEhFaL/lrEOaephfuoiARg=
github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da/go.mod h1:E1AXubJBdNmFERAOucpDIxNzeGfLzg0mYh+UfMWdChA=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
@ -780,6 +782,7 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View file

@ -0,0 +1,28 @@
function replace_prefix(str, prefix, value)
return str:gsub("^"..prefix, value)
end
function envoy_on_request(request_handle)
end
function envoy_on_response(response_handle)
local headers = response_handle:headers()
local metadata = response_handle:metadata()
-- should be in the form:
-- [{
-- "header":"Location",
-- "prefix":"http://localhost:8000/two/",
-- "value":"http://frontend/one/"
-- }]
local rewrite_response_headers = metadata:get("rewrite_response_headers")
if rewrite_response_headers then
for _, obj in pairs(rewrite_response_headers) do
local hdr = headers:get(obj.header)
if hdr ~= nil then
local newhdr = replace_prefix(hdr, obj.prefix, obj.value)
headers:replace(obj.header, newhdr)
end
end
end
end

View file

@ -373,6 +373,9 @@ func (srv *Server) buildMainHTTPConnectionManagerFilter(
removeImpersonateHeadersLua := marshalAny(&envoy_extensions_filters_http_lua_v3.Lua{ removeImpersonateHeadersLua := marshalAny(&envoy_extensions_filters_http_lua_v3.Lua{
InlineCode: luascripts.RemoveImpersonateHeaders, InlineCode: luascripts.RemoveImpersonateHeaders,
}) })
rewriteHeadersLua := marshalAny(&envoy_extensions_filters_http_lua_v3.Lua{
InlineCode: luascripts.RewriteHeaders,
})
filters := []*envoy_http_connection_manager.HttpFilter{ filters := []*envoy_http_connection_manager.HttpFilter{
{ {
@ -399,6 +402,12 @@ func (srv *Server) buildMainHTTPConnectionManagerFilter(
TypedConfig: cleanUpstreamLua, TypedConfig: cleanUpstreamLua,
}, },
}, },
{
Name: "envoy.filters.http.lua",
ConfigType: &envoy_http_connection_manager.HttpFilter_TypedConfig{
TypedConfig: rewriteHeadersLua,
},
},
} }
if tlsDomain != "" && tlsDomain != "*" { if tlsDomain != "" && tlsDomain != "*" {
fixMisdirectedLua := marshalAny(&envoy_extensions_filters_http_lua_v3.Lua{ fixMisdirectedLua := marshalAny(&envoy_extensions_filters_http_lua_v3.Lua{

View file

@ -173,6 +173,13 @@ func Test_buildMainHTTPConnectionManagerFilter(t *testing.T) {
"inlineCode": "function remove_pomerium_cookie(cookie_name, cookie)\n -- lua doesn't support optional capture groups\n -- so we replace twice to handle pomerium=xyz at the end of the string\n cookie = cookie:gsub(cookie_name .. \"=[^;]+; \", \"\")\n cookie = cookie:gsub(cookie_name .. \"=[^;]+\", \"\")\n return cookie\nend\n\nfunction has_prefix(str, prefix)\n return str ~= nil and str:sub(1, #prefix) == prefix\nend\n\nfunction envoy_on_request(request_handle)\n local headers = request_handle:headers()\n local metadata = request_handle:metadata()\n\n local remove_cookie_name = metadata:get(\"remove_pomerium_cookie\")\n if remove_cookie_name then\n local cookie = headers:get(\"cookie\")\n if cookie ~= nil then\n newcookie = remove_pomerium_cookie(remove_cookie_name, cookie)\n headers:replace(\"cookie\", newcookie)\n end\n end\n\n local remove_authorization = metadata:get(\"remove_pomerium_authorization\")\n if remove_authorization then\n local authorization = headers:get(\"authorization\")\n local authorization_prefix = \"Pomerium \"\n if has_prefix(authorization, authorization_prefix) then\n headers:remove(\"authorization\")\n end\n end\nend\n\nfunction envoy_on_response(response_handle)\n\nend\n" "inlineCode": "function remove_pomerium_cookie(cookie_name, cookie)\n -- lua doesn't support optional capture groups\n -- so we replace twice to handle pomerium=xyz at the end of the string\n cookie = cookie:gsub(cookie_name .. \"=[^;]+; \", \"\")\n cookie = cookie:gsub(cookie_name .. \"=[^;]+\", \"\")\n return cookie\nend\n\nfunction has_prefix(str, prefix)\n return str ~= nil and str:sub(1, #prefix) == prefix\nend\n\nfunction envoy_on_request(request_handle)\n local headers = request_handle:headers()\n local metadata = request_handle:metadata()\n\n local remove_cookie_name = metadata:get(\"remove_pomerium_cookie\")\n if remove_cookie_name then\n local cookie = headers:get(\"cookie\")\n if cookie ~= nil then\n newcookie = remove_pomerium_cookie(remove_cookie_name, cookie)\n headers:replace(\"cookie\", newcookie)\n end\n end\n\n local remove_authorization = metadata:get(\"remove_pomerium_authorization\")\n if remove_authorization then\n local authorization = headers:get(\"authorization\")\n local authorization_prefix = \"Pomerium \"\n if has_prefix(authorization, authorization_prefix) then\n headers:remove(\"authorization\")\n end\n end\nend\n\nfunction envoy_on_response(response_handle)\n\nend\n"
} }
}, },
{
"name": "envoy.filters.http.lua",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua",
"inlineCode": "function replace_prefix(str, prefix, value)\n return str:gsub(\"^\"..prefix, value)\nend\n\nfunction envoy_on_request(request_handle)\nend\n\nfunction envoy_on_response(response_handle)\n local headers = response_handle:headers()\n local metadata = response_handle:metadata()\n\n -- should be in the form:\n -- [{\n -- \"header\":\"Location\",\n -- \"prefix\":\"http://localhost:8000/two/\",\n -- \"value\":\"http://frontend/one/\"\n -- }]\n local rewrite_response_headers = metadata:get(\"rewrite_response_headers\")\n if rewrite_response_headers then\n for _, obj in pairs(rewrite_response_headers) do\n local hdr = headers:get(obj.header)\n if hdr ~= nil then\n local newhdr = replace_prefix(hdr, obj.prefix, obj.value)\n headers:replace(obj.header, newhdr)\n end\n end\n end\nend\n"
}
},
{ {
"name": "envoy.filters.http.router" "name": "envoy.filters.http.router"
} }

View file

@ -12,6 +12,7 @@ var luascripts struct {
ExtAuthzSetCookie string ExtAuthzSetCookie string
CleanUpstream string CleanUpstream string
RemoveImpersonateHeaders string RemoveImpersonateHeaders string
RewriteHeaders string
FixMisdirected string FixMisdirected string
} }
@ -20,6 +21,7 @@ func init() {
"luascripts/clean-upstream.lua": &luascripts.CleanUpstream, "luascripts/clean-upstream.lua": &luascripts.CleanUpstream,
"luascripts/ext-authz-set-cookie.lua": &luascripts.ExtAuthzSetCookie, "luascripts/ext-authz-set-cookie.lua": &luascripts.ExtAuthzSetCookie,
"luascripts/remove-impersonate-headers.lua": &luascripts.RemoveImpersonateHeaders, "luascripts/remove-impersonate-headers.lua": &luascripts.RemoveImpersonateHeaders,
"luascripts/rewrite-headers.lua": &luascripts.RewriteHeaders,
"luascripts/fix-misdirected.lua": &luascripts.FixMisdirected, "luascripts/fix-misdirected.lua": &luascripts.FixMisdirected,
} }

View file

@ -0,0 +1,166 @@
package controlplane
import (
"encoding/json"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
lua "github.com/yuin/gopher-lua"
)
func TestLuaRewriteHeaders(t *testing.T) {
L := lua.NewState()
defer L.Close()
bs, err := luaFS.ReadFile("luascripts/rewrite-headers.lua")
require.NoError(t, err)
err = L.DoString(string(bs))
require.NoError(t, err)
headers := map[string]string{
"Location": "https://localhost:8080/two/some/uri/",
}
metadata := map[string]interface{}{
"rewrite_response_headers": []interface{}{
map[string]interface{}{
"header": "Location",
"prefix": "https://localhost:8080/two/",
"value": "https://frontend/one/",
},
map[string]interface{}{
"header": "SomeOtherHeader",
"prefix": "x",
"value": "y",
},
},
}
handle := newLuaResponseHandle(L, headers, metadata)
err = L.CallByParam(lua.P{
Fn: L.GetGlobal("envoy_on_response"),
NRet: 0,
Protect: true,
}, handle)
require.NoError(t, err)
assert.Equal(t, "https://frontend/one/some/uri/", headers["Location"])
}
func newLuaResponseHandle(L *lua.LState, headers map[string]string, metadata map[string]interface{}) lua.LValue {
typ := L.NewTable()
L.SetFuncs(typ, map[string]lua.LGFunction{
"headers": func(L *lua.LState) int {
L.Push(newLuaHeaders(L, headers))
return 1
},
"metadata": func(L *lua.LState) int {
L.Push(newLuaMetadata(L, metadata))
return 1
},
})
L.SetField(typ, "__index", typ)
tbl := L.NewTable()
L.SetMetatable(tbl, typ)
return tbl
}
func newLuaHeaders(L *lua.LState, headers map[string]string) lua.LValue {
typ := L.NewTable()
L.SetFuncs(typ, map[string]lua.LGFunction{
"get": func(L *lua.LState) int {
_ = L.CheckTable(1)
key := L.CheckString(2)
str, ok := headers[key]
if !ok {
L.Push(lua.LNil)
return 0
}
L.Push(lua.LString(str))
return 1
},
"replace": func(L *lua.LState) int {
_ = L.CheckTable(1)
key := L.CheckString(2)
value := L.CheckString(3)
headers[key] = value
return 0
},
})
L.SetField(typ, "__index", typ)
tbl := L.NewTable()
L.SetMetatable(tbl, typ)
return tbl
}
func newLuaMetadata(L *lua.LState, metadata map[string]interface{}) lua.LValue {
typ := L.NewTable()
L.SetFuncs(typ, map[string]lua.LGFunction{
"get": func(L *lua.LState) int {
_ = L.CheckTable(1)
key := L.CheckString(2)
obj, ok := metadata[key]
if !ok {
L.Push(lua.LNil)
return 0
}
L.Push(toLua(L, obj))
return 1
},
})
L.SetField(typ, "__index", typ)
tbl := L.NewTable()
L.SetMetatable(tbl, typ)
return tbl
}
func toLua(L *lua.LState, obj interface{}) lua.LValue {
// send the object through JSON to remove custom types
var normalized interface{}
bs, err := json.Marshal(obj)
if err != nil {
panic(err)
}
err = json.Unmarshal(bs, &normalized)
if err != nil {
panic(err)
}
if normalized == nil {
return lua.LNil
}
switch t := normalized.(type) {
case []interface{}:
tbl := L.NewTable()
for _, v := range t {
tbl.Append(toLua(L, v))
}
return tbl
case map[string]interface{}:
tbl := L.NewTable()
for k, v := range t {
L.SetField(tbl, k, toLua(L, v))
}
return tbl
case bool:
return lua.LBool(t)
case float64:
return lua.LNumber(t)
case string:
return lua.LString(t)
default:
panic(fmt.Sprintf("%T not supported for toLua", obj))
}
}

View file

@ -1,6 +1,7 @@
package controlplane package controlplane
import ( import (
"encoding/json"
"fmt" "fmt"
"net/url" "net/url"
"sort" "sort"
@ -290,6 +291,10 @@ func (srv *Server) buildPolicyRoutes(options *config.Options, domain string) ([]
envoyRoute.Action = &envoy_config_route_v3.Route_Route{Route: action} envoyRoute.Action = &envoy_config_route_v3.Route_Route{Route: action}
} }
luaMetadata := map[string]*structpb.Value{
"rewrite_response_headers": getRewriteHeadersMetadata(policy.RewriteResponseHeaders),
}
// disable authentication entirely when the proxy is fronting authenticate // disable authentication entirely when the proxy is fronting authenticate
isFrontingAuthenticate, err := isProxyFrontingAuthenticate(options, domain) isFrontingAuthenticate, err := isProxyFrontingAuthenticate(options, domain)
if err != nil { if err != nil {
@ -300,29 +305,27 @@ func (srv *Server) buildPolicyRoutes(options *config.Options, domain string) ([]
"envoy.filters.http.ext_authz": disableExtAuthz, "envoy.filters.http.ext_authz": disableExtAuthz,
} }
} else { } else {
envoyRoute.Metadata.FilterMetadata = map[string]*structpb.Struct{ luaMetadata["remove_pomerium_cookie"] = &structpb.Value{
"envoy.filters.http.lua": {
Fields: map[string]*structpb.Value{
"remove_pomerium_cookie": {
Kind: &structpb.Value_StringValue{ Kind: &structpb.Value_StringValue{
StringValue: options.CookieName, StringValue: options.CookieName,
}, },
}, }
"remove_pomerium_authorization": { luaMetadata["remove_pomerium_authorization"] = &structpb.Value{
Kind: &structpb.Value_BoolValue{ Kind: &structpb.Value_BoolValue{
BoolValue: true, BoolValue: true,
}, },
}, }
"remove_impersonate_headers": { luaMetadata["remove_impersonate_headers"] = &structpb.Value{
Kind: &structpb.Value_BoolValue{ Kind: &structpb.Value_BoolValue{
BoolValue: policy.KubernetesServiceAccountTokenFile != "" || policy.KubernetesServiceAccountToken != "", BoolValue: policy.KubernetesServiceAccountTokenFile != "" || policy.KubernetesServiceAccountToken != "",
}, },
},
},
},
} }
} }
envoyRoute.Metadata.FilterMetadata = map[string]*structpb.Struct{
"envoy.filters.http.lua": {Fields: luaMetadata},
}
routes = append(routes, envoyRoute) routes = append(routes, envoyRoute)
} }
return routes, nil return routes, nil
@ -559,3 +562,18 @@ func isProxyFrontingAuthenticate(options *config.Options, domain string) (bool,
return false, nil return false, nil
} }
func getRewriteHeadersMetadata(headers []config.RewriteHeader) *structpb.Value {
if len(headers) == 0 {
return &structpb.Value{
Kind: &structpb.Value_ListValue{
ListValue: new(structpb.ListValue),
},
}
}
var obj interface{}
bs, _ := json.Marshal(headers)
_ = json.Unmarshal(bs, &obj)
v, _ := structpb.NewValue(obj)
return v
}

View file

@ -295,7 +295,8 @@ func Test_buildPolicyRoutes(t *testing.T) {
"envoy.filters.http.lua": { "envoy.filters.http.lua": {
"remove_impersonate_headers": false, "remove_impersonate_headers": false,
"remove_pomerium_authorization": true, "remove_pomerium_authorization": true,
"remove_pomerium_cookie": "pomerium" "remove_pomerium_cookie": "pomerium",
"rewrite_response_headers": []
} }
} }
}, },
@ -319,7 +320,8 @@ func Test_buildPolicyRoutes(t *testing.T) {
"envoy.filters.http.lua": { "envoy.filters.http.lua": {
"remove_impersonate_headers": false, "remove_impersonate_headers": false,
"remove_pomerium_authorization": true, "remove_pomerium_authorization": true,
"remove_pomerium_cookie": "pomerium" "remove_pomerium_cookie": "pomerium",
"rewrite_response_headers": []
} }
} }
}, },
@ -344,7 +346,8 @@ func Test_buildPolicyRoutes(t *testing.T) {
"envoy.filters.http.lua": { "envoy.filters.http.lua": {
"remove_impersonate_headers": false, "remove_impersonate_headers": false,
"remove_pomerium_authorization": true, "remove_pomerium_authorization": true,
"remove_pomerium_cookie": "pomerium" "remove_pomerium_cookie": "pomerium",
"rewrite_response_headers": []
} }
} }
}, },
@ -378,7 +381,8 @@ func Test_buildPolicyRoutes(t *testing.T) {
"envoy.filters.http.lua": { "envoy.filters.http.lua": {
"remove_impersonate_headers": false, "remove_impersonate_headers": false,
"remove_pomerium_authorization": true, "remove_pomerium_authorization": true,
"remove_pomerium_cookie": "pomerium" "remove_pomerium_cookie": "pomerium",
"rewrite_response_headers": []
} }
} }
}, },
@ -402,7 +406,8 @@ func Test_buildPolicyRoutes(t *testing.T) {
"envoy.filters.http.lua": { "envoy.filters.http.lua": {
"remove_impersonate_headers": false, "remove_impersonate_headers": false,
"remove_pomerium_authorization": true, "remove_pomerium_authorization": true,
"remove_pomerium_cookie": "pomerium" "remove_pomerium_cookie": "pomerium",
"rewrite_response_headers": []
} }
} }
}, },
@ -427,7 +432,8 @@ func Test_buildPolicyRoutes(t *testing.T) {
"envoy.filters.http.lua": { "envoy.filters.http.lua": {
"remove_impersonate_headers": false, "remove_impersonate_headers": false,
"remove_pomerium_authorization": true, "remove_pomerium_authorization": true,
"remove_pomerium_cookie": "pomerium" "remove_pomerium_cookie": "pomerium",
"rewrite_response_headers": []
} }
} }
}, },
@ -451,7 +457,8 @@ func Test_buildPolicyRoutes(t *testing.T) {
"envoy.filters.http.lua": { "envoy.filters.http.lua": {
"remove_impersonate_headers": false, "remove_impersonate_headers": false,
"remove_pomerium_authorization": true, "remove_pomerium_authorization": true,
"remove_pomerium_cookie": "pomerium" "remove_pomerium_cookie": "pomerium",
"rewrite_response_headers": []
} }
} }
}, },
@ -476,7 +483,8 @@ func Test_buildPolicyRoutes(t *testing.T) {
"envoy.filters.http.lua": { "envoy.filters.http.lua": {
"remove_impersonate_headers": false, "remove_impersonate_headers": false,
"remove_pomerium_authorization": true, "remove_pomerium_authorization": true,
"remove_pomerium_cookie": "pomerium" "remove_pomerium_cookie": "pomerium",
"rewrite_response_headers": []
} }
} }
}, },
@ -517,6 +525,11 @@ func Test_buildPolicyRoutes(t *testing.T) {
"prefix": "/" "prefix": "/"
}, },
"metadata": { "metadata": {
"filterMetadata": {
"envoy.filters.http.lua": {
"rewrite_response_headers": []
}
}
}, },
"route": { "route": {
"autoHostRewrite": true, "autoHostRewrite": true,
@ -568,7 +581,8 @@ func Test_buildPolicyRoutes(t *testing.T) {
"envoy.filters.http.lua": { "envoy.filters.http.lua": {
"remove_impersonate_headers": false, "remove_impersonate_headers": false,
"remove_pomerium_authorization": true, "remove_pomerium_authorization": true,
"remove_pomerium_cookie": "pomerium" "remove_pomerium_cookie": "pomerium",
"rewrite_response_headers": []
} }
} }
}, },
@ -594,7 +608,8 @@ func Test_buildPolicyRoutes(t *testing.T) {
"envoy.filters.http.lua": { "envoy.filters.http.lua": {
"remove_impersonate_headers": false, "remove_impersonate_headers": false,
"remove_pomerium_authorization": true, "remove_pomerium_authorization": true,
"remove_pomerium_cookie": "pomerium" "remove_pomerium_cookie": "pomerium",
"rewrite_response_headers": []
} }
} }
}, },
@ -678,7 +693,8 @@ func Test_buildPolicyRoutesRewrite(t *testing.T) {
"envoy.filters.http.lua": { "envoy.filters.http.lua": {
"remove_impersonate_headers": false, "remove_impersonate_headers": false,
"remove_pomerium_authorization": true, "remove_pomerium_authorization": true,
"remove_pomerium_cookie": "pomerium" "remove_pomerium_cookie": "pomerium",
"rewrite_response_headers": []
} }
} }
}, },
@ -703,7 +719,8 @@ func Test_buildPolicyRoutesRewrite(t *testing.T) {
"envoy.filters.http.lua": { "envoy.filters.http.lua": {
"remove_impersonate_headers": false, "remove_impersonate_headers": false,
"remove_pomerium_authorization": true, "remove_pomerium_authorization": true,
"remove_pomerium_cookie": "pomerium" "remove_pomerium_cookie": "pomerium",
"rewrite_response_headers": []
} }
} }
}, },
@ -728,7 +745,8 @@ func Test_buildPolicyRoutesRewrite(t *testing.T) {
"envoy.filters.http.lua": { "envoy.filters.http.lua": {
"remove_impersonate_headers": false, "remove_impersonate_headers": false,
"remove_pomerium_authorization": true, "remove_pomerium_authorization": true,
"remove_pomerium_cookie": "pomerium" "remove_pomerium_cookie": "pomerium",
"rewrite_response_headers": []
} }
} }
}, },
@ -759,7 +777,8 @@ func Test_buildPolicyRoutesRewrite(t *testing.T) {
"envoy.filters.http.lua": { "envoy.filters.http.lua": {
"remove_impersonate_headers": false, "remove_impersonate_headers": false,
"remove_pomerium_authorization": true, "remove_pomerium_authorization": true,
"remove_pomerium_cookie": "pomerium" "remove_pomerium_cookie": "pomerium",
"rewrite_response_headers": []
} }
} }
}, },
@ -784,7 +803,8 @@ func Test_buildPolicyRoutesRewrite(t *testing.T) {
"envoy.filters.http.lua": { "envoy.filters.http.lua": {
"remove_impersonate_headers": false, "remove_impersonate_headers": false,
"remove_pomerium_authorization": true, "remove_pomerium_authorization": true,
"remove_pomerium_cookie": "pomerium" "remove_pomerium_cookie": "pomerium",
"rewrite_response_headers": []
} }
} }
}, },
@ -809,7 +829,8 @@ func Test_buildPolicyRoutesRewrite(t *testing.T) {
"envoy.filters.http.lua": { "envoy.filters.http.lua": {
"remove_impersonate_headers": false, "remove_impersonate_headers": false,
"remove_pomerium_authorization": true, "remove_pomerium_authorization": true,
"remove_pomerium_cookie": "pomerium" "remove_pomerium_cookie": "pomerium",
"rewrite_response_headers": []
} }
} }
}, },