Authentication and Authorization
This guide describes how to configure authentication providers and tenant assignment for Feldera Enterprise.
Feldera supports authentication through OIDC/OAuth2 providers, enabling secure multi-tenant deployments with flexible tenant assignment strategies.
Authentication model
Feldera API supports two authentication types:
-
OIDC: Requests should include a valid OIDC Access token in the
AuthorizationHTTP header in the shapeBearer <token> -
API key: Authorized Feldera users can generate API keys to be included in the
AuthorizationHTTP header in the shapeBearer <token>
Authorization model
Feldera Tenant is a scope of access to Feldera pipelines for their management and configuration. The same tenant can be assigned to multiple users for shared access. The ingress and egress business data flow, which is configured through connectors, has it's own connector-dependent authentication and is not subject to tenant-based authorization.
Interaction with Feldera is always authorized through a tenant, so access to the platform implies assigning tenant to the user. For OIDC authentication, the tenants a user may act in are stored by Feldera; a tenancy strategy can provision memberships automatically at login from the OIDC Access token. For API key authentication, the key is associated with the tenant through which the key was generated. We support multiple authorization use-cases through strategies to provision tenants and memberships for Feldera API and clients' users.
As an orthogonal feature, the authorized-groups startup parameter can be used to limit access to the users who are a member of at least one of the groups in this list. The membership is determined based on the groups claim of an OIDC Access token.
Users must belong to at least one of the specified groups to access Feldera. If authorizedGroups is not specified or empty, no group restrictions apply.
This group check applies to every principal, including platform owners: the membership check runs before owner resolution, so an identity listed in owners that is not in any authorized group is still denied access. Being an owner does not exempt a user from the group requirement.
Tenant Assignment Strategies
A user acts in the tenants they hold a membership in, at the role the
membership records. Memberships are granted through the
member-management API and web console, and, by
default (authorization.provisionOnLogin: true), also provisioned at login by
one of three strategies:
Individual Tenancy (Enabled by default)
Each authenticated user gets their own private tenant based on the sub claim of the OIDC Access token. Does not require authentication provider configuration. Configured with authorization.individualTenant Helm value.
Organization-wide Tenancy
Users from the same organization share a tenant, derived from the issuer hostname of the authentication token. Does not require authentication provider configuration. Configured with authorization.issuerTenant Helm value.
Managed Tenancy (deprecated)
Each team's users are assigned to their tenant(s) through the dynamic tenants
claim in the OIDC Access token. tenants can contain either a list, or a
string of comma-separated tenant names; empty entries are ignored.
The claim provisions rather than restricts: the deliberately selected tenant is created if absent and the user enrolled, further listed names enroll the user into tenants that already exist, and the user may additionally act in any tenant they hold a membership in, whether the claim names it or not. Narrowing the claim therefore does not revoke access; remove the membership as well (see Revoking access).
This strategy is deprecated in favor of managing memberships in Feldera
directly, which needs no claim mapping at the identity provider; see
Migrating to Feldera-managed memberships.
One consequence for new multi-entry-claim users: a listed tenant that does not
exist yet is not created by their login unless they select it with the
Feldera-Tenant header, so create tenants up front with
POST /v0/tenants.
Turning login provisioning off
authorization.provisionOnLogin: false (default true) disables all three
strategies at once: a login creates no tenant and enrolls no one, and access
comes only from memberships granted through the API and console. This is the
recommended end state for enterprise deployments, because access then has one
audit trail and one revocation lever. It requires a configured
authorization.owners or authorization.ownerTrusts; the manager refuses to
start otherwise, because without an owner no principal could ever grant access.
The user interacts with the API through a single tenant at a time. A user who
belongs to several tenants switches tenants in the Web Console, or names one in
the Feldera-Tenant header on HTTP API calls.
Tenant Assignment use cases
Listed below are example configurations for common authorization use-cases achieved through a combination of tenant assignment strategy and whitelisted group access.
Development environment - no authentication
Helm Configuration:
auth:
enabled: false
Individual access
Every user gets their individual tenant based on their sub claim.
Helm Configuration:
auth:
enabled: true
provider: "generic-oidc"
clientId: "0oa1a2b3c4d5e6f7g8h9"
issuer: "https://dev-12345.okta.com/oauth2/default"
authorization:
individualTenant: true
issuerTenant: false
authAudience: "feldera-api"
Organization-wide shared access
All users in your organization share the same tenant based on the organization domain.
The tenant name is extracted from OIDC issuer domain:
https://acme-corp.okta.com/oauth2/default→acme-corp.okta.comtenant
Helm Configuration:
auth:
enabled: true
provider: "generic-oidc"
clientId: "0oa1a2b3c4d5e6f7g8h9"
issuer: "https://acme-corp.okta.com/oauth2/default"
authorization:
individualTenant: false
issuerTenant: true
authAudience: "feldera-api"
Group-based whitelist with organization-wide shared access
Users must belong to at least one of the specified groups to access Feldera. All authorized users share the organization tenant.
Helm Configuration:
auth:
enabled: true
provider: "generic-oidc"
clientId: "0oa1a2b3c4d5e6f7g8h9"
issuer: "https://company.okta.com/oauth2/default"
authorization:
individualTenant: false
issuerTenant: true
authorizedGroups:
- "feldera-engineering"
- "feldera-qa"
authAudience: "feldera-api"
Shared access within a user group (managed tenancy)
Tenant assignment via tenants claim in JWT configured in your OIDC provider.
Helm Configuration:
auth:
enabled: true
provider: "generic-oidc"
clientId: "0oa1a2b3c4d5e6f7g8h9"
issuer: "https://company.okta.com/oauth2/default"
authorization:
individualTenant: false
issuerTenant: false
authAudience: "feldera-api"
Individual access to whitelisted user groups
Each user gets their individual tenant, but only users belonging to specified groups can access Feldera.
Helm Configuration:
auth:
enabled: true
provider: "generic-oidc"
clientId: "0oa1a2b3c4d5e6f7g8h9"
issuer: "https://company.okta.com/oauth2/default"
authorization:
individualTenant: true
issuerTenant: false
authorizedGroups:
- "feldera-engineering"
- "feldera-qa"
authAudience: "feldera-api"
Changing your authentication setup
Feldera supports a single identity provider at a time. Two supported changes alter which tenant a login lands in: 1) enabling authentication on a deployment that ran without it, and 2) pointing an authenticated deployment at a different provider. Both need planning, because a tenant is where pipelines live.
How a tenant is identified
A tenant is identified by its name alone. The name is derived from the token on each login, by whichever tenant assignment strategy you configured.
A user is identified by the pair (issuer, subject), where the subject is the
token's sub claim. That pair is what memberships and roles are based on. Note,
OIDC only guarantees sub to be unique within one issuer, which is why the
issuer is part of the pair.
In short, a tenant can survive a provider change, but the users in it cannot. Users arrive as new identities and must be granted their roles again.
Enabling authentication on an existing deployment
Without authentication, all pipelines live in a built-in tenant named default,
whose id is the all-zero UUID 00000000-0000-0000-0000-000000000000.
When authentication is enabled for the first time in such a deployment, logins
resolve to a tenant named by your authentication provider and tenant strategy.
This makes default tenant pipelines and API keys no longer visible to
authenticated logins, even though the data is intact.
To avoid this problem, plan the following steps before enabling authentication on a deployment that already holds pipelines.
A platform owner can still reach
the default tenant by naming it explicitly:
curl -H "Authorization: Bearer $OWNER_TOKEN" \
-H "Feldera-Tenant: 00000000-0000-0000-0000-000000000000" \
https://<your-host>/v0/pipelines
There are two options:
- Recreate the resources in the tenant your logins now reach, then stop and
delete the pipelines left behind in
default. Deleting them matters: a pipeline nobody can see still holds its Kubernetes pods and volumes, running and unaccounted for. - Put
defaultin that tenant's place, by giving it the new tenant name your logins resolve.
To rename the default tenant, 00000000-0000-0000-0000-000000000000, to
acme.us-west1.idp.com:
curl -X PATCH -H "Authorization: Bearer $OWNER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "acme.us-west1.idp.com", "displace_existing": true}' \
https://<your-host>/v0/tenants/00000000-0000-0000-0000-000000000000
The first login after the switch already created a tenant named
acme.us-west1.idp.com, so the rename needs displace_existing. It hands the
name over: default takes it, and the tenant that held it is renamed out of the
way and reported in the response under displaced. Logins now resolve to your
original pipelines.
The displaced tenant is empty, so delete it:
curl -X DELETE -H "Authorization: Bearer $OWNER_TOKEN" \
https://<your-host>/v0/tenants/<displaced id>
Changing the identity provider
When changing identity providers, each tenant's name (per the provider-supplied tokens) decides whether it survives the migration:
| Strategy | Tenant name comes from | Survives a provider change? |
|---|---|---|
| Managed tenancy | the tenants claim | Yes, if you configure the new provider to emit the same values |
| Organization-wide | the issuer hostname | Only if the hostname is unchanged, e.g. a new authorization server on the same domain |
| Individual tenancy | the sub claim | No, in practice: a new provider issues different subjects |
Managed tenancy migrates cleanly, because the tenant name is a value you control at the provider rather than something derived from it. Use this strategy if you expect to change providers regularly.
Where the name does change, the old tenant keeps every pipeline and is no longer
reachable by ordinary logins. Recover it the same way as above: an owner selects
it with Feldera-Tenant (by name or UUID; GET /v0/tenants
lists both, and GET /v0/tenants/{tenant_id} retrieves one by
either selector) and
moves what is needed, or gives it the name the new provider produces, with
displace_existing, so the logins land back on it.
In general, do not leave pipelines in an unreachable tenant. The corresponding
pipelines use system resources (like Kubernetes pods) while running and can go
unnoticed. Stop and delete those pipelines, then delete the empty tenant with
DELETE /v0/tenants/{tenant_id}.
The destructive rename works the opposite way: taking a name away from the
tenant whose users still arrive under it. Say you rename acme.us-west1.idp.com
to an unreachable tmp while the provider keeps asserting
acme.us-west1.idp.com. The next request from those users re-creates that name
as an empty tenant, which is where they then work. Rename a tenant only to a
name you want its users to arrive under.
Even when the tenant survives, its members do not. A membership is keyed to
(issuer, subject), so after the switch every user is a new identity with no
membership, and each is admitted at authorization.defaultRole. Administrators
and pre-provisioned members must be granted their roles again, and at least one
identity from the new provider must be listed in authorization.owners so that
someone can do the granting. See
Roles.
Migrating to Feldera-managed memberships
A deployment using the deprecated managed tenancy (tenants claim) moves to
Feldera-managed memberships as follows:
- Upgrade Feldera.
provisionOnLoginstaystrue; nothing changes at the identity provider yet. - Audit existing memberships per tenant with
GET /v0/tenant/users: every past login left a membership row, including for users whose claim no longer names the tenant. Remove rows that should not confer access, because they do now. - Populate the memberships you want: let every user log in once, or
pre-provision them with
POST /v0/tenant/users. - Verify per tenant that the member list matches the intended access.
- Confirm
authorization.owners(orownerTrusts) is set; the manager refuses to start without one in the next step. - Set
authorization.provisionOnLogin: falseand restart. - Delete the
tenantsclaim mapping at the identity provider.
Deployments on individual or organization-wide tenancy need no migration:
behavior is unchanged until an admin grants cross-tenant memberships, and
provisionOnLogin: false is available whenever explicit provisioning is
preferred.
How members are identified in the member list
A membership is keyed to an OIDC subject, which is rarely a string anyone
recognizes. So that an administrator can tell members apart,
GET /v0/tenant/users, the web console's member
list, and fda member list also report the name and email the identity
provider holds:
| Field | Source |
|---|---|
subject | the token's sub; the identity itself |
display_name | the provider's name, or preferred_username |
email | the provider's email, or an email supplied when pre-provisioning |
email_verified | whether the provider vouches for email |
Feldera reads the name and email from the provider's OIDC UserInfo endpoint, because an access token often carries neither.
Configuration options
Mapping Pipeline Manager Options to Helm Chart Values
Feldera's authentication and authorization are configured through pipeline-manager command-line options. When deploying via Helm, these options map to values in your values.yaml file.
Complete Configuration Template
Below is a comprehensive template showing all available authentication and authorization options:
# Authentication provider configuration
auth:
enabled: true # Enable/disable authentication
provider: "generic-oidc" # Maps to: AUTH_PROVIDER; Options: "none", "aws-cognito", "generic-oidc"
clientId: "your-client-id" # Maps to: FELDERA_AUTH_CLIENT_ID
issuer: "https://your-domain/oauth2/default" # Maps to: FELDERA_AUTH_ISSUER
# AWS Cognito specific (only when provider: "aws-cognito")
cognitoLoginUrl: "" # Maps to: AWS_COGNITO_LOGIN_URL
cognitoLogoutUrl: "" # Maps to: AWS_COGNITO_LOGOUT_URL
# Authorization and tenant assignment configuration
authorization:
# Individual tenant mode - each user gets their own tenant (default: true)
individualTenant: true # Maps to: FELDERA_AUTH_INDIVIDUAL_TENANT
# Issuer-based tenant - derive tenant from auth issuer domain (default: false)
issuerTenant: false # Maps to: FELDERA_AUTH_ISSUER_TENANT
# Group-based access control - restrict access to specific groups
# Users must have at least one of these groups in their 'groups' claim
authorizedGroups: # Maps to: FELDERA_AUTH_AUTHORIZED_GROUPS
- "feldera-users"
- "data-engineers"
# OIDC audience claim validation (default: "feldera-api")
authAudience: "feldera-api" # Maps to: FELDERA_AUTH_AUDIENCE
# Platform owners: identities granted the platform-wide `owner` role (default: [])
owners: # Maps to: FELDERA_OWNERS
- "ops@example.com"
# Workloads granted `owner`, matched on their OIDC token (default: [])
ownerTrusts: # Maps to: FELDERA_OWNER_TRUSTS
- issuer: "https://token.actions.githubusercontent.com"
subject: "repo:acme/infra:ref:refs/heads/main"
audience: "https://github.com/acme"
# Role for an authenticated user with no explicit membership yet (default: "read")
# Ship "write" when upgrading a pre-RBAC deployment; see the Roles page.
defaultRole: "write" # Maps to: FELDERA_AUTH_DEFAULT_ROLE
# Role for the user whose login first creates a tenant (default: "admin")
# Set to "write"/"read" for a shared sandbox; see the Roles page.
firstUserRole: "admin" # Maps to: FELDERA_AUTH_FIRST_USER_ROLE
# Provision tenants and memberships at login per the tenancy strategy
# (default: true). false = access comes only from memberships granted
# through the API and console; requires owners or ownerTrusts.
provisionOnLogin: true # Maps to: FELDERA_AUTH_PROVISION_ON_LOGIN
Environment Variables Reference
If you need to configure pipeline-manager directly (without Helm), use these environment variables:
Required Variables
# OIDC provider configuration
FELDERA_AUTH_ISSUER=https://<your-domain>/oauth2/<custom-auth-server-id>
FELDERA_AUTH_CLIENT_ID=<your-client-id>
Optional Variables
# Authorization configuration
FELDERA_AUTH_INDIVIDUAL_TENANT=true # default: true
FELDERA_AUTH_ISSUER_TENANT=false # default: false
FELDERA_AUTH_AUTHORIZED_GROUPS=group1,group2 # comma-separated list
FELDERA_AUTH_AUDIENCE=feldera-api # default: feldera-api
FELDERA_OWNERS=ops@example.com # comma-separated; default: (none)
FELDERA_OWNER_TRUSTS='[{"issuer":"https://token.actions.githubusercontent.com","subject":"repo:acme/infra:*"}]'
# JSON array; default: []
FELDERA_AUTH_DEFAULT_ROLE=read # read or write; default: read
FELDERA_AUTH_FIRST_USER_ROLE=admin # read, write, or admin; default: admin
FELDERA_AUTH_PROVISION_ON_LOGIN=true # default: true; false requires owners
# AWS Cognito specific
AWS_COGNITO_LOGIN_URL=https://...
AWS_COGNITO_LOGOUT_URL=https://...
Tenant Resolution
A login's acting tenant comes from the user's memberships:
- A
Feldera-Tenantheader (tenant name or UUID) selects the tenant; it must be one the user holds a membership in. An unknown tenant and one the user is no member of are answered alike, so the header cannot be used to probe which tenants exist. - Without a header, a user with exactly one membership acts in it.
- Without a header, a user with several memberships is refused; the session endpoint still answers, listing the memberships so a client can pick one (the Web Console shows a tenant picker).
- A user with no membership at all is denied, again except for the session endpoint, which answers with an empty membership list so a client can show a useful message.
Before this resolution, and only while provisionOnLogin is true (the
default), the login provisions memberships in priority order: the tenants
claim, the issuer domain (when issuerTenant: true), or the user's sub
(when individualTenant: true). With all three strategies off, or with
provisionOnLogin: false, a login provisions nothing and case 4 applies until
an admin grants a membership.
Provider-Specific Setup
Feldera supports the following authentication providers:
- AWS Cognito
- Okta
- Google Identity
- Generic OIDC
Each authentication provider requires specific configuration. Choose your provider below:
📄️ Roles
Feldera Enterprise governs access with role-based access control (RBAC). Every
📄️ AWS Cognito
To configure AWS Cognito as an authentication provider, follow these steps:
📄️ Okta SSO
This guide explains how to configure Okta as an authentication provider for Feldera Enterprise.