Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add dynamic metadata support in http ext authz #4164

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions api/v1alpha1/ext_auth_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,11 @@ type HTTPExtAuthService struct {
// original client request.
// +optional
HeadersToBackend []string `json:"headersToBackend,omitempty"`

// HeadersToMetadata are the authorization response headers that will be emitted
// as dynamic metadata to be consumed by next filter.
// Note: this metadata lives in envoy.filters.http.ext_authz and can only be consumed
// by the next filter if explicitly specified.
// +optional
HeadersToMetadata []string `json:"headersToMetadata,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

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

looks like only support exact with this PR, what will happen if we want to support prefix/suffix/regex in the future?

BTW, please proposal the API first.

Copy link
Author

Choose a reason for hiding this comment

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

yes, this will only support exact matching for now, similar to HeadersToBackend.

Apologies, I wasn't aware a proposal was needed. I have now created it on #4163.

Copy link
Author

@nothinux nothinux Sep 5, 2024

Choose a reason for hiding this comment

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

we will need to modify the API for HeadersToBackend as well if we want to support prefix/suffix/regex in the future, do you think this is necessary @zirain? if so I'll try to change the implementation for both

Copy link
Contributor

Choose a reason for hiding this comment

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

let's focus on metadata first, WDYT?

Copy link
Member

@zhaohuabing zhaohuabing Sep 23, 2024

Choose a reason for hiding this comment

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

I believe it may be sufficient to just support the exact match for the HeadersToMetadata, considering that

  • HTTP header names are typically fixed and don't change dynamically, and the number of HTTP headers is usually quite limited.
  • A downstream filter that needs to extract the value from a Metada will also need to know the Metadata name in advance, so having a fixed name seems reasonable.

Supporting prefix/suffix/regex may unnecessarily complicate the API.

That said, I could be mistaken on this. @envoyproxy/gateway-maintainers, please feel free to chime in.

Copy link
Author

Choose a reason for hiding this comment

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

yes, I think adding prefix, suffix, or regex might complicate the API. For now, could we consider only supporting exact matches @zirain?

}
5 changes: 5 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2083,6 +2083,15 @@ spec:
items:
type: string
type: array
headersToMetadata:
description: |-
HeadersToMetadata are the authorization response headers that will be emitted
as dynamic metadata to be consumed by next filter.
Note: this metadata lives in envoy.filters.http.ext_authz and can only be consumed
by the next filter if explicitly specified.
items:
type: string
type: array
path:
description: |-
Path is the path of the HTTP External Authorization service.
Expand Down
9 changes: 5 additions & 4 deletions internal/gatewayapi/securitypolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -878,10 +878,11 @@ func (t *Translator) buildExtAuth(policy *egv1a1.SecurityPolicy, resources *reso

if http != nil {
extAuth.HTTP = &ir.HTTPExtAuthService{
Destination: rd,
Authority: authority,
Path: ptr.Deref(http.Path, ""),
HeadersToBackend: http.HeadersToBackend,
Destination: rd,
Authority: authority,
Path: ptr.Deref(http.Path, ""),
HeadersToBackend: http.HeadersToBackend,
HeadersToMetadata: http.HeadersToMetadata,
}
} else {
extAuth.GRPC = &ir.GRPCExtAuthService{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,6 @@ securityPolicies:
headersToBackend:
- header1
- header2
headersToMetadata:
- metadata1
- metadata2
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ securityPolicies:
headersToBackend:
- header1
- header2
headersToMetadata:
- metadata1
- metadata2
path: /auth
targetRef:
group: gateway.networking.k8s.io
Expand Down Expand Up @@ -350,5 +353,8 @@ xdsIR:
headersToBackend:
- header1
- header2
headersToMetadata:
- metadata1
- metadata2
path: /auth
name: securitypolicy/default/policy-for-gateway-1
7 changes: 7 additions & 0 deletions internal/ir/xds.go
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,13 @@ type HTTPExtAuthService struct {
// original client request.
// +optional
HeadersToBackend []string `json:"headersToBackend,omitempty"`

// HeadersToMetadata are the authorization response headers that will be emitted
// as dynamic metadata to be consumed by next filter.
// Note: this metadata lives in envoy.filters.http.ext_authz and can only be consumed
// by the next filter if explicitly specified.
// +optional
HeadersToMetadata []string `json:"headersToMetadata,omitempty"`
}

// GRPCExtAuthService defines the gRPC External Authorization service
Expand Down
5 changes: 5 additions & 0 deletions internal/ir/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 23 additions & 3 deletions internal/xds/translator/extauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,10 @@ func extAuthConfig(extAuth *ir.ExtAuth) *extauthv3.ExtAuthz {

func httpService(http *ir.HTTPExtAuthService) *extauthv3.HttpService {
var (
uri string
headersToBackend []*matcherv3.StringMatcher
service *extauthv3.HttpService
uri string
headersToBackend []*matcherv3.StringMatcher
headersToMetadata []*matcherv3.StringMatcher
service *extauthv3.HttpService
)

service = &extauthv3.HttpService{
Expand Down Expand Up @@ -191,6 +192,25 @@ func httpService(http *ir.HTTPExtAuthService) *extauthv3.HttpService {
}
}

for _, metadata := range http.HeadersToMetadata {
headersToMetadata = append(headersToMetadata, &matcherv3.StringMatcher{
MatchPattern: &matcherv3.StringMatcher_Exact{
Exact: metadata,
},
IgnoreCase: true,
})
}

if len(headersToMetadata) > 0 {
if service.AuthorizationResponse == nil {
service.AuthorizationResponse = &extauthv3.AuthorizationResponse{}
}

service.AuthorizationResponse.DynamicMetadataFromHeaders = &matcherv3.ListStringMatcher{
Patterns: headersToMetadata,
}
}

return service
}

Expand Down
3 changes: 3 additions & 0 deletions internal/xds/translator/testdata/in/xds-ir/ext-auth.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,7 @@ http:
headersToBackend:
- header1
- header2
headersToMetadata:
- metadata1
- metadata2
path: /auth
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@
ignoreCase: true
- exact: header2
ignoreCase: true
dynamicMetadataFromHeaders:
patterns:
- exact: metadata1
ignoreCase: true
- exact: metadata2
ignoreCase: true
pathPrefix: /auth
serverUri:
cluster: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
Expand Down
1 change: 1 addition & 0 deletions site/content/en/latest/api/extension_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -1936,6 +1936,7 @@ _Appears in:_
| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection<br />to the backend. |
| `path` | _string_ | true | Path is the path of the HTTP External Authorization service.<br />If path is specified, the authorization request will be sent to that path,<br />or else the authorization request will be sent to the root path. |
| `headersToBackend` | _string array_ | false | HeadersToBackend are the authorization response headers that will be added<br />to the original client request before sending it to the backend server.<br />Note that coexisting headers will be overridden.<br />If not specified, no authorization response headers will be added to the<br />original client request. |
| `headersToMetadata` | _string array_ | false | HeadersToMetadata are the authorization response headers that will be emitted<br />as dynamic metadata to be consumed by next filter.<br />Note: this metadata lives in envoy.filters.http.ext_authz and can only be consumed<br />by the next filter if explicitly specified. |


#### HTTPPathModifier
Expand Down
1 change: 1 addition & 0 deletions site/content/zh/latest/api/extension_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -1936,6 +1936,7 @@ _Appears in:_
| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection<br />to the backend. |
| `path` | _string_ | true | Path is the path of the HTTP External Authorization service.<br />If path is specified, the authorization request will be sent to that path,<br />or else the authorization request will be sent to the root path. |
| `headersToBackend` | _string array_ | false | HeadersToBackend are the authorization response headers that will be added<br />to the original client request before sending it to the backend server.<br />Note that coexisting headers will be overridden.<br />If not specified, no authorization response headers will be added to the<br />original client request. |
| `headersToMetadata` | _string array_ | false | HeadersToMetadata are the authorization response headers that will be emitted<br />as dynamic metadata to be consumed by next filter.<br />Note: this metadata lives in envoy.filters.http.ext_authz and can only be consumed<br />by the next filter if explicitly specified. |


#### HTTPPathModifier
Expand Down