Skip to content

Latest commit

 

History

History
220 lines (174 loc) · 8.32 KB

File metadata and controls

220 lines (174 loc) · 8.32 KB

Guide 5 — Security

The operator supports two authorization models via spec.authz, plus TLS for all servers. Authorization is optional — omitting authz deploys Feast with no access control.


Kubernetes RBAC authorization

Kubernetes RBAC authorization uses ServiceAccount tokens. The operator creates ClusterRoles for each named role you declare and binds them to ServiceAccounts. Feast servers enforce these roles on every API call.

apiVersion: feast.dev/v1
kind: FeatureStore
metadata:
  name: sample-rbac
spec:
  feastProject: feast_rbac
  authz:
    kubernetes:
      roles:
        - feast-writer     # created as a ClusterRole
        - feast-reader
  services:
    offlineStore:
      server: {}
    onlineStore:
      server: {}
    registry:
      local:
        server: {}

The operator creates ClusterRole resources named after each entry in roles. Bind them to subjects using standard Kubernetes ClusterRoleBinding or RoleBinding resources.

Kubernetes auth requires all services to be exposed as servers (the controller rejects partial configurations where some services are local while RBAC is enabled).

SDK docs: Feast RBAC


OIDC authorization

OIDC authorization validates Bearer tokens against an OIDC provider (Keycloak, Dex, etc.).

Secret format

Create a Secret with the OIDC client credentials:

apiVersion: v1
kind: Secret
metadata:
  name: oidc-secret
stringData:
  client_id: <your-client-id>
  auth_discovery_url: https://keycloak.example.com/realms/feast/.well-known/openid-configuration
  client_secret: <your-client-secret>
  username: <service-account-username>     # used for client-credentials flow
  password: <service-account-password>
  audience: <expected-aud-claim>           # optional: reject tokens whose aud claim differs
  issuer: <expected-iss-claim>             # optional: reject tokens whose iss claim differs

The optional audience and issuer keys enable audience and issuer claim verification on the standard OIDC/JWKS validation path; when omitted, the aud and iss claims are not checked. Set them to the values your IdP puts in the token itself, which are not always the ones in the discovery document (see OIDC Authorization). The Secret key issuer is distinct from the CR's issuerUrl, which selects the discovery endpoint and plays no part in claim verification. Kubernetes ServiceAccount tokens (validated via TokenReview) and intra-server communication follow separate paths and are not subject to these checks.

{% hint style="warning" %} Before enabling these, three operational caveats:

  • Existing Secret keys take effect on operator upgrade. Keys named audience or issuer already present in the referenced Secret were previously ignored; after upgrading they are forwarded to every Feast pod.
  • Your IdP must mint matching tokens for Feast's own clients. Feast's client-credentials flow requests no audience, so in multi-service topologies (e.g. a remote registry) and for the UI's browser tokens, the IdP must be configured to issue tokens carrying the expected claims (e.g. a Keycloak audience mapper), or inter-service calls will be rejected.
  • Secret edits are not watched. Changes to these keys apply on the next reconcile or pod restart, not immediately. {% endhint %}

Reference the Secret from the CR:

apiVersion: feast.dev/v1
kind: FeatureStore
metadata:
  name: sample-oidc
spec:
  feastProject: my_project
  authz:
    oidc:
      secretRef:
        name: oidc-secret

Advanced OIDC options

{% hint style="warning" %} Every option in this section requires apiVersion: feast.dev/v1. Under the deprecated feast.dev/v1alpha1, authz.oidc accepts only secretRef. The CRD has no conversion webhook, so a resource submitted as v1alpha1 is validated against the v1alpha1 schema and any other field is pruned without error rather than rejected. Applying the example below as v1alpha1 therefore leaves OIDC configured by Secret alone, with none of these settings taking effect and nothing in the output to say so. Use v1, which is the storage version. {% endhint %}

authz:
  oidc:
    secretRef:
      name: oidc-secret
    secretKeyName: client_id          # override the default Secret key name
    tokenEnvVar: FEAST_TOKEN          # env var from which servers read the Bearer token
    verifySSL: false                  # disable SSL verification (dev only)
    caCertConfigMap:                  # ConfigMap with CA cert for SSL verification
      name: oidc-ca-cert
    jwksCacheLifespanSeconds: 300     # how long servers reuse the fetched JWK set
    jwksRequestTimeoutSeconds: 10     # network timeout for the JWKS fetch

jwksCacheLifespanSeconds is not only a performance setting: it also bounds how long a key the provider has revoked continues to validate tokens. Lower it if your provider rotates or revokes aggressively, at the cost of proportionally more JWKS fetches. Key rotations that introduce a new key id are picked up immediately regardless, because an unknown key id forces a refetch. jwksRequestTimeoutSeconds bounds how long an unresponsive provider can block request serving. Both must be at least 1. When unset, neither key is written to the generated configuration and the feature server applies its own defaults (300 and 10 seconds respectively).

{% hint style="warning" %} These two options require a feature server image that recognizes them. The operator deploys a matching image by default, so this only applies if you pin an older one explicitly, through a container image override or the operator's RELATED_IMAGE_FEATURE_SERVER setting. An image that predates these options rejects its configuration at startup, so leave them unset until the pinned image is updated. {% endhint %}

SDK docs: Feast OIDC Auth


TLS for servers

Each server accepts a tls block pointing to a Kubernetes Secret that holds the TLS certificate and key.

Creating a TLS Secret

kubectl create secret tls feast-tls \
  --cert=path/to/tls.crt \
  --key=path/to/tls.key \
  -n <namespace>

Applying TLS to servers

services:
  onlineStore:
    server:
      tls:
        secretRef:
          name: feast-tls
  offlineStore:
    server:
      tls:
        secretRef:
          name: feast-tls
  registry:
    local:
      server:
        tls:
          secretRef:
            name: feast-tls

Each service can use different TLS Secrets.

Custom certificate key names

By default the operator looks for keys tls.crt and tls.key. Override with:

tls:
  secretRef:
    name: feast-tls
  certKeyName: server.crt     # default: tls.crt

mTLS — providing a CA certificate

For mutual TLS (client certificate verification), supply a CA cert via a ConfigMap:

tls:
  secretRef:
    name: feast-tls
  caCertConfigMapRef:
    name: client-ca-cert
  certKeyName: tls.crt

OpenShift non-TLS mode

On OpenShift, services are typically accessed via Routes with TLS termination at the edge. In this case it is common to run the Feast servers without internal TLS:

# See config/samples/v1_featurestore_all_openshift_non_tls.yaml
services:
  onlineStore:
    server: {}    # no tls block
  offlineStore:
    server: {}
  registry:
    local:
      server: {}

See also