Skip to content

Commit c64c0a8

Browse files
fix: Default authentication to kubernetes auth
Signed-off-by: ntkathole <nikhilkathole2683@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: ntkathole <nikhilkathole2683@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent a9219d9 commit c64c0a8

27 files changed

Lines changed: 355 additions & 112 deletions

.secrets.baseline

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -957,7 +957,7 @@
957957
"filename": "infra/feast-operator/api/v1/featurestore_types.go",
958958
"hashed_secret": "44e17306b837162269a410204daaa5ecee4ec22c",
959959
"is_verified": false,
960-
"line_number": 958
960+
"line_number": 963
961961
}
962962
],
963963
"infra/feast-operator/api/v1/zz_generated.deepcopy.go": [
@@ -966,21 +966,21 @@
966966
"filename": "infra/feast-operator/api/v1/zz_generated.deepcopy.go",
967967
"hashed_secret": "f914fc9324de1bec1ad13dec94a8ea2ddb41fc87",
968968
"is_verified": false,
969-
"line_number": 842
969+
"line_number": 847
970970
},
971971
{
972972
"type": "Secret Keyword",
973973
"filename": "infra/feast-operator/api/v1/zz_generated.deepcopy.go",
974974
"hashed_secret": "44e17306b837162269a410204daaa5ecee4ec22c",
975975
"is_verified": false,
976-
"line_number": 903
976+
"line_number": 908
977977
},
978978
{
979979
"type": "Secret Keyword",
980980
"filename": "infra/feast-operator/api/v1/zz_generated.deepcopy.go",
981981
"hashed_secret": "c2028031c154bbe86fd69bef740855c74b927dcf",
982982
"is_verified": false,
983-
"line_number": 1595
983+
"line_number": 1600
984984
}
985985
],
986986
"infra/feast-operator/api/v1alpha1/featurestore_types.go": [
@@ -989,7 +989,7 @@
989989
"filename": "infra/feast-operator/api/v1alpha1/featurestore_types.go",
990990
"hashed_secret": "44e17306b837162269a410204daaa5ecee4ec22c",
991991
"is_verified": false,
992-
"line_number": 663
992+
"line_number": 668
993993
}
994994
],
995995
"infra/feast-operator/api/v1alpha1/zz_generated.deepcopy.go": [
@@ -998,21 +998,21 @@
998998
"filename": "infra/feast-operator/api/v1alpha1/zz_generated.deepcopy.go",
999999
"hashed_secret": "f914fc9324de1bec1ad13dec94a8ea2ddb41fc87",
10001000
"is_verified": false,
1001-
"line_number": 615
1001+
"line_number": 620
10021002
},
10031003
{
10041004
"type": "Secret Keyword",
10051005
"filename": "infra/feast-operator/api/v1alpha1/zz_generated.deepcopy.go",
10061006
"hashed_secret": "44e17306b837162269a410204daaa5ecee4ec22c",
10071007
"is_verified": false,
1008-
"line_number": 1123
1008+
"line_number": 1128
10091009
},
10101010
{
10111011
"type": "Secret Keyword",
10121012
"filename": "infra/feast-operator/api/v1alpha1/zz_generated.deepcopy.go",
10131013
"hashed_secret": "c2028031c154bbe86fd69bef740855c74b927dcf",
10141014
"is_verified": false,
1015-
"line_number": 1128
1015+
"line_number": 1133
10161016
}
10171017
],
10181018
"infra/feast-operator/bundle/manifests/openlineage-secret_v1_secret.yaml": [
@@ -1147,7 +1147,7 @@
11471147
"filename": "infra/feast-operator/internal/controller/featurestore_controller_oidc_auth_test.go",
11481148
"hashed_secret": "a1f14fc6f33ba39a8b6d006fefa6fe0fe8d60ae2",
11491149
"is_verified": false,
1150-
"line_number": 450
1150+
"line_number": 449
11511151
}
11521152
],
11531153
"infra/feast-operator/internal/controller/featurestore_controller_test_utils_test.go": [
@@ -1564,5 +1564,5 @@
15641564
}
15651565
]
15661566
},
1567-
"generated_at": "2026-07-31T05:29:18Z"
1567+
"generated_at": "2026-08-13T17:14:16Z"
15681568
}

docs/getting-started/components/authz_manager.md

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,89 @@ the authorization tokens that the server can properly identify and use to enforc
2121
The server-side implementation of the authorization functionality is defined [here](./../../../sdk/python/feast/permissions/server).
2222
Few of the key models, classes to understand the authorization implementation on the client side can be found [here](./../../../sdk/python/feast/permissions/client).
2323

24+
## Default Authorization Behavior
25+
26+
### Feast Operator (Kubernetes Deployments)
27+
28+
When deploying Feast using the [Feast operator](../../../infra/feast-operator/docs/api/markdown/ref.md), **Kubernetes authentication is enabled by default**. If no `authz` section is specified in the `FeatureStore` CR, the operator automatically configures `kubernetes` auth for all deployed services.
29+
30+
This follows an **"Authenticated by Default, Authorized Gradually"** security model:
31+
- All Feast endpoints require a valid Kubernetes bearer token by default.
32+
- If no explicit `Permission` objects are defined (via `permissions.py` + `feast apply`), **all authenticated users are granted full access**. A warning is logged to remind administrators to define fine-grained permissions.
33+
- Unauthenticated requests are rejected.
34+
35+
This ensures that Feast deployments are never accidentally exposed without authentication, while allowing teams to incrementally adopt fine-grained RBAC.
36+
37+
#### Disabling Authentication with `noAuth`
38+
39+
For development, testing, or environments where authentication is handled externally, you can explicitly disable authentication using the `noAuth` option in the `FeatureStore` CR:
40+
41+
```yaml
42+
apiVersion: feast.dev/v1
43+
kind: FeatureStore
44+
metadata:
45+
name: my-feature-store
46+
spec:
47+
feastProject: my_project
48+
authz:
49+
noAuth: true
50+
```
51+
52+
{% hint style="warning" %}
53+
Setting `noAuth: true` disables all authentication and authorization. All endpoints become publicly accessible without any identity checks. Only use this for local development or testing environments. For production, use `kubernetes` or `oidc` authentication.
54+
{% endhint %}
55+
56+
#### Explicit Kubernetes Auth (Default)
57+
58+
This is equivalent to the default behavior when no `authz` section is provided:
59+
60+
```yaml
61+
apiVersion: feast.dev/v1
62+
kind: FeatureStore
63+
metadata:
64+
name: my-feature-store
65+
spec:
66+
feastProject: my_project
67+
authz:
68+
kubernetes: {}
69+
```
70+
71+
#### OIDC Auth via Operator
72+
73+
```yaml
74+
apiVersion: feast.dev/v1
75+
kind: FeatureStore
76+
metadata:
77+
name: my-feature-store
78+
spec:
79+
feastProject: my_project
80+
authz:
81+
oidc:
82+
secretRef:
83+
name: feast-oidc-secret
84+
```
85+
86+
### Standalone Deployments (feature_store.yaml)
87+
2488
## Configuring Authorization
2589
The authorization is configured using a dedicated `auth` section in the `feature_store.yaml` configuration.
2690

2791
**Note**: As a consequence, when deploying the Feast servers with the Helm [charts](../../../infra/charts/feast-feature-server/README.md),
2892
the `feature_store_yaml_base64` value must include the `auth` section to specify the authorization configuration.
2993

3094
### No Authorization
31-
This configuration applies the default `no_auth` authorization:
95+
This configuration applies the `no_auth` authorization:
3296
```yaml
3397
project: my-project
3498
auth:
3599
type: no_auth
36100
...
37101
```
38102

