Skip to content

Commit

Permalink
sotw: auth (#952)
Browse files Browse the repository at this point in the history
* Prepare AuthPolicy type for the merge strategy

* Structure of named patterns changed from `patterns: map[string][]PatternExpression` to `patterns: map[string]{allOf: []PatternExpression}`.
* `spec.response.success.dynamicMetadata` field renamed `spec.response.success.filters`, documented as meant for exporting data to other filters managed by Kuadrant only.

Signed-off-by: Guilherme Cassolato <[email protected]>

* sotw: auth

* AuthPolicies validation
* Effective auth policies
* Authorino AuthConfigs
* Istio/Envoy Gateway cluster patches
* Istio/Envoy Gateway wasm extensions
* (Most part of) AuthPolicy status update

Signed-off-by: Guilherme Cassolato <[email protected]>

* activate auth service in the wasm config

Signed-off-by: Guilherme Cassolato <[email protected]>

* check status of the authconfigs for the authpolicy enforced status condition + refactoring of the ratelimitpolicy staus updater for consistency with auth

Signed-off-by: Guilherme Cassolato <[email protected]>

* tests: fix unit tests pkg/wasm

Signed-off-by: Guilherme Cassolato <[email protected]>

* bump policy-machinery to v0.6.2

Signed-off-by: Guilherme Cassolato <[email protected]>

* bump policy-machinery to v0.6.3

Signed-off-by: Guilherme Cassolato <[email protected]>

* add effective authpolicy count to debug log messages when building gateway extension resources

Signed-off-by: Guilherme Cassolato <[email protected]>

* fix: equality between envoy gateway extension resources

Signed-off-by: Guilherme Cassolato <[email protected]>

* De/restructure all objects via JSON

Signed-off-by: Guilherme Cassolato <[email protected]>

* Remove unused funcs from the reconciliation of AuthConfigs

Signed-off-by: Guilherme Cassolato <[email protected]>

* fix: equality between envoy gateway cluster patch resources

Signed-off-by: Guilherme Cassolato <[email protected]>

* bump policy-machinery to v0.6.4

Signed-off-by: Guilherme Cassolato <[email protected]>

* remove unnecessary custom json unmarshallers from poliyc types

Signed-off-by: Guilherme Cassolato <[email protected]>

* tests: activate auth service in the wasm config

Signed-off-by: Guilherme Cassolato <[email protected]>

* fix: build envoy auth cluster patch with correct name

Signed-off-by: Guilherme Cassolato <[email protected]>

* fix: cel validations of the authpolicy

Signed-off-by: Guilherme Cassolato <[email protected]>

* tests: fix authpolicy integration tests

Signed-off-by: Guilherme Cassolato <[email protected]>

* fix: mark empty authpolicies as enforced

Signed-off-by: Guilherme Cassolato <[email protected]>

* disable prealloc linter

Signed-off-by: Guilherme Cassolato <[email protected]>

* refactor: improved tracking of the origin of a policy rule throughout merges

Signed-off-by: Guilherme Cassolato <[email protected]>

* fix log message

Signed-off-by: Guilherme Cassolato <[email protected]>

* fix nil custom response unauthenticated/unauthorized configs

Signed-off-by: Guilherme Cassolato <[email protected]>

* preallocate the modifiedAuthConfigs slice

Signed-off-by: Guilherme Cassolato <[email protected]>

* docs: updated user guide Enforcing authentication & authorization with Kuadrant AuthPolicy

Signed-off-by: Guilherme Cassolato <[email protected]>

---------

Signed-off-by: Guilherme Cassolato <[email protected]>
  • Loading branch information
guicassolato authored and maleck13 committed Nov 13, 2024
1 parent b084d80 commit cb75a5f
Show file tree
Hide file tree
Showing 69 changed files with 4,142 additions and 7,058 deletions.
2 changes: 1 addition & 1 deletion .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ linters:
- errorlint
- revive
- gosec
- prealloc
- stylecheck
- prealloc
- tparallel
- unconvert
- unparam
Expand Down
56 changes: 41 additions & 15 deletions api/v1/merge_strategies.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,20 @@ const (
PolicyRuleMergeStrategy = "merge"
)

type MergeableRule struct {
Spec any
Source string
// NewMergeableRule creates a new MergeableRule with a default source if the rule does not have one.
func NewMergeableRule(rule MergeableRule, defaultSource string) MergeableRule {
if rule.GetSource() == "" {
return rule.WithSource(defaultSource)
}
return rule
}

// MergeableRule is a policy rule that contains a spec which can be traced back to its source,
// i.e. to the policy where the rule spec was defined.
type MergeableRule interface {
GetSpec() any
GetSource() string
WithSource(string) MergeableRule
}

// +kubebuilder:object:generate=false
Expand All @@ -58,13 +69,11 @@ func AtomicDefaultsMergeStrategy(source, target machinery.Policy) machinery.Poli
return source
}

mergeableTargetPolicy := target.(MergeablePolicy)

if !mergeableTargetPolicy.Empty() {
return mergeableTargetPolicy.DeepCopyObject().(machinery.Policy)
if mergeableTarget := target.(MergeablePolicy); !mergeableTarget.Empty() {
return copyMergeablePolicy(mergeableTarget)
}

return source.(MergeablePolicy).DeepCopyObject().(machinery.Policy)
return copyMergeablePolicy(source.(MergeablePolicy))
}

var _ machinery.MergeStrategy = AtomicDefaultsMergeStrategy
Expand All @@ -75,7 +84,7 @@ func AtomicOverridesMergeStrategy(source, _ machinery.Policy) machinery.Policy {
if source == nil {
return nil
}
return source.(MergeablePolicy).DeepCopyObject().(machinery.Policy)
return copyMergeablePolicy(source.(MergeablePolicy))
}

var _ machinery.MergeStrategy = AtomicOverridesMergeStrategy
Expand All @@ -94,15 +103,16 @@ func PolicyRuleDefaultsMergeStrategy(source, target machinery.Policy) machinery.
targetMergeablePolicy := target.(MergeablePolicy)

// copy rules from the target
rules := targetMergeablePolicy.Rules()
rules := lo.MapValues(targetMergeablePolicy.Rules(), mapRuleWithSourceFunc(target))

// add extra rules from the source
for ruleID, rule := range sourceMergeablePolicy.Rules() {
if _, ok := targetMergeablePolicy.Rules()[ruleID]; !ok {
rules[ruleID] = MergeableRule{
Spec: rule.Spec,
Source: source.GetLocator(),
origin := rule.GetSource()
if origin == "" {
origin = source.GetLocator()
}
rules[ruleID] = rule.WithSource(origin)
}
}

Expand All @@ -121,12 +131,16 @@ func PolicyRuleOverridesMergeStrategy(source, target machinery.Policy) machinery
targetMergeablePolicy := target.(MergeablePolicy)

// copy rules from the source
rules := sourceMergeablePolicy.Rules()
rules := lo.MapValues(sourceMergeablePolicy.Rules(), mapRuleWithSourceFunc(source))

// add extra rules from the target
for ruleID, rule := range targetMergeablePolicy.Rules() {
if _, ok := sourceMergeablePolicy.Rules()[ruleID]; !ok {
rules[ruleID] = rule
origin := rule.GetSource()
if origin == "" {
origin = target.GetLocator()
}
rules[ruleID] = rule.WithSource(origin)
}
}

Expand Down Expand Up @@ -198,3 +212,15 @@ func PathID(path []machinery.Targetable) string {
return strings.TrimPrefix(k8stypes.NamespacedName{Namespace: t.GetNamespace(), Name: t.GetName()}.String(), string(k8stypes.Separator))
}), "|")
}

