Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,7 @@
"filename": "infra/feast-operator/api/v1/featurestore_types.go",
"hashed_secret": "44e17306b837162269a410204daaa5ecee4ec22c",
"is_verified": false,
"line_number": 958
"line_number": 963
}
],
"infra/feast-operator/api/v1/zz_generated.deepcopy.go": [
Expand All @@ -966,21 +966,21 @@
"filename": "infra/feast-operator/api/v1/zz_generated.deepcopy.go",
"hashed_secret": "f914fc9324de1bec1ad13dec94a8ea2ddb41fc87",
"is_verified": false,
"line_number": 842
"line_number": 847
},
{
"type": "Secret Keyword",
"filename": "infra/feast-operator/api/v1/zz_generated.deepcopy.go",
"hashed_secret": "44e17306b837162269a410204daaa5ecee4ec22c",
"is_verified": false,
"line_number": 903
"line_number": 908
},
{
"type": "Secret Keyword",
"filename": "infra/feast-operator/api/v1/zz_generated.deepcopy.go",
"hashed_secret": "c2028031c154bbe86fd69bef740855c74b927dcf",
"is_verified": false,
"line_number": 1595
"line_number": 1600
}
],
"infra/feast-operator/api/v1alpha1/featurestore_types.go": [
Expand All @@ -989,7 +989,7 @@
"filename": "infra/feast-operator/api/v1alpha1/featurestore_types.go",
"hashed_secret": "44e17306b837162269a410204daaa5ecee4ec22c",
"is_verified": false,
"line_number": 663
"line_number": 668
}
],
"infra/feast-operator/api/v1alpha1/zz_generated.deepcopy.go": [
Expand All @@ -998,21 +998,21 @@
"filename": "infra/feast-operator/api/v1alpha1/zz_generated.deepcopy.go",
"hashed_secret": "f914fc9324de1bec1ad13dec94a8ea2ddb41fc87",
"is_verified": false,
"line_number": 615
"line_number": 620
},
{
"type": "Secret Keyword",
"filename": "infra/feast-operator/api/v1alpha1/zz_generated.deepcopy.go",
"hashed_secret": "44e17306b837162269a410204daaa5ecee4ec22c",
"is_verified": false,
"line_number": 1123
"line_number": 1128
},
{
"type": "Secret Keyword",
"filename": "infra/feast-operator/api/v1alpha1/zz_generated.deepcopy.go",
"hashed_secret": "c2028031c154bbe86fd69bef740855c74b927dcf",
"is_verified": false,
"line_number": 1128
"line_number": 1133
}
],
"infra/feast-operator/bundle/manifests/openlineage-secret_v1_secret.yaml": [
Expand Down Expand Up @@ -1147,7 +1147,7 @@
"filename": "infra/feast-operator/internal/controller/featurestore_controller_oidc_auth_test.go",
"hashed_secret": "a1f14fc6f33ba39a8b6d006fefa6fe0fe8d60ae2",
"is_verified": false,
"line_number": 450
"line_number": 449
}
],
"infra/feast-operator/internal/controller/featurestore_controller_test_utils_test.go": [
Expand Down Expand Up @@ -1564,5 +1564,5 @@
}
]
},
"generated_at": "2026-07-31T05:29:18Z"
"generated_at": "2026-08-13T17:14:16Z"
}
70 changes: 69 additions & 1 deletion docs/getting-started/components/authz_manager.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,89 @@ the authorization tokens that the server can properly identify and use to enforc
The server-side implementation of the authorization functionality is defined [here](./../../../sdk/python/feast/permissions/server).
Few of the key models, classes to understand the authorization implementation on the client side can be found [here](./../../../sdk/python/feast/permissions/client).

## Default Authorization Behavior

### Feast Operator (Kubernetes Deployments)

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.

This follows an **"Authenticated by Default, Authorized Gradually"** security model:
- All Feast endpoints require a valid Kubernetes bearer token by default.
- 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.
- Unauthenticated requests are rejected.

This ensures that Feast deployments are never accidentally exposed without authentication, while allowing teams to incrementally adopt fine-grained RBAC.

#### Disabling Authentication with `noAuth`

For development, testing, or environments where authentication is handled externally, you can explicitly disable authentication using the `noAuth` option in the `FeatureStore` CR:

```yaml
apiVersion: feast.dev/v1
kind: FeatureStore
metadata:
name: my-feature-store
spec:
feastProject: my_project
authz:
noAuth: true
```

{% hint style="warning" %}
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.
{% endhint %}

#### Explicit Kubernetes Auth (Default)

This is equivalent to the default behavior when no `authz` section is provided:

```yaml
apiVersion: feast.dev/v1
kind: FeatureStore
metadata:
name: my-feature-store
spec:
feastProject: my_project
authz:
kubernetes: {}
```

#### OIDC Auth via Operator

```yaml
apiVersion: feast.dev/v1
kind: FeatureStore
metadata:
name: my-feature-store
spec:
feastProject: my_project
authz:
oidc:
secretRef:
name: feast-oidc-secret
```

### Standalone Deployments (feature_store.yaml)

## Configuring Authorization
The authorization is configured using a dedicated `auth` section in the `feature_store.yaml` configuration.

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

### No Authorization
This configuration applies the default `no_auth` authorization:
This configuration applies the `no_auth` authorization:
```yaml
project: my-project
auth:
type: no_auth
...
```

{% hint style="warning" %}
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.
{% endhint %}

### OIDC Authorization
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/))
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).
Expand Down
54 changes: 51 additions & 3 deletions docs/reference/auth/kubernetes_auth_setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,45 @@ Feast supports extracting user groups, namespaces and roles of both Service Acco
- **Namespaces**: Kubernetes namespaces associated with User/SA
- **Roles**: Kubernetes roles associated with User/SA

## Operator Default Behavior

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.

### What This Means

- All HTTP/gRPC requests to Feast services must include a valid Kubernetes bearer token in the `Authorization` header.
- The server validates the token via the Kubernetes Token Access Review API and extracts user identity (username, groups, namespaces, roles).
- If no `Permission` objects are defined, authenticated users get full access (with a warning logged).
- Unauthenticated requests receive a `401 Unauthorized` response.

### Disabling Authentication

If you need to run Feast without authentication (e.g., for local development or testing), explicitly set `noAuth: true` in the `FeatureStore` CR:

```yaml
apiVersion: feast.dev/v1
kind: FeatureStore
metadata:
name: my-feature-store
spec:
feastProject: my_project
authz:
noAuth: true
```

{% hint style="warning" %}
`noAuth: true` disables all authentication and authorization checks. All endpoints become publicly accessible. Use only in non-production environments.
{% endhint %}

### Choosing an Auth Mode

| `spec.authz` Setting | Behavior |
| --- | --- |
| _(not specified)_ | Kubernetes auth enabled (default) |
| `kubernetes: {}` | Kubernetes auth enabled (explicit) |
| `oidc: { ... }` | OIDC auth enabled |
| `noAuth: true` | All auth disabled |

## Key Features

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

### Common Issues

1. **Token Access Review Fails**
1. **401 Unauthorized After Upgrading**
- The Feast operator now defaults to Kubernetes authentication. If your existing FeatureStore CR did not specify `authz`, the upgrade enables auth automatically.
- **Quick fix for testing**: Add `authz.noAuth: true` to your `FeatureStore` CR to restore the previous unauthenticated behavior.
- **Recommended**: Update your client applications to include a valid Kubernetes bearer token in requests.

2. **Token Access Review Fails**
- Check that the Feast server has the required RBAC permissions
- Verify the token is valid and not expired
- Check server logs for detailed error messages in debug mode

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

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

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

## Migration Guide

### From Role-Based to Group/Namespace-Based
Expand Down
7 changes: 6 additions & 1 deletion infra/feast-operator/api/v1/featurestore_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -889,10 +889,15 @@ type OptionalCtrConfigs struct {
}

// AuthzConfig defines the authorization settings for the deployed Feast services.
// +kubebuilder:validation:XValidation:rule="[has(self.kubernetes), has(self.oidc)].exists_one(c, c)",message="One selection required between kubernetes or oidc."
// +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."
type AuthzConfig struct {
KubernetesAuthz *KubernetesAuthz `json:"kubernetes,omitempty"`
OidcAuthz *OidcAuthz `json:"oidc,omitempty"`
// NoAuth explicitly disables authentication and authorization.
// When set to true, Feast services run without any auth checks.
// Use only for development or testing environments.
// +optional
NoAuth *bool `json:"noAuth,omitempty"`
}

// KubernetesAuthz provides a way to define the authorization settings using Kubernetes RBAC resources.
Expand Down
5 changes: 5 additions & 0 deletions infra/feast-operator/api/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion infra/feast-operator/api/v1alpha1/featurestore_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -621,10 +621,15 @@ type OptionalCtrConfigs struct {
}

// AuthzConfig defines the authorization settings for the deployed Feast services.
// +kubebuilder:validation:XValidation:rule="[has(self.kubernetes), has(self.oidc)].exists_one(c, c)",message="One selection required between kubernetes or oidc."
// +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."
type AuthzConfig struct {
KubernetesAuthz *KubernetesAuthz `json:"kubernetes,omitempty"`
OidcAuthz *OidcAuthz `json:"oidc,omitempty"`
// NoAuth explicitly disables authentication and authorization.
// When set to true, Feast services run without any auth checks.
// Use only for development or testing environments.
// +optional
NoAuth *bool `json:"noAuth,omitempty"`
}

// KubernetesAuthz provides a way to define the authorization settings using Kubernetes RBAC resources.
Expand Down
5 changes: 5 additions & 0 deletions infra/feast-operator/api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading