Skip to content

Add support for 3p identity providers #70

@heeki

Description

@heeki

Add support for 3p identity providers

Summary

Customers with existing investments in third-party identity providers (Okta, Azure AD/Entra ID, Auth0, Ping Identity, etc.) need to bring those into Loom rather than adopting a separate Cognito-based identity system. This issue adds support for federating frontend/backend authentication through external OIDC-compliant IdPs and for configuring agents with inbound authorizers and outbound credential providers that reference identity systems beyond AgentCore Identity.

Context

Loom currently hardcodes Cognito as the sole identity provider. The AuthContext directly calls Cognito's InitiateAuth and RespondToAuthChallenge APIs. The backend validates JWTs against a Cognito JWKS endpoint. Agent authorizers assume a Cognito-style customJWTAuthorizer with pool-based discovery URLs. Outbound credential providers use AgentCore Identity's OAuth2 credential provider APIs exclusively.

For enterprise adoption, the auth layer needs to become IdP-agnostic: the frontend login flow should support standard OIDC authorization code flow with PKCE (which works with any compliant IdP), the backend should validate JWTs from any OIDC issuer, and agent configuration should allow inbound authorizers and outbound credential providers that reference arbitrary OIDC/OAuth2 endpoints.

Requirements

  • R1: idp-configuration-model — The backend should support an IdentityProvider data model that stores connection details for external IdPs. Fields should include: name, provider_type (cognito, okta, azure_ad, auth0, generic_oidc), issuer_url (OIDC discovery base), client_id, client_secret (stored in Secrets Manager, write-only), scopes (space-separated), audience, group_claim_path (JSONPath for extracting group membership from ID tokens, e.g., cognito:groups, groups, roles), status (active/inactive), and timestamps. CRUD endpoints under /api/settings/identity-providers with scope security:write.

  • R2: oidc-discovery — When an IdP is created or updated, the backend should fetch the OIDC discovery document from {issuer_url}/.well-known/openid-configuration and cache the JWKS URI, authorization endpoint, token endpoint, and supported scopes. A GET /api/settings/identity-providers/{id}/discover endpoint should allow manual re-fetch. Validation should fail with a clear error if the discovery document is unreachable or malformed.

  • R3: frontend-oidc-login — The frontend login flow should support OIDC Authorization Code flow with PKCE for external IdPs. The GET /api/auth/config endpoint should return the active IdP configuration (provider type, authorization endpoint, client ID, scopes, redirect URI) so the frontend can initiate the appropriate flow. For Cognito, the existing USER_PASSWORD_AUTH flow should continue to work. For external IdPs, the frontend should redirect to the IdP's authorization endpoint and handle the callback with code exchange.

  • R4: backend-jwt-validation — The backend JWT validation middleware should become issuer-agnostic. Instead of hardcoding the Cognito JWKS endpoint, it should resolve the JWKS URI from the active IdP's cached discovery metadata. JWKS keys should continue to be cached (1-hour TTL). The middleware should validate iss, aud, exp, and extract user identity (sub, email, username) and group membership using the IdP's configured group_claim_path.

  • R5: group-claim-mapping — The backend should support mapping external IdP group names to Loom's internal group structure (t-admin/t-user types and g-admins-*/g-users-* groups). A group_mappings configuration on the IdP model should map external group names (e.g., Loom-Admins, Engineering) to Loom groups. The require_scopes dependency should derive scopes from mapped groups using the existing GROUP_SCOPES logic, regardless of which IdP issued the token.

  • R6: agent-inbound-authorizer-types — The agent authorizer configuration should support authorizer types beyond Cognito JWT. The AuthorizerConfig model should accept a provider_type field (cognito, generic_oidc, custom) and store the corresponding configuration: OIDC discovery URL, issuer, audience, allowed clients, and allowed scopes. The deploy form's authorizer section should allow selecting from registered IdPs or entering a custom OIDC issuer URL, and the deploy flow should configure the AgentCore runtime's customJWTAuthorizer accordingly.

  • R7: agent-outbound-credential-providers — Agent outbound integrations (MCP servers, A2A agents) should support credential providers beyond AgentCore Identity. The integration configuration should allow specifying: credential_source (agentcore_identity, external_oauth2, api_key), and for external OAuth2: token_url, client_id, client_secret (Secrets Manager), scopes, and grant_type (client_credentials, authorization_code). The deploy flow should create the appropriate AgentCore credential provider or pass tokens directly depending on the source type.

  • R8: idp-management-ui — The frontend Security Admin page should include an "Identity Providers" section for managing IdP configurations. The form should support selecting a provider type (with type-specific field hints, e.g., Okta tenant URL format, Azure AD tenant ID), testing the OIDC discovery endpoint, configuring group claim paths with preview (show sample token claims), and mapping external groups to Loom groups with a visual mapping table.

  • R9: credential-provider-ui-enhancements — The agent deploy form's integration section (MCP servers, A2A agents) should display credential source options beyond the current AgentCore Identity flow. When an external OAuth2 source is selected, the form should show token URL, client ID, secret, and scope fields. The credential provider selection should indicate which IdP or credential source each option uses.

  • R10: migration-path — Existing Cognito-based deployments should continue to work without changes. The system should default to Cognito when no external IdP is configured (backward-compatible). A migration guide should document how to transition from Cognito-only to external IdP, including: registering the IdP, configuring group mappings, updating agent authorizers, and testing the new login flow. The GET /api/auth/config response format should remain backward-compatible with a provider_type field added.

Relevant Files

File Description
frontend/src/contexts/AuthContext.tsx Cognito-specific auth flow, GROUP_SCOPES mapping, JWT parsing
frontend/src/api/auth.ts Cognito InitiateAuth/RespondToAuthChallenge API calls
frontend/src/api/client.ts getAuthToken(), setAuthToken(), bearer token injection
frontend/src/pages/LoginPage.tsx Cognito username/password login form
backend/app/dependencies/auth.py JWT validation, require_scopes, UserInfo, group-to-scope mapping
backend/app/routers/security.py Authorizer config and credential CRUD
backend/app/models/authorizer_config.py AuthorizerConfig ORM model (Cognito-centric fields)
backend/app/models/authorizer_credential.py AuthorizerCredential model with Secrets Manager integration
backend/app/models/credential_provider.py OAuth2CredentialProvider model for AgentCore Identity
backend/app/services/credential.py AgentCore credential provider create/update/delete
backend/app/services/deployment.py Agent deploy flow including authorizer and credential provider setup
backend/app/routers/credentials.py Credential provider endpoints
shared/iac/cognito.yaml Cognito User Pool, groups, scopes, clients CloudFormation
frontend/src/components/AuthorizerManagementPanel.tsx Authorizer config cards and forms
frontend/src/components/AgentRegistrationForm.tsx Deploy form with authorizer and integration sections

Labels

feature, security, backend, frontend, authentication

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions