AWS Cognito Provider

The AWS Cognito provider enables authentication and authorization using Amazon Cognito User Pools. This provider validates JWT tokens issued by Cognito and extracts user information and group memberships.

Overview

AWS Cognito is a managed identity service that provides:

  • User Authentication: Sign-up, sign-in, and user management

  • JWT Token Issuance: Secure ID tokens for API access

  • Group Management: Organize users into groups for authorization

  • Integration: Seamless integration with AWS services

The Cognito provider in auth-middleware handles:

  • JWT token validation and signature verification

  • User information extraction from tokens

  • Group membership resolution

  • Token expiration checking

Configuration

Basic Configuration

from auth_middleware import JwtAuthMiddleware
from auth_middleware.providers.authn.cognito_provider import CognitoProvider
from auth_middleware.providers.authn.cognito_authz_provider_settings import (
    CognitoAuthzProviderSettings,
)
from auth_middleware.providers.authz.cognito_groups_provider import (
    CognitoGroupsProvider,
)

# Configure Cognito settings
auth_settings = CognitoAuthzProviderSettings(
    user_pool_id="us-east-1_abcdef123",
    user_pool_region="us-east-1",
    jwt_token_verification_disabled=False,
)

# Create Cognito provider
cognito_provider = CognitoProvider(
    settings=auth_settings,
    groups_provider=CognitoGroupsProvider,
)

# Add to FastAPI application
app.add_middleware(JwtAuthMiddleware, auth_provider=cognito_provider)

Environment Variables

Set these environment variables for your application:

# Required
AWS_COGNITO_USER_POOL_ID=us-east-1_abcdef123
AWS_COGNITO_USER_POOL_REGION=us-east-1

# Optional
TOKEN_VERIFICATION_DISABLED=false  # Set to true only for development

Example Application

Complete example with Cognito integration:

from fastapi import FastAPI, Depends
from starlette.requests import Request
from auth_middleware import JwtAuthMiddleware, require_user, require_groups
from auth_middleware.providers.authn.cognito_provider import CognitoProvider
from auth_middleware.providers.authn.cognito_authz_provider_settings import (
    CognitoAuthzProviderSettings,
)
from auth_middleware.providers.authz.cognito_groups_provider import (
    CognitoGroupsProvider,
)

app = FastAPI(title="Cognito Example API")

# Configuration
auth_settings = CognitoAuthzProviderSettings(
    user_pool_id="us-east-1_abcdef123",
    user_pool_region="us-east-1",
    jwt_token_verification_disabled=False,
)

# Setup middleware
app.add_middleware(
    JwtAuthMiddleware,
    auth_provider=CognitoProvider(
        settings=auth_settings,
        groups_provider=CognitoGroupsProvider,
    ),
)

# User endpoints
@app.get("/profile", dependencies=[Depends(require_user())])
async def get_profile(request: Request):
    user = request.state.current_user
    return {"user": user.name, "email": user.email, "groups": user.groups}

# Admin endpoints
@app.get("/admin", dependencies=[Depends(require_groups("admin"))])
async def admin_only():
    return {"message": "Admin access granted"}

API Reference

class auth_middleware.providers.authn.cognito_provider.CognitoProvider(settings: CognitoAuthzProviderSettings | None = None, permissions_provider: type[PermissionsProvider] | PermissionsProvider | None = None, groups_provider: type[GroupsProvider] | GroupsProvider | None = None)[source]

Bases: JWTProvider

__init__(settings: CognitoAuthzProviderSettings | None = None, permissions_provider: type[PermissionsProvider] | PermissionsProvider | None = None, groups_provider: type[GroupsProvider] | GroupsProvider | None = None) None[source]
async create_user_from_token(token: JWTAuthorizationCredentials) User[source]

Initializes a domain User object with data recovered from a JWT TOKEN. Args: token (JWTAuthorizationCredentials): Defaults to Depends(oauth2_scheme).

Returns:

Domain object.

Return type:

User

async get_keys() list[dict[str, Any]][source]

Get keys from AWS Cognito

Returns:

