<a id="best-practices-oauth-identity-providers"></a>

# Best Practices for OAuth/OIDC Identity Providers on Confluent Cloud

When you use Confluent OAuth, your OAuth identity provider is responsible
for identity management. This offers you flexibility for managing your identities,
but it is only as secure as the protections enforced on the identity
provider itself.

## Precautions about using the same identity provider across multiple organizations

If you use the same OAuth identity provider (with the same Issuer URI and
JWKS URI) across multiple organizations that you own, access tokens issued by
the OAuth identity provider can be used across all applicable identity pools,
based on the filters, in all those organizations.

To restrict the usage of a token to a single organization, configure your
identity provider to issue tokens with specific claims, such as `sub`,
`aud`, or `scp`, and use those claims in the identity pool filters for
that organization. Even though the token signature is valid for all your
organizations, the token claims only pass validation in an organization that
contains an identity pool with a filter that matches the token’s claims.

The security model works as follows:

1. Your identity provider issues JWT tokens with specific claims.
2. Confluent Cloud validates the token signature using the JWKS endpoint.
3. Confluent Cloud evaluates the token claims against the identity pool filters.
4. Confluent Cloud grants access only if the claims match the filter criteria.
5. The client receives the permissions associated with the matching identity pools.

This model ensures that even if someone discovers an identity pool ID,
which is not sensitive, they cannot access the pool unless their token
contains the required claims.

## Use identity pool filters

Leverage [identity pool filters](identity-pools.md#set-pool-filters) for all
of your identity pools. Use claims, such as `aud`, `scp`, or others, to
restrict access for specific purposes or operations.

**Important Security Note**: Clients cannot change or modify filters. Filters are
configured on the identity pool and are enforced by Confluent Cloud during authentication.
The security model relies on the identity provider issuing tokens with specific
claim values that must match the filter criteria for access to be granted.

**Understanding Claims and Filters**:

- **Claims**: These are pieces of information contained in the JWT token issued by
  your identity provider. Common claims include:
  - `sub` (subject): The unique identifier for the user/application
  - `aud` (audience): The intended recipient of the token
  - `iss` (issuer): The identity provider that issued the token
  - `scp` (scope): The permissions or scopes granted to the token
  - Custom claims: Any additional information your identity provider includes
- **Filters**: These are CEL (Common Expression Language) expressions that evaluate
  the claims in the JWT token. Only tokens with claims that match the filter
  criteria can use that identity pool.

**Example**: If your filter requires `claims.aud == "confluent-cloud"`, only
tokens with an audience claim of “confluent-cloud” can use that identity pool.

## Identity pool design recommendations

**One identity pool per application vs. multiple pools**:

The decision depends on your security requirements and organizational structure:

- **One pool per application**: Provides the most granular control and isolation.
  Each application has its own set of permissions and filters.
- **Multiple pools per application**: Useful when applications need different
  permission sets for different environments (dev, staging, prod) or when using
  the union/multi-pool feature to aggregate permissions.

**Multi-environment scenarios**:

When using the same identity provider across multiple environments (dev, staging, prod):

1. **Use environment-specific claims**: Configure your identity provider to issue
   tokens with environment-specific claim values, for example, `env: "production"`,
   `env: "development"`).
2. **Create environment-specific filters**: Set up filters that match the
   environment-specific claims:
   ```text
   # Production environment filter
   claims.env == "production"

   # Development environment filter
   claims.env == "development"
   ```
3. **Consider using the union/multi-pool feature**: This allows clients to be
   mapped to multiple identity pools based on matching filters, providing
   aggregated permissions while maintaining environment isolation.

**Building OAuth expertise**:

To implement secure OAuth configurations, start by building a solid understanding
of OAuth concepts. Review the [OAuth overview](overview.md#oauth-overview) documentation,
study your identity provider’s documentation (for example, Microsoft Entra ID, Okta, Auth0),
understand JWT token structure and claims, learn about Common Expression Language
(CEL) for filter expressions, and review [identity pool filters](identity-pools.md#set-pool-filters)
examples. This foundational knowledge will help you design effective identity pool
strategies and implement proper security controls.

## Verify network access to the JWKS URI regularly

If your identity provider is behind a firewall, you should verify network
access from Confluent Cloud to your identity provider using the public IP addresses
at least every three months to ensure that Confluent Cloud can access your identity provider
JWKS endpoint over the internet. For details about verifying network access,
see [Verify network access to the JWKS URI](jwks-manual-refresh.md#verify-network-access-jwks-uri).

## Don’t rely on keeping identity pool IDs hidden

Identity pool IDs are not considered sensitive information. Instead, you should use
pool filters to restrict access to specific pools without exposing
sensitive access information.

For example, suppose you have two organizations, orgA and orgB:

- The administrator for orgA is security conscious and creates pools
  with restrictive pool filters and role bindings.
- The administrator for orgB is not security-conscious and creates an
  identity pool with a permissive pool filter.

Because the access token from their single identity provider would work
across both organizations (orgA and orgB), a user with valid, but restrictive
access to orgA could then get elevated access to orgB, simply by discovering
orgB’s identity pool IDs, which are explicitly non-sensitive. This access should be
restricted by applying appropriately restrictive filters on the pools of orgB.

**Best practice**: Always use restrictive filters that match only the specific
claims your identity provider issues for legitimate use cases. Never use
permissive filters like `true` in production environments.