func mapRuleWithSourceFunc(source machinery.Policy) func(MergeableRule, string) MergeableRule {
return func(rule MergeableRule, _ string) MergeableRule {
return rule.WithSource(source.GetLocator())
}
}

func copyMergeablePolicy(policy MergeablePolicy) MergeablePolicy {
dup := policy.DeepCopyObject().(MergeablePolicy)
dup.SetRules(lo.MapValues(dup.Rules(), mapRuleWithSourceFunc(policy)))
return dup
}
42 changes: 33 additions & 9 deletions api/v1beta1/topology.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
package v1beta1

import (
authorinov1beta1 "github.com/kuadrant/authorino-operator/api/v1beta1"
authorinooperatorv1beta1 "github.com/kuadrant/authorino-operator/api/v1beta1"
authorinov1beta2 "github.com/kuadrant/authorino/api/v1beta2"
limitadorv1alpha1 "github.com/kuadrant/limitador-operator/api/v1alpha1"
"github.com/kuadrant/policy-machinery/controller"
"github.com/kuadrant/policy-machinery/machinery"
"github.com/samber/lo"
"k8s.io/apimachinery/pkg/runtime/schema"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1"
)

var (
AuthorinoGroupKind = schema.GroupKind{Group: authorinov1beta1.GroupVersion.Group, Kind: "Authorino"}
KuadrantGroupKind = schema.GroupKind{Group: GroupVersion.Group, Kind: "Kuadrant"}
LimitadorGroupKind = schema.GroupKind{Group: limitadorv1alpha1.GroupVersion.Group, Kind: "Limitador"}
KuadrantGroupKind = schema.GroupKind{Group: GroupVersion.Group, Kind: "Kuadrant"}
LimitadorGroupKind = schema.GroupKind{Group: limitadorv1alpha1.GroupVersion.Group, Kind: "Limitador"}
AuthorinoGroupKind = schema.GroupKind{Group: authorinooperatorv1beta1.GroupVersion.Group, Kind: "Authorino"}
AuthConfigGroupKind = schema.GroupKind{Group: authorinov1beta2.GroupVersion.Group, Kind: "AuthConfig"}

AuthorinosResource = authorinov1beta1.GroupVersion.WithResource("authorinos")
KuadrantsResource = GroupVersion.WithResource("kuadrants")
LimitadorsResource = limitadorv1alpha1.GroupVersion.WithResource("limitadors")
KuadrantsResource = GroupVersion.WithResource("kuadrants")
LimitadorsResource = limitadorv1alpha1.GroupVersion.WithResource("limitadors")
AuthorinosResource = authorinooperatorv1beta1.GroupVersion.WithResource("authorinos")
AuthConfigsResource = authorinov1beta2.GroupVersion.WithResource("authconfigs")

AuthConfigHTTPRouteRuleAnnotation = machinery.HTTPRouteRuleGroupKind.String()
)