a list of JWK keys

Return type:

List[JWK]

async load_jwks() JWKS[source]

Load JWKS credentials from remote Identity Provider

Returns:

_description_

Return type:

JWKS

async verify_token(token: JWTAuthorizationCredentials) bool[source]
class auth_middleware.providers.authn.cognito_authz_provider_settings.CognitoAuthzProviderSettings(_case_sensitive: bool | None = None, _nested_model_default_partial_update: bool | None = None, _env_prefix: str | None = None, _env_file: DotenvType | None = PosixPath('.'), _env_file_encoding: str | None = None, _env_ignore_empty: bool | None = None, _env_nested_delimiter: str | None = None, _env_nested_max_split: int | None = None, _env_parse_none_str: str | None = None, _env_parse_enums: bool | None = None, _cli_prog_name: str | None = None, _cli_parse_args: bool | list[str] | tuple[str, ...] | None = None, _cli_settings_source: CliSettingsSource[Any] | None = None, _cli_parse_none_str: str | None = None, _cli_hide_none_type: bool | None = None, _cli_avoid_json: bool | None = None, _cli_enforce_required: bool | None = None, _cli_use_class_docs_for_groups: bool | None = None, _cli_exit_on_error: bool | None = None, _cli_prefix: str | None = None, _cli_flag_prefix_char: str | None = None, _cli_implicit_flags: bool | None = None, _cli_ignore_unknown_args: bool | None = None, _cli_kebab_case: bool | None = None, _cli_shortcuts: Mapping[str, str | list[str]] | None = None, _secrets_dir: PathType | None = None, *, jwt_secret_key: str | None = None, jwt_algorithm: str | None = 'HS256', jwt_token_verification_disabled: bool | None = False, user_pool_id: str | None = None, user_pool_region: str, user_pool_client_id: str | None = None, user_pool_client_secret: str | None = None, jwks_url_template: str | None = 'https://cognito-idp.{}.amazonaws.com/{}/.well-known/jwks.json', jwks_cache_interval: int | None = 20, jwks_cache_usages: int | None = 1000)[source]

Bases: JWTProviderSettings

Settings for Cognito provider

Parameters:

BaseModel (_type_) – _description_

jwks_cache_interval: int | None
jwks_cache_usages: int | None
jwks_url_template: str | None
model_config: ClassVar[SettingsConfigDict] = {'arbitrary_types_allowed': True, 'case_sensitive': False, 'cli_avoid_json': False, 'cli_enforce_required': False, 'cli_exit_on_error': True, 'cli_flag_prefix_char': '-', 'cli_hide_none_type': False, 'cli_ignore_unknown_args': False, 'cli_implicit_flags': False, 'cli_kebab_case': False, 'cli_parse_args': None, 'cli_parse_none_str': None, 'cli_prefix': '', 'cli_prog_name': None, 'cli_shortcuts': None, 'cli_use_class_docs_for_groups': False, 'enable_decoding': True, 'env_file': '.env', 'env_file_encoding': 'utf-8', 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', 'extra': 'ignore', 'frozen': True, 'json_file': None, 'json_file_encoding': None, 'nested_model_default_partial_update': False, 'protected_namespaces': ('model_validate', 'model_dump', 'settings_customise_sources'), 'secrets_dir': None, 'toml_file': None, 'validate_default': True, 'yaml_config_section': None, 'yaml_file': None, 'yaml_file_encoding': None}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

user_pool_client_id: str | None
user_pool_client_secret: str | None
user_pool_id: str | None
user_pool_region: str
class auth_middleware.providers.authz.cognito_groups_provider.CognitoGroupsProvider[source]

Bases: GroupsProvider

Recovers groups from AWS Cognito using the token provided

Parameters:

metaclass (_type_, optional) – _description_. Defaults to ABCMeta.

async fetch_groups(token: str | JWTAuthorizationCredentials) list[str][source]

Get groups using the token provided

Parameters:

token (JWTAuthorizationCredentials) – _description_

Raises:

NotImplementedError – _description_

Returns:

_description_

Return type:

List[str]