103+
{% hint style="warning" %}
104+
Running with `auth.type: no_auth` leaves all endpoints unauthenticated. This is suitable for local development only. For production deployments, configure `kubernetes` or `oidc` authentication.
105+
{% endhint %}
106+
39107
### OIDC Authorization
40108
With OIDC authorization, the Feast client proxies retrieve the JWT token from an OIDC server (or [Identity Provider](https://openid.net/developers/how-connect-works/))
41109
and append it in every request to a Feast server, using an [Authorization Bearer Token](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#bearer).

docs/reference/auth/kubernetes_auth_setup.md

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,45 @@ Feast supports extracting user groups, namespaces and roles of both Service Acco
1010
- **Namespaces**: Kubernetes namespaces associated with User/SA
1111
- **Roles**: Kubernetes roles associated with User/SA
1212

13+
## Operator Default Behavior
14+
15+
When deploying Feast using the Feast operator, **Kubernetes authentication is enabled by default**. You do not need to explicitly configure `authz` in the `FeatureStore` CR — the operator automatically applies `kubernetes` auth to all deployed services.
16+
17+
### What This Means
18+
19+
- All HTTP/gRPC requests to Feast services must include a valid Kubernetes bearer token in the `Authorization` header.
20+
- The server validates the token via the Kubernetes Token Access Review API and extracts user identity (username, groups, namespaces, roles).
21+
- If no `Permission` objects are defined, authenticated users get full access (with a warning logged).
22+
- Unauthenticated requests receive a `401 Unauthorized` response.
23+
24+
### Disabling Authentication
25+
26+
If you need to run Feast without authentication (e.g., for local development or testing), explicitly set `noAuth: true` in the `FeatureStore` CR:
27+
28+
```yaml
29+
apiVersion: feast.dev/v1
30+
kind: FeatureStore
31+
metadata:
32+
name: my-feature-store
33+
spec:
34+
feastProject: my_project
35+
authz:
36+
noAuth: true
37+
```
38+
39+
{% hint style="warning" %}
40+
`noAuth: true` disables all authentication and authorization checks. All endpoints become publicly accessible. Use only in non-production environments.
41+
{% endhint %}
42+
43+
### Choosing an Auth Mode
44+
45+
| `spec.authz` Setting | Behavior |
46+
| --- | --- |
47+
| _(not specified)_ | Kubernetes auth enabled (default) |
48+
| `kubernetes: {}` | Kubernetes auth enabled (explicit) |
49+
| `oidc: { ... }` | OIDC auth enabled |
50+
| `noAuth: true` | All auth disabled |
51+
1352
## Key Features
1453

1554
### Setting Up Kubernetes RBAC for Feast
@@ -142,20 +181,29 @@ Run `feast apply` from CLI/API/SDK on server or from client(if permitted) to app
142181

143182
### Common Issues
144183

145-
1. **Token Access Review Fails**
184+
1. **401 Unauthorized After Upgrading**
185+
- The Feast operator now defaults to Kubernetes authentication. If your existing FeatureStore CR did not specify `authz`, the upgrade enables auth automatically.
186+
- **Quick fix for testing**: Add `authz.noAuth: true` to your `FeatureStore` CR to restore the previous unauthenticated behavior.
187+
- **Recommended**: Update your client applications to include a valid Kubernetes bearer token in requests.
188+
189+
2. **Token Access Review Fails**
146190
- Check that the Feast server has the required RBAC permissions
147191
- Verify the token is valid and not expired
148192
- Check server logs for detailed error messages in debug mode
149193

150-
2. **Groups/Namespaces Not Extracted**
194+
3. **Groups/Namespaces Not Extracted**
151195
- Verify the token contains the expected claims
152196
- Check that the user is properly configured in Kubernetes/ODH/RHOAI
153197

154-
3. **Permission Denied**
198+
4. **Permission Denied**
155199
- Verify the user is added to required groups/namespaces Or has the required role assigned
156200
- Check that the policy is correctly configured
157201
- Review the permission evaluation logs
158202

203+
5. **"No permissions defined" Warning in Logs**
204+
- This is expected when Kubernetes auth is enabled but no `Permission` objects have been applied.
205+
- Authenticated users get full access by default. Define permissions via `permissions.py` + `feast apply` to enforce fine-grained authorization.
206+
159207
## Migration Guide
160208

161209
### From Role-Based to Group/Namespace-Based

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -889,10 +889,15 @@ type OptionalCtrConfigs struct {
889889
}
890890

891891
// AuthzConfig defines the authorization settings for the deployed Feast services.
892-
// +kubebuilder:validation:XValidation:rule="[has(self.kubernetes), has(self.oidc)].exists_one(c, c)",message="One selection required between kubernetes or oidc."
892+
// +kubebuilder:validation:XValidation:rule="[has(self.kubernetes), has(self.oidc), has(self.noAuth)].exists_one(c, c)",message="One selection required between kubernetes, oidc, or noAuth."
893893
type AuthzConfig struct {
894894
KubernetesAuthz *KubernetesAuthz `json:"kubernetes,omitempty"`
895895
OidcAuthz *OidcAuthz `json:"oidc,omitempty"`
896+
// NoAuth explicitly disables authentication and authorization.
897+
// When set to true, Feast services run without any auth checks.
898+
// Use only for development or testing environments.
899+
// +optional
900+
NoAuth *bool `json:"noAuth,omitempty"`
896901
}
897902

898903
// KubernetesAuthz provides a way to define the authorization settings using Kubernetes RBAC resources.

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

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

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,10 +621,15 @@ type OptionalCtrConfigs struct {
621621
}
622622

623623
// AuthzConfig defines the authorization settings for the deployed Feast services.
624-
// +kubebuilder:validation:XValidation:rule="[has(self.kubernetes), has(self.oidc)].exists_one(c, c)",message="One selection required between kubernetes or oidc."
624+
// +kubebuilder:validation:XValidation:rule="[has(self.kubernetes), has(self.oidc), has(self.noAuth)].exists_one(c, c)",message="One selection required between kubernetes, oidc, or noAuth."
625625
type AuthzConfig struct {
626626
KubernetesAuthz *KubernetesAuthz `json:"kubernetes,omitempty"`
627627
OidcAuthz *OidcAuthz `json:"oidc,omitempty"`
628+
// NoAuth explicitly disables authentication and authorization.
629+
// When set to true, Feast services run without any auth checks.
630+
// Use only for development or testing environments.
631+
// +optional
632+
NoAuth *bool `json:"noAuth,omitempty"`
628633
}
629634

630635
// KubernetesAuthz provides a way to define the authorization settings using Kubernetes RBAC resources.

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

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

0 commit comments

Comments
 (0)