CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pycognito

Python class to integrate Boto3's Cognito client so it is easy to login users with SRP support.

Pending
Overview
Eval results
Files

authentication.mddocs/

Authentication and Token Management

Core authentication functionality for AWS Cognito User Pools, providing secure user authentication using SRP protocol, admin authentication, token verification, automatic renewal, and logout operations. This module handles the complete authentication lifecycle from initial login through token management and secure logout.

Capabilities

SRP Authentication

Authenticate users using the Secure Remote Password (SRP) protocol, which provides secure authentication without transmitting passwords over the network. This is the recommended authentication method.

def authenticate(self, password: str, client_metadata: dict = None) -> None:
    """
    Authenticate user using the SRP protocol.
    
    Args:
        password (str): The user's password
        client_metadata (dict, optional): Metadata for custom workflows
        
    Raises:
        MFAChallengeException: When MFA is required
        ForceChangePasswordException: When password change is required
        
    Sets instance attributes:
        - id_token: JWT ID token
        - access_token: JWT access token  
        - refresh_token: Token for refreshing access
        - token_type: Type of token (usually "Bearer")
        - id_claims: Verified claims from ID token
        - access_claims: Verified claims from access token
    """

Usage Example:

from pycognito import Cognito
from pycognito.exceptions import MFAChallengeException

u = Cognito('your-user-pool-id', 'your-client-id', username='bob')

try:
    u.authenticate(password='bobs-password')
    print("Authentication successful!")
    print(f"Access token: {u.access_token}")
except MFAChallengeException as e:
    # Handle MFA challenge
    mfa_tokens = e.get_tokens()
    # Proceed with MFA flow

Admin Authentication

Authenticate users using administrative privileges without SRP protocol. This method bypasses SRP but requires admin permissions on the user pool.

def admin_authenticate(self, password: str) -> None:
    """
    Authenticate user using admin super privileges.
    
    Args:
        password (str): The user's password
        
    Sets same instance attributes as authenticate()
    """

Usage Example:

u = Cognito('your-user-pool-id', 'your-client-id', username='bob')
u.admin_authenticate(password='bobs-password')

New Password Challenge

Handle forced password change scenarios when users are required to set a new password after initial authentication or admin password reset.

def new_password_challenge(self, password: str, new_password: str) -> None:
    """
    Handle NEW_PASSWORD_REQUIRED challenge by setting a new password.
    
    Args:
        password (str): The user's current/temporary password
        new_password (str): The new password to set
        
    Raises:
        Exception: If the challenge response fails
        
    Sets instance attributes:
        - id_token: JWT ID token
        - access_token: JWT access token  
        - refresh_token: Token for refreshing access
        - token_type: Type of token (usually "Bearer")
        - id_claims: Verified claims from ID token
        - access_claims: Verified claims from access token
    """

Usage Example:

from pycognito import Cognito
from pycognito.exceptions import ForceChangePasswordException

u = Cognito('your-user-pool-id', 'your-client-id', username='bob')

try:
    u.authenticate(password='temporary-password')
except ForceChangePasswordException:
    # User must change their password
    u.new_password_challenge(
        password='temporary-password',
        new_password='new-secure-password'
    )
    print("Password changed successfully!")
    print(f"Access token: {u.access_token}")

Token Verification

Verify the authenticity and validity of JWT tokens received from authentication or stored from previous sessions.

def verify_tokens(self) -> None:
    """
    Verify the current id_token and access_token.
    
    Raises:
        TokenVerificationException: If tokens fail verification
        
    Verifies:
        - Token signatures using JWK keys
        - Token expiration times
        - Token audience and issuer
        - Token use claims
    """

def verify_token(self, token: str, id_name: str, token_use: str) -> dict:
    """
    Verify a specific token.
    
    Args:
        token (str): The JWT token to verify
        id_name (str): Token identifier ("id_token" or "access_token")
        token_use (str): Expected token use ("id" or "access")
        
    Returns:
        dict: Verified token payload
        
    Raises:
        TokenVerificationException: If token verification fails
    """

Usage Example:

# Verify tokens from a previous session
u = Cognito(
    'your-user-pool-id', 
    'your-client-id',
    id_token='existing-id-token',
    access_token='existing-access-token',
    refresh_token='existing-refresh-token'
)

