From 3bc7cf1d00635f602bc4731a904675d982d34317 Mon Sep 17 00:00:00 2001 From: Jesse Haka Date: Sun, 12 May 2024 18:59:44 +0300 Subject: [PATCH] api: Authorization API design (#2652) * add authorisation api spec Signed-off-by: Jesse Haka * add comments Signed-off-by: huabing zhao * Remove permission in the first run Signed-off-by: huabing zhao * Move subject and permission to Rule Signed-off-by: huabing zhao * remove log action Signed-off-by: huabing zhao * add default action Signed-off-by: huabing zhao * add excluded client CIDR Signed-off-by: huabing zhao * hide api Signed-off-by: huabing zhao * minor wording Signed-off-by: huabing zhao * remove exclude ip range in the first run Signed-off-by: huabing zhao * change subject to principal: align with Envoy and the AWS RBAC term Signed-off-by: huabing zhao * add Name field to a Rule Signed-off-by: huabing zhao * remove name field for now Signed-off-by: huabing zhao * Update api/v1alpha1/authorization_types.go Co-authored-by: Arko Dasgupta Signed-off-by: Huabing Zhao * fix docs Signed-off-by: huabing zhao * minor wording Signed-off-by: huabing zhao * fix lint Signed-off-by: huabing zhao --------- Signed-off-by: Jesse Haka Signed-off-by: huabing zhao Signed-off-by: Huabing Zhao Co-authored-by: huabing zhao Co-authored-by: Arko Dasgupta --- api/v1alpha1/authorization_types.go | 65 ++++++++++++++++++ api/v1alpha1/clienttrafficpolicy_types.go | 2 +- api/v1alpha1/securitypolicy_types.go | 6 ++ api/v1alpha1/zz_generated.deepcopy.go | 68 +++++++++++++++++++ ...y.envoyproxy.io_clienttrafficpolicies.yaml | 2 +- ...ateway.envoyproxy.io_securitypolicies.yaml | 53 +++++++++++++++ site/content/en/latest/api/extension_types.md | 62 ++++++++++++++++- 7 files changed, 255 insertions(+), 3 deletions(-) create mode 100644 api/v1alpha1/authorization_types.go diff --git a/api/v1alpha1/authorization_types.go b/api/v1alpha1/authorization_types.go new file mode 100644 index 00000000000..c52a2063b36 --- /dev/null +++ b/api/v1alpha1/authorization_types.go @@ -0,0 +1,65 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +package v1alpha1 + +// Authorization defines the authorization configuration. +// +notImplementedHide +type Authorization struct { + // Rules defines a list of authorization rules. + // These rules are evaluated in order, the first matching rule will be applied, + // and the rest will be skipped. + // + // For example, if there are two rules: the first rule allows the request + // and the second rule denies it, when a request matches both rules, it will be allowed. + // + // +optional + Rules []Rule `json:"rules,omitempty"` + + // DefaultAction defines the default action to be taken if no rules match. + // If not specified, the default action is Deny. + // +optional + DefaultAction *RuleActionType `json:"defaultAction"` +} + +// Rule defines the single authorization rule. +// +notImplementedHide +type Rule struct { + // Action defines the action to be taken if the rule matches. + Action RuleActionType `json:"action"` + + // Principal specifies the client identity of a request. + Principal Principal `json:"principal"` + + // Permissions contains allowed HTTP methods. + // If empty, all methods are matching. + // + // +optional + // Permissions []string `json:"permissions,omitempty"` +} + +// Principal specifies the client identity of a request. +// +notImplementedHide +type Principal struct { + // ClientCIDR is the IP CIDR range of the client. + // Valid examples are "192.168.1.0/24" or "2001:db8::/64" + // + // By default, the client IP is inferred from the x-forwarder-for header and proxy protocol. + // You can use the `EnableProxyProtocol` and `ClientIPDetection` options in + // the `ClientTrafficPolicy` to configure how the client IP is detected. + ClientCIDR []string `json:"clientCIDR,omitempty"` +} + +// RuleActionType specifies the types of authorization rule action. +// +kubebuilder:validation:Enum=Allow;Deny +// +notImplementedHide +type RuleActionType string + +const ( + // Allow is the action to allow the request. + Allow RuleActionType = "Allow" + // Deny is the action to deny the request. + Deny RuleActionType = "Deny" +) diff --git a/api/v1alpha1/clienttrafficpolicy_types.go b/api/v1alpha1/clienttrafficpolicy_types.go index b84d7a9698e..440c01c6c98 100644 --- a/api/v1alpha1/clienttrafficpolicy_types.go +++ b/api/v1alpha1/clienttrafficpolicy_types.go @@ -136,7 +136,7 @@ type ClientIPDetectionSettings struct { // +optional XForwardedFor *XForwardedForSettings `json:"xForwardedFor,omitempty"` // CustomHeader provides configuration for determining the client IP address for a request based on - // a trusted custom HTTP header. This uses the the custom_header original IP detection extension. + // a trusted custom HTTP header. This uses the custom_header original IP detection extension. // Refer to https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto // for more details. // diff --git a/api/v1alpha1/securitypolicy_types.go b/api/v1alpha1/securitypolicy_types.go index bbc86072324..95b160a9c0e 100644 --- a/api/v1alpha1/securitypolicy_types.go +++ b/api/v1alpha1/securitypolicy_types.go @@ -69,6 +69,12 @@ type SecurityPolicySpec struct { // // +optional ExtAuth *ExtAuth `json:"extAuth,omitempty"` + + // Authorization defines the authorization configuration. + // + // +optional + // +notImplementedHide + Authorization *Authorization `json:"authorization,omitempty"` } //+kubebuilder:object:root=true diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 71f09022f35..5dc25960173 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -151,6 +151,33 @@ func (in *ActiveHealthCheckPayload) DeepCopy() *ActiveHealthCheckPayload { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Authorization) DeepCopyInto(out *Authorization) { + *out = *in + if in.Rules != nil { + in, out := &in.Rules, &out.Rules + *out = make([]Rule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.DefaultAction != nil { + in, out := &in.DefaultAction, &out.DefaultAction + *out = new(RuleActionType) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Authorization. +func (in *Authorization) DeepCopy() *Authorization { + if in == nil { + return nil + } + out := new(Authorization) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BackOffPolicy) DeepCopyInto(out *BackOffPolicy) { *out = *in @@ -3122,6 +3149,26 @@ func (in *PerRetryPolicy) DeepCopy() *PerRetryPolicy { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Principal) DeepCopyInto(out *Principal) { + *out = *in + if in.ClientCIDR != nil { + in, out := &in.ClientCIDR, &out.ClientCIDR + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Principal. +func (in *Principal) DeepCopy() *Principal { + if in == nil { + return nil + } + out := new(Principal) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ProcessingModeOptions) DeepCopyInto(out *ProcessingModeOptions) { *out = *in @@ -3831,6 +3878,22 @@ func (in *RetryOn) DeepCopy() *RetryOn { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Rule) DeepCopyInto(out *Rule) { + *out = *in + in.Principal.DeepCopyInto(&out.Principal) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Rule. +func (in *Rule) DeepCopy() *Rule { + if in == nil { + return nil + } + out := new(Rule) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecurityPolicy) DeepCopyInto(out *SecurityPolicy) { *out = *in @@ -3919,6 +3982,11 @@ func (in *SecurityPolicySpec) DeepCopyInto(out *SecurityPolicySpec) { *out = new(ExtAuth) (*in).DeepCopyInto(*out) } + if in.Authorization != nil { + in, out := &in.Authorization, &out.Authorization + *out = new(Authorization) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityPolicySpec. diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml index c308847ea0d..b45522e3e39 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml @@ -56,7 +56,7 @@ spec: customHeader: description: |- CustomHeader provides configuration for determining the client IP address for a request based on - a trusted custom HTTP header. This uses the the custom_header original IP detection extension. + a trusted custom HTTP header. This uses the custom_header original IP detection extension. Refer to https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto for more details. properties: diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml index 7c314e20cd7..919d272cf89 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -49,6 +49,59 @@ spec: spec: description: Spec defines the desired state of SecurityPolicy. properties: + authorization: + description: Authorization defines the authorization configuration. + properties: + defaultAction: + description: |- + DefaultAction defines the default action to be taken if no rules match. + If not specified, the default action is Deny. + enum: + - Allow + - Deny + type: string + rules: + description: |- + Rules defines a list of authorization rules. + These rules are evaluated in order, the first matching rule will be applied, + and the rest will be skipped. + + + For example, if there are two rules: the first rule allows the request + and the second rule denies it, when a request matches both rules, it will be allowed. + items: + description: Rule defines the single authorization rule. + properties: + action: + description: Action defines the action to be taken if the + rule matches. + enum: + - Allow + - Deny + type: string + principal: + description: Principal specifies the client identity of + a request. + properties: + clientCIDR: + description: |- + ClientCIDR is the IP CIDR range of the client. + Valid examples are "192.168.1.0/24" or "2001:db8::/64" + + + By default, the client IP is inferred from the x-forwarder-for header and proxy protocol. + You can use the `EnableProxyProtocol` and `ClientIPDetection` options in + the `ClientTrafficPolicy` to configure how the client IP is detected. + items: + type: string + type: array + type: object + required: + - action + - principal + type: object + type: array + type: object basicAuth: description: BasicAuth defines the configuration for the HTTP Basic Authentication. diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index bc85633137c..cde865d9ab2 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -171,6 +171,21 @@ _Appears in:_ | `TCP` | ActiveHealthCheckerTypeTCP defines the TCP type of health checking.
| +#### Authorization + + + +Authorization defines the authorization configuration. + +_Appears in:_ +- [SecurityPolicySpec](#securitypolicyspec) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `rules` | _[Rule](#rule) array_ | false | Rules defines a list of authorization rules.
These rules are evaluated in order, the first matching rule will be applied,
and the rest will be skipped.

For example, if there are two rules: the first rule allows the request
and the second rule denies it, when a request matches both rules, it will be allowed. | +| `defaultAction` | _[RuleActionType](#ruleactiontype)_ | false | DefaultAction defines the default action to be taken if no rules match.
If not specified, the default action is Deny. | + + #### BackOffPolicy @@ -379,7 +394,7 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | | `xForwardedFor` | _[XForwardedForSettings](#xforwardedforsettings)_ | false | XForwardedForSettings provides configuration for using X-Forwarded-For headers for determining the client IP address. | -| `customHeader` | _[CustomHeaderExtensionSettings](#customheaderextensionsettings)_ | false | CustomHeader provides configuration for determining the client IP address for a request based on
a trusted custom HTTP header. This uses the the custom_header original IP detection extension.
Refer to https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto
for more details. | +| `customHeader` | _[CustomHeaderExtensionSettings](#customheaderextensionsettings)_ | false | CustomHeader provides configuration for determining the client IP address for a request based on
a trusted custom HTTP header. This uses the custom_header original IP detection extension.
Refer to https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto
for more details. | #### ClientTLSSettings @@ -2253,6 +2268,20 @@ _Appears in:_ | `backOff` | _[BackOffPolicy](#backoffpolicy)_ | false | Backoff is the backoff policy to be applied per retry attempt. gateway uses a fully jittered exponential
back-off algorithm for retries. For additional details,
see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#config-http-filters-router-x-envoy-max-retries | +#### Principal + + + +Principal specifies the client identity of a request. + +_Appears in:_ +- [Rule](#rule) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `clientCIDR` | _string array_ | true | ClientCIDR is the IP CIDR range of the client.
Valid examples are "192.168.1.0/24" or "2001:db8::/64"

By default, the client IP is inferred from the x-forwarder-for header and proxy protocol.
You can use the `EnableProxyProtocol` and `ClientIPDetection` options in
the `ClientTrafficPolicy` to configure how the client IP is detected. | + + #### ProcessingModeOptions @@ -2884,6 +2913,37 @@ _Appears in:_ | `httpStatusCodes` | _[HTTPStatus](#httpstatus) array_ | false | HttpStatusCodes specifies the http status codes to be retried.
The retriable-status-codes trigger must also be configured for these status codes to trigger a retry. | +#### Rule + + + +Rule defines the single authorization rule. + +_Appears in:_ +- [Authorization](#authorization) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `action` | _[RuleActionType](#ruleactiontype)_ | true | Action defines the action to be taken if the rule matches. | +| `principal` | _[Principal](#principal)_ | true | Principal specifies the client identity of a request. | + + +#### RuleActionType + +_Underlying type:_ _string_ + +RuleActionType specifies the types of authorization rule action. + +_Appears in:_ +- [Authorization](#authorization) +- [Rule](#rule) + +| Value | Description | +| ----- | ----------- | +| `Allow` | Allow is the action to allow the request.
| +| `Deny` | Deny is the action to deny the request.
| + + #### SecurityPolicy