Skip to content

Commit eb111d6

Browse files
authored
feat: OIDC authorization in Feast Operator (#4801)
* Initial commit Signed-off-by: Daniele Martinoli <dmartino@redhat.com> * no private image Signed-off-by: Daniele Martinoli <dmartino@redhat.com> * removed nameLabelKey, using serices.NameLabelKey Signed-off-by: Daniele Martinoli <dmartino@redhat.com> * improved CRD comments and using IsLocalRegistry Signed-off-by: Daniele Martinoli <dmartino@redhat.com> * fixing generated code Signed-off-by: Daniele Martinoli <dmartino@redhat.com> * renamed auth condition and types Signed-off-by: Daniele Martinoli <dmartino@redhat.com> * more renamings Signed-off-by: Daniele Martinoli <dmartino@redhat.com> * initial commit Signed-off-by: Daniele Martinoli <dmartino@redhat.com> * oidc IT Signed-off-by: Daniele Martinoli <dmartino@redhat.com> * with sample Signed-off-by: Daniele Martinoli <dmartino@redhat.com> * no private image Signed-off-by: Daniele Martinoli <dmartino@redhat.com> --------- Signed-off-by: Daniele Martinoli <dmartino@redhat.com>
1 parent 8181e9d commit eb111d6

16 files changed

+1035
-45
lines changed

infra/feast-operator/api/v1alpha1/featurestore_types.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,10 @@ type OptionalConfigs struct {
280280
}
281281

282282
// AuthzConfig defines the authorization settings for the deployed Feast services.
283+
// +kubebuilder:validation:XValidation:rule="[has(self.kubernetes), has(self.oidc)].exists_one(c, c)",message="One selection required between kubernetes or oidc."
283284
type AuthzConfig struct {
284285
KubernetesAuthz *KubernetesAuthz `json:"kubernetes,omitempty"`
286+
OidcAuthz *OidcAuthz `json:"oidc,omitempty"`
285287
}
286288

287289
// KubernetesAuthz provides a way to define the authorization settings using Kubernetes RBAC resources.
@@ -296,6 +298,12 @@ type KubernetesAuthz struct {
296298
Roles []string `json:"roles,omitempty"`
297299
}
298300

301+
// OidcAuthz defines the authorization settings for deployments using an Open ID Connect identity provider.
302+
// https://auth0.com/docs/authenticate/protocols/openid-connect-protocol
303+
type OidcAuthz struct {
304+
SecretRef corev1.LocalObjectReference `json:"secretRef"`
305+
}
306+
299307
// TlsConfigs configures server TLS for a feast service. in an openshift cluster, this is configured by default using service serving certificates.
300308
// +kubebuilder:validation:XValidation:rule="(!has(self.disable) || !self.disable) ? has(self.secretRef) : true",message="`secretRef` required if `disable` is false."
301309
type TlsConfigs struct {

infra/feast-operator/api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

infra/feast-operator/config/crd/bases/feast.dev_featurestores.yaml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,31 @@ spec:
6969
type: string
7070
type: array
7171
type: object
72+
oidc:
73+
description: |-
74+
OidcAuthz defines the authorization settings for deployments using an Open ID Connect identity provider.
75+
https://auth0.com/docs/authenticate/protocols/openid-connect-protocol
76+
properties:
77+
secretRef:
78+
description: |-
79+
LocalObjectReference contains enough information to let you locate the
80+
referenced object inside the same namespace.
81+
properties:
82+
name:
83+
description: |-
84+
Name of the referent.
85+
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
86+
TODO: Add other useful fields. apiVersion, kind, uid?
87+
type: string
88+
type: object
89+
x-kubernetes-map-type: atomic
90+
required:
91+
- secretRef
92+
type: object
7293
type: object
94+
x-kubernetes-validations:
95+
- message: One selection required between kubernetes or oidc.
96+
rule: '[has(self.kubernetes), has(self.oidc)].exists_one(c, c)'
7397
feastProject:
7498
description: FeastProject is the Feast project id. This can be any
7599
alphanumeric string with underscores, but it cannot start with an
@@ -1238,7 +1262,32 @@ spec:
12381262
type: string
12391263
type: array
12401264
type: object
1265+
oidc:
1266+
description: |-
1267+
OidcAuthz defines the authorization settings for deployments using an Open ID Connect identity provider.
1268+
https://auth0.com/docs/authenticate/protocols/openid-connect-protocol
1269+
properties:
1270+
secretRef:
1271+
description: |-
1272+
LocalObjectReference contains enough information to let you locate the
1273+
referenced object inside the same namespace.
1274+
properties:
1275+
name:
1276+
description: |-
1277+
Name of the referent.
1278+
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
1279+
TODO: Add other useful fields. apiVersion, kind, uid?
1280+
type: string
1281+
type: object
1282+
x-kubernetes-map-type: atomic
1283+
required:
1284+
- secretRef
1285+
type: object
12411286
type: object
1287+
x-kubernetes-validations:
1288+
- message: One selection required between kubernetes or oidc.
1289+
rule: '[has(self.kubernetes), has(self.oidc)].exists_one(c,
1290+
c)'
12421291
feastProject:
12431292
description: FeastProject is the Feast project id. This can be
12441293
any alphanumeric string with underscores, but it cannot start
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
apiVersion: feast.dev/v1alpha1
2+
kind: FeatureStore
3+
metadata:
4+
name: sample-oidc-auth
5+
spec:
6+
feastProject: my_project
7+
services:
8+
onlineStore:
9+
persistence:
10+
file:
11+
path: /data/online_store.db
12+
offlineStore:
13+
persistence:
14+
file:
15+
type: dask
16+
registry:
17+
local:
18+
persistence:
19+
file:
20+
path: /data/registry.db
21+
authz:
22+
oidc:
23+
secretRef:
24+
name: oidc-secret
25+
---
26+
kind: Secret
27+
apiVersion: v1
28+
metadata:
29+
name: oidc-secret
30+
stringData:
31+
client_id: client_id
32+
auth_discovery_url: auth_discovery_url
33+
client_secret: client_secret
34+
username: username
35+
password: password

infra/feast-operator/dist/install.yaml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,31 @@ spec:
7777
type: string
7878
type: array
7979
type: object
80+
oidc:
81+
description: |-
82+
OidcAuthz defines the authorization settings for deployments using an Open ID Connect identity provider.
83+
https://auth0.com/docs/authenticate/protocols/openid-connect-protocol
84+
properties:
85+
secretRef:
86+
description: |-
87+
LocalObjectReference contains enough information to let you locate the
88+
referenced object inside the same namespace.
89+
properties:
90+
name:
91+
description: |-
92+
Name of the referent.
93+
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
94+
TODO: Add other useful fields. apiVersion, kind, uid?
95+
type: string
96+
type: object
97+
x-kubernetes-map-type: atomic
98+
required:
99+
- secretRef
100+
type: object
80101
type: object
102+
x-kubernetes-validations:
103+
- message: One selection required between kubernetes or oidc.
104+
rule: '[has(self.kubernetes), has(self.oidc)].exists_one(c, c)'
81105
feastProject:
82106
description: FeastProject is the Feast project id. This can be any
83107
alphanumeric string with underscores, but it cannot start with an
@@ -1246,7 +1270,32 @@ spec:
12461270
type: string
12471271
type: array
12481272
type: object
1273+
oidc:
1274+
description: |-
1275+
OidcAuthz defines the authorization settings for deployments using an Open ID Connect identity provider.
1276+
https://auth0.com/docs/authenticate/protocols/openid-connect-protocol
1277+
properties:
1278+
secretRef:
1279+
description: |-
1280+
LocalObjectReference contains enough information to let you locate the
1281+
referenced object inside the same namespace.
1282+
properties:
1283+
name:
1284+
description: |-
1285+
Name of the referent.
1286+
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
1287+
TODO: Add other useful fields. apiVersion, kind, uid?
1288+
type: string
1289+
type: object
1290+
x-kubernetes-map-type: atomic
1291+
required:
1292+
- secretRef
1293+
type: object
12491294
type: object
1295+
x-kubernetes-validations:
1296+
- message: One selection required between kubernetes or oidc.
1297+
rule: '[has(self.kubernetes), has(self.oidc)].exists_one(c,
1298+
c)'
12501299
feastProject:
12511300
description: FeastProject is the Feast project id. This can be
12521301
any alphanumeric string with underscores, but it cannot start

infra/feast-operator/internal/controller/authz/authz.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,13 @@ import (
1818
// Deploy the feast authorization
1919
func (authz *FeastAuthorization) Deploy() error {
2020
if authz.isKubernetesAuth() {
21-
if err := authz.deployKubernetesAuth(); err != nil {
22-
return err
23-
}
24-
} else {
25-
authz.removeOrphanedRoles()
26-
_ = authz.Handler.DeleteOwnedFeastObj(authz.initFeastRole())
27-
_ = authz.Handler.DeleteOwnedFeastObj(authz.initFeastRoleBinding())
28-
apimeta.RemoveStatusCondition(&authz.Handler.FeatureStore.Status.Conditions, feastKubernetesAuthConditions[metav1.ConditionTrue].Type)
21+
return authz.deployKubernetesAuth()
2922
}
23+
24+
authz.removeOrphanedRoles()
25+
_ = authz.Handler.DeleteOwnedFeastObj(authz.initFeastRole())
26+
_ = authz.Handler.DeleteOwnedFeastObj(authz.initFeastRoleBinding())
27+
apimeta.RemoveStatusCondition(&authz.Handler.FeatureStore.Status.Conditions, feastKubernetesAuthConditions[metav1.ConditionTrue].Type)
3028
return nil
3129
}
3230

infra/feast-operator/internal/controller/featurestore_controller_kubernetes_auth_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,9 +333,9 @@ var _ = Describe("FeatureStore Controller-Kubernetes authorization", func() {
333333
Expect(err).To(HaveOccurred())
334334
Expect(errors.IsNotFound(err)).To(BeTrue())
335335

336-
By("Clearing the kubernetes authorizatino and reconciling")
336+
By("Clearing the kubernetes authorization and reconciling")
337337
resourceNew = resource.DeepCopy()
338-
resourceNew.Spec.AuthzConfig = &feastdevv1alpha1.AuthzConfig{}
338+
resourceNew.Spec.AuthzConfig = nil
339339
err = k8sClient.Update(ctx, resourceNew)
340340
Expect(err).NotTo(HaveOccurred())
341341
_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{

0 commit comments

Comments
 (0)