try:
    u.verify_tokens()  # Throws exception if invalid
    print("Tokens are valid!")
    print(f"User ID: {u.id_claims['sub']}")
    print(f"Username: {u.access_claims['username']}")
except TokenVerificationException:
    print("Tokens are invalid or expired")

Token Expiration and Renewal

Check token expiration status and automatically renew access tokens using refresh tokens.

def check_token(self, renew: bool = True) -> bool:
    """
    Check if access token has expired and optionally renew it.
    
    Args:
        renew (bool): Whether to automatically renew expired tokens
        
    Returns:
        bool: True if token was expired, False if still valid
        
    Raises:
        AttributeError: If no access token is available
    """

def renew_access_token(self) -> None:
    """
    Set a new access token using the cached refresh token.
    
    Raises:
        Exception: If refresh token is invalid or expired
        
    Updates:
        - access_token: New access token
        - id_token: New ID token
        - token_type: Token type
        - access_claims: New access token claims
        - id_claims: New ID token claims
    """

Usage Example:

# Check and renew token automatically
if u.check_token(renew=True):
    print("Token was expired and has been renewed")
else:
    print("Token is still valid")

# Manual token renewal
u.renew_access_token()
print(f"New access token: {u.access_token}")

Logout

Securely log out users by invalidating all tokens across all clients and clearing local token storage.

def logout(self) -> None:
    """
    Log user out of all clients and remove token attributes.
    
    Actions:
        - Calls AWS Cognito global sign out
        - Clears id_token, refresh_token, access_token, token_type
        - Invalidates tokens on all devices/clients
    """

Usage Example:

# Logout user
u.logout()
print("User logged out successfully")

# Tokens are now None
assert u.access_token is None
assert u.id_token is None
assert u.refresh_token is None

JWT Key Management

Retrieve and cache JSON Web Key (JWK) sets for token verification.

def get_keys(self) -> dict:
    """
    Get JWK keys for token verification.
    
    Returns:
        dict: JWK key set from AWS Cognito or environment
        
    Checks:
        1. Environment variable COGNITO_JWKS
        2. AWS Cognito /.well-known/jwks.json endpoint
    """

def get_key(self, kid: str) -> dict:
    """
    Get specific JWK key by key ID.
    
    Args:
        kid (str): Key ID from JWT header
        
    Returns:
        dict: JWK key data
    """

Session Management

Switch boto3 sessions for testing or different AWS configurations.

def switch_session(self, session) -> None:
    """
    Switch the boto3 session used for Cognito operations.
    
    Args:
        session: boto3 session object
        
    Used primarily for:
        - Unit testing with placebo library
        - Different AWS credentials/regions
        - Custom boto3 configurations
    """

Usage Patterns

Basic Authentication Flow

from pycognito import Cognito

# Initialize
u = Cognito('pool-id', 'client-id', username='user')

# Authenticate
u.authenticate(password='password')

# Use tokens
headers = {'Authorization': f'Bearer {u.access_token}'}

# Check token before use
if not u.check_token():
    # Token is still valid
    make_api_call(headers)

Persistent Session Management

# Save tokens after authentication
session_data = {
    'id_token': u.id_token,
    'access_token': u.access_token, 
    'refresh_token': u.refresh_token
}

# Later, restore session
u = Cognito(
    'pool-id', 'client-id',
    id_token=session_data['id_token'],
    access_token=session_data['access_token'],
    refresh_token=session_data['refresh_token']
)

# Verify and potentially renew
try:
    u.verify_tokens()
except TokenVerificationException:
    # Handle invalid tokens
    redirect_to_login()

MFA Handling

from pycognito.exceptions import (
    MFAChallengeException, 
    SoftwareTokenMFAChallengeException,
    SMSMFAChallengeException
)

try:
    u.authenticate(password='password')
except SoftwareTokenMFAChallengeException as e:
    # Handle TOTP MFA
    code = input("Enter TOTP code: ")
    u.respond_to_software_token_mfa_challenge(code, e.get_tokens())
except SMSMFAChallengeException as e:
    # Handle SMS MFA
    code = input("Enter SMS code: ")
    u.respond_to_sms_mfa_challenge(code, e.get_tokens())

Install with Tessl CLI

npx tessl i tessl/pypi-pycognito

docs

authentication.md

device-authentication.md

group-management.md

http-integration.md

index.md

mfa.md

password-management.md

srp-authentication.md

user-management.md

tile.json