Skip to content

feat: add Multiple Custom Domain Support#71

Merged
kishore7snehil merged 15 commits intomainfrom
feat/multiple-custom-domain
Apr 9, 2026
Merged

feat: add Multiple Custom Domain Support#71
kishore7snehil merged 15 commits intomainfrom
feat/multiple-custom-domain

Conversation

@kishore7snehil
Copy link
Copy Markdown
Contributor

@kishore7snehil kishore7snehil commented Feb 23, 2026

📋 Changes

This PR implements Multiple Custom Domain (MCD) support for auth0-api-python, enabling APIs to accept tokens from multiple Auth0 custom domains with static lists, dynamic resolvers, and hybrid mode for zero-downtime domain migrations.

✨ Features

  • Multiple Custom Domain Verification: Accept tokens from multiple Auth0 domains via a domains parameter (static list or callable resolver) on ApiClientOptions
  • Double Issuer Validation: Pre-signature and post-signature issuer checks to prevent issuer confusion attacks
  • Hybrid Mode: Use domain and domains together for migration scenarios — domain drives client-initiated flows (token exchange, connection tokens), domains drives token verification
  • Dynamic Resolver: Runtime domain resolution via DomainsResolver callable with request context (DomainsResolverContext)
  • Per-Issuer Caching: OIDC discovery metadata and JWKS cached per issuer domain with configurable TTL, max entries, and LRU eviction
  • Pluggable Cache Backends: New CacheAdapter ABC allows custom backends (Redis, Memcached, etc.) with a default InMemoryCache implementation

🔧 API Changes

  • Extended ApiClientOptions with MCD parameters: domains, cache_ttl_seconds, cache_max_entries, cache_adapter
  • Added request_url and request_headers parameters to verify_access_token() and verify_request() for resolver context
  • New types: DomainsResolverContext (TypedDict), DomainsResolver (type alias)
  • New error classes: ConfigurationError (invalid SDK config, status 500), DomainsResolverError (resolver failure, status 500)
  • New cache classes: CacheAdapter (ABC), InMemoryCache (default LRU cache with TTL)

📖 Documentation

  • Updated README.md with MCD feature callout and new section 7 (Multi-Custom Domain Support)
  • Created docs/MultipleCustomDomain.md — configuration modes, resolver patterns, error handling, migration guide
  • Created docs/Caching.md — default behavior, custom adapters (Redis example), tuning recommendations

🧪 Testing

  • This change adds test coverage
  • This change has been tested on the latest version of the platform/language
Manual Integration Testing

Requires an Auth0 tenant with multiple custom domains configured and a machine-to-machine application with client credentials grant enabled.

import asyncio
import httpx
from auth0_api_python import ApiClient, ApiClientOptions

DOMAIN = "<AUTH0_DOMAIN>"               # e.g. "dev-tenant.us.auth0.com"
CUSTOM_DOMAIN_1 = "<CUSTOM_DOMAIN_1>"   # e.g. "auth.example.com"
CUSTOM_DOMAIN_2 = "<CUSTOM_DOMAIN_2>"   # e.g. "auth.acme.org"
ALL_DOMAINS = [DOMAIN, CUSTOM_DOMAIN_1, CUSTOM_DOMAIN_2]

CLIENT_ID = "<CLIENT_ID>"
CLIENT_SECRET = "<CLIENT_SECRET>"
AUDIENCE = "<API_AUDIENCE>"


# Helper: get an access token from a specific domain via client_credentials grant.
# POST to https://{domain}/oauth/token with grant_type, client_id, client_secret, audience.
# Returns the access_token string from the response.

async def get_token(domain: str) -> str:
    ...


async def test_bearer_mcd():
    api_client = ApiClient(ApiClientOptions(
        domains=ALL_DOMAINS,
        audience=AUDIENCE,
    ))

    for domain in ALL_DOMAINS:
        token = await get_token(domain)
        claims = await api_client.verify_request(
            headers={"Authorization": f"Bearer {token}"}
        )
        print(f"[PASS] {domain} -> iss={claims['iss']}, sub={claims['sub']}")

asyncio.run(test_bearer_mcd())

Expected: All three domains succeed. Each token's iss matches its issuing domain.

Contributor Checklist

@kishore7snehil kishore7snehil requested a review from a team as a code owner February 23, 2026 13:03
nandan-bhat
nandan-bhat previously approved these changes Apr 9, 2026
Copy link
Copy Markdown

@tanya732 tanya732 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kishore7snehil kishore7snehil merged commit 11022cd into main Apr 9, 2026
7 checks passed
@kishore7snehil kishore7snehil deleted the feat/multiple-custom-domain branch April 9, 2026 13:37
@kishore7snehil kishore7snehil mentioned this pull request Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants