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: authorization implementation #3399

Merged
merged 14 commits into from
May 29, 2024
50 changes: 25 additions & 25 deletions api/v1alpha1/authorization_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
package v1alpha1

// Authorization defines the authorization configuration.
// +notImplementedHide
//
// Note: if neither `Rules` nor `DefaultAction` is specified, the default action is to deny all requests.
type Authorization struct {
// Rules defines a list of authorization rules.
// These rules are evaluated in order, the first matching rule will be applied,
Expand All @@ -16,50 +17,49 @@ type Authorization struct {
// and the second rule denies it, when a request matches both rules, it will be allowed.
//
// +optional
Rules []Rule `json:"rules,omitempty"`
Rules []AuthorizationRule `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"`
DefaultAction *AuthorizationAction `json:"defaultAction"`
}

// Rule defines the single authorization rule.
// +notImplementedHide
type Rule struct {
// AuthorizationRule defines a single authorization rule.
type AuthorizationRule struct {
// Name is a user-friendly name for the rule. It's just for display purposes.
zhaohuabing marked this conversation as resolved.
Show resolved Hide resolved
// +optional
Name *string `json:"name,omitempty"`

// Action defines the action to be taken if the rule matches.
Action RuleActionType `json:"action"`
Action AuthorizationAction `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
// A client identity can be a client IP, a JWT claim, username from the Authorization header,
// or any other identity that can be extracted from a custom header.
// Currently, only the client IP is supported.
type Principal struct {
// ClientCIDR is the IP CIDR range of the client.
// ClientCIDRs are the IP CIDR ranges 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 client IP is inferred from the x-forwarder-for header, a custom header,
// or the proxy protocol.
// You can use the `ClientIPDetection` or the `EnableProxyProtocol` field in
// the `ClientTrafficPolicy` to configure how the client IP is detected.
ClientCIDR []string `json:"clientCIDR,omitempty"`
ClientCIDRs []string `json:"clientCIDRs,omitempty"`
}

// RuleActionType specifies the types of authorization rule action.
// AuthorizationAction defines the action to be taken if a rule matches.
// +kubebuilder:validation:Enum=Allow;Deny
// +notImplementedHide
type RuleActionType string
type AuthorizationAction string

const (
// Allow is the action to allow the request.
Allow RuleActionType = "Allow"
// Deny is the action to deny the request.
Deny RuleActionType = "Deny"
// AuthorizationActionAllow is the action to allow the request.
AuthorizationActionAllow AuthorizationAction = "Allow"
// AuthorizationActionDeny is the action to deny the request.
AuthorizationActionDeny AuthorizationAction = "Deny"
)
7 changes: 6 additions & 1 deletion api/v1alpha1/envoyproxy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ type EnvoyProxySpec struct {
//
// - envoy.filters.http.wasm
//
// - envoy.filters.http.rbac
//
// - envoy.filters.http.local_ratelimit
//
// - envoy.filters.http.ratelimit
Expand Down Expand Up @@ -150,7 +152,7 @@ type FilterPosition struct {
}

// EnvoyFilter defines the type of Envoy HTTP filter.
// +kubebuilder:validation:Enum=envoy.filters.http.cors;envoy.filters.http.ext_authz;envoy.filters.http.basic_authn;envoy.filters.http.oauth2;envoy.filters.http.jwt_authn;envoy.filters.http.fault;envoy.filters.http.local_ratelimit;envoy.filters.http.ratelimit;envoy.filters.http.wasm;envoy.filters.http.ext_proc
// +kubebuilder:validation:Enum=envoy.filters.http.cors;envoy.filters.http.ext_authz;envoy.filters.http.basic_authn;envoy.filters.http.oauth2;envoy.filters.http.jwt_authn;envoy.filters.http.fault;envoy.filters.http.local_ratelimit;envoy.filters.http.ratelimit;envoy.filters.http.wasm;envoy.filters.http.ext_proc;envoy.filters.http.rbac
type EnvoyFilter string

const (
Expand Down Expand Up @@ -183,6 +185,9 @@ const (
// EnvoyFilterRateLimit defines the Envoy HTTP rate limit filter.
EnvoyFilterRateLimit EnvoyFilter = "envoy.filters.http.ratelimit"

// EnvoyFilterRBAC defines the Envoy RBAC filter.
EnvoyFilterRBAC EnvoyFilter = "envoy.filters.http.rbac"

// EnvoyFilterRouter defines the Envoy HTTP router filter.
EnvoyFilterRouter EnvoyFilter = "envoy.filters.http.router"
)
Expand Down
45 changes: 25 additions & 20 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 @@ -253,6 +253,9 @@ spec:
- envoy.filters.http.wasm


- envoy.filters.http.rbac


- envoy.filters.http.local_ratelimit


Expand All @@ -279,6 +282,7 @@ spec:
- envoy.filters.http.ratelimit
- envoy.filters.http.wasm
- envoy.filters.http.ext_proc
- envoy.filters.http.rbac
type: string
before:
description: |-
Expand All @@ -295,6 +299,7 @@ spec:
- envoy.filters.http.ratelimit
- envoy.filters.http.wasm
- envoy.filters.http.ext_proc
- envoy.filters.http.rbac
type: string
name:
description: Name of the filter.
Expand All @@ -309,6 +314,7 @@ spec:
- envoy.filters.http.ratelimit
- envoy.filters.http.wasm
- envoy.filters.http.ext_proc
- envoy.filters.http.rbac
type: string
required:
- name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ spec:
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.
description: AuthorizationRule defines a single authorization
rule.
properties:
action:
description: Action defines the action to be taken if the
Expand All @@ -79,18 +80,23 @@ spec:
- Allow
- Deny
type: string
name:
description: Name is a user-friendly name for the rule.
It's just for display purposes.
type: string
principal:
description: Principal specifies the client identity of
a request.
properties:
clientCIDR:
clientCIDRs:
description: |-
ClientCIDR is the IP CIDR range of the client.
ClientCIDRs are the IP CIDR ranges 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 client IP is inferred from the x-forwarder-for header, a custom header,
or the proxy protocol.
You can use the `ClientIPDetection` or the `EnableProxyProtocol` field in
the `ClientTrafficPolicy` to configure how the client IP is detected.
items:
type: string
Expand Down
15 changes: 4 additions & 11 deletions internal/gatewayapi/backendtrafficpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import (
"fmt"
"math"
"net"
"sort"
"strings"
"time"
Expand Down Expand Up @@ -732,18 +731,12 @@
distinct = true
}

ip, ipn, err := net.ParseCIDR(sourceCIDR)
cidrMatch, err := parseCIDR(sourceCIDR)

Check warning on line 734 in internal/gatewayapi/backendtrafficpolicy.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/backendtrafficpolicy.go#L734

Added line #L734 was not covered by tests
if err != nil {
return nil, fmt.Errorf("unable to translate rateLimit")
}

mask, _ := ipn.Mask.Size()
irRule.CIDRMatch = &ir.CIDRMatch{
CIDR: ipn.String(),
IPv6: ip.To4() == nil,
MaskLen: mask,
Distinct: distinct,
return nil, fmt.Errorf("unable to translate rateLimit: %w", err)

Check warning on line 736 in internal/gatewayapi/backendtrafficpolicy.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/backendtrafficpolicy.go#L736

Added line #L736 was not covered by tests
}
cidrMatch.Distinct = distinct
irRule.CIDRMatch = cidrMatch
}
}
return irRule, nil
Expand Down
16 changes: 16 additions & 0 deletions internal/gatewayapi/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import (
"errors"
"fmt"
"net"
"strings"

v1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -466,3 +467,18 @@
}
return res
}

func parseCIDR(cidr string) (*ir.CIDRMatch, error) {
ip, ipn, err := net.ParseCIDR(cidr)
if err != nil {
return nil, err

Check warning on line 474 in internal/gatewayapi/helpers.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/helpers.go#L474

Added line #L474 was not covered by tests
}

mask, _ := ipn.Mask.Size()
return &ir.CIDRMatch{
CIDR: ipn.String(),
IP: ip.String(),
MaskLen: uint32(mask),
IsIPv6: ip.To4() == nil,
}, nil
}
Loading
Loading