var _ machinery.Object = &Kuadrant{}
Expand All @@ -31,7 +36,7 @@ func LinkKuadrantToGatewayClasses(objs controller.Store) machinery.LinkFunc {

return machinery.LinkFunc{
From: KuadrantGroupKind,
To: schema.GroupKind{Group: gwapiv1.GroupVersion.Group, Kind: "GatewayClass"},
To: schema.GroupKind{Group: gatewayapiv1.GroupVersion.Group, Kind: "GatewayClass"},
Func: func(_ machinery.Object) []machinery.Object {
parents := make([]machinery.Object, len(kuadrants))
for _, parent := range kuadrants {
Expand Down Expand Up @@ -69,3 +74,22 @@ func LinkKuadrantToAuthorino(objs controller.Store) machinery.LinkFunc {
},
}
}

func LinkHTTPRouteRuleToAuthConfig(objs controller.Store) machinery.LinkFunc {
httpRoutes := lo.Map(objs.FilterByGroupKind(machinery.HTTPRouteGroupKind), controller.ObjectAs[*gatewayapiv1.HTTPRoute])
httpRouteRules := lo.FlatMap(lo.Map(httpRoutes, func(r *gatewayapiv1.HTTPRoute, _ int) *machinery.HTTPRoute {
return &machinery.HTTPRoute{HTTPRoute: r}
}), machinery.HTTPRouteRulesFromHTTPRouteFunc)

return machinery.LinkFunc{
From: machinery.HTTPRouteRuleGroupKind,
To: AuthConfigGroupKind,
Func: func(child machinery.Object) []machinery.Object {
return lo.FilterMap(httpRouteRules, func(httpRouteRule *machinery.HTTPRouteRule, _ int) (machinery.Object, bool) {
authConfig := child.(*controller.RuntimeObject).Object.(*authorinov1beta2.AuthConfig)
annotations := authConfig.GetAnnotations()
return httpRouteRule, annotations != nil && annotations[AuthConfigHTTPRouteRuleAnnotation] == httpRouteRule.GetLocator()
})
},
}
}
Loading

0 comments on commit cb75a5f

Please sign in to comment.