Shared Cognito authentication library for FastAPI + Jinja2 web apps
Project description
daylily-cognito
daylily-cognito is both a reusable Python Cognito integration library and the daycog operational CLI.
The current repo workflow is built around:
- managing Cognito pools, app clients, users, groups, and Google federation with
daycog - wiring FastAPI bearer-token authentication into services
- running Cognito Hosted UI browser-session flows without storing raw OAuth tokens in the session
- verifying JWTs with Cognito JWKS-backed helpers
- sharing one flat YAML config file per environment
Quick Start
From the repo root:
source ./activate
daycog --help
daycog status
pytest -q
source ./activate is the standard entrypoint for this repo. It prepares .venv, installs the package editable, exposes daycog, and points imports at the sibling ../cli-core-yo checkout when present.
For application code outside this repo:
pip install "daylily-cognito[auth]"
Configuration Model
The canonical config file is the one reported by:
daycog config path
By default that is:
~/.config/daycog/config.yaml
You can override it for a single invocation with the root --config PATH option:
daycog --config ./staging.yaml status
daycog --config ./staging.yaml auth-config print --json
Flat YAML shape
Required keys:
COGNITO_REGIONCOGNITO_USER_POOL_IDCOGNITO_APP_CLIENT_ID
Optional non-AWS keys:
COGNITO_CLIENT_NAMECOGNITO_CALLBACK_URLCOGNITO_LOGOUT_URLGOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRETCOGNITO_DOMAIN
Optional AWS keys:
AWS_PROFILEAWS_REGION
Example:
COGNITO_REGION: us-west-2
COGNITO_USER_POOL_ID: us-west-2_example
COGNITO_APP_CLIENT_ID: example-client-id
COGNITO_CLIENT_NAME: web
COGNITO_CALLBACK_URL: https://app.example.com/auth/callback
COGNITO_LOGOUT_URL: https://app.example.com/logout
COGNITO_DOMAIN: example.auth.us-west-2.amazoncognito.com
GOOGLE_CLIENT_ID: your-google-client-id
GOOGLE_CLIENT_SECRET: your-google-client-secret
AWS_PROFILE: dev-aws
AWS_REGION: us-west-2
Resolution rules
- Non-
AWS_*values come from the config file only. - AWS profile precedence is
--profile, then fileAWS_PROFILE, then envAWS_PROFILE. - AWS region precedence is
--region, then fileCOGNITO_REGION, then fileAWS_REGION, then envAWS_REGION. - The old named-context and namespaced env-override model is gone. Use flat YAML config files and
CognitoConfig.from_file(...).
Python Library
Core imports
Top-level imports are exposed through daylily_cognito.__init__, including:
CognitoConfigCognitoAuthcreate_auth_dependencyCognitoWebSessionConfigconfigure_session_middlewarestart_cognito_logincomplete_cognito_callbackload_session_principalSessionPrincipalbuild_authorization_urlbuild_logout_urlexchange_authorization_coderefresh_with_refresh_tokenbuild_google_authorization_urlexchange_google_code_for_tokensfetch_google_userinfoauto_create_cognito_user_from_googledecode_jwt_unverifiedverify_jwt_claimsverify_jwt_claims_unverified_signatureJWKSCacheDomainValidator
Bearer auth in FastAPI
from fastapi import Depends, FastAPI
from daylily_cognito import CognitoAuth, CognitoConfig, create_auth_dependency
config = CognitoConfig.from_file("~/.config/daycog/config.yaml")
auth = CognitoAuth(
region=config.region,
user_pool_id=config.user_pool_id,
app_client_id=config.app_client_id,
profile=config.aws_profile,
)
get_current_user = create_auth_dependency(auth)
app = FastAPI()
@app.get("/me")
def me(user=Depends(get_current_user)):
return {
"sub": user["sub"],
"email": user.get("email"),
}
Use create_auth_dependency(auth, optional=True) when anonymous requests should resolve to None instead of a 401.
Hosted UI browser sessions
daylily_cognito.web_session is the forward path for cookie-backed browser auth. The helpers exchange the authorization code during the callback, then persist a normalized SessionPrincipal in the session rather than raw OAuth tokens.
from fastapi import FastAPI, Request
from daylily_cognito import (
CognitoWebSessionConfig,
SessionPrincipal,
complete_cognito_callback,
configure_session_middleware,
load_session_principal,
start_cognito_login,
)
app = FastAPI()
config = CognitoWebSessionConfig(
domain="example.auth.us-west-2.amazoncognito.com",
client_id="example-client-id",
client_secret="example-client-secret",
redirect_uri="https://app.example.com/auth/callback",
logout_uri="https://app.example.com/logout",
public_base_url="https://app.example.com",
session_cookie_name="app_session",
session_secret_key="replace-me",
)
configure_session_middleware(app, config)
@app.get("/auth/login")
async def login(request: Request):
return start_cognito_login(request, config, next_path="/")
async def resolve_principal(tokens: dict, request: Request) -> SessionPrincipal:
del request
return SessionPrincipal(
user_sub="sub-from-id-token",
email="user@example.com",
roles=["admin"],
auth_mode="cognito",
)
@app.get("/auth/callback")
async def callback(request: Request, code: str | None = None, state: str | None = None):
return await complete_cognito_callback(request, config, code, state, resolve_principal)
@app.get("/me")
async def me(request: Request):
principal = load_session_principal(request)
return principal.to_session_dict() if principal else {"user": None}
Current behavior:
- session data stores normalized identity fields, not raw OAuth tokens
- Hosted UI cookie security is derived from
public_base_url - local HTTP development requires
allow_insecure_http=True
daycog CLI
daycog is the primary operational interface for Cognito work in this repo.
Built-in config commands
These come from cli-core-yo:
daycog config path
daycog config init
daycog config show
daycog config validate
Use daycog config init to create the canonical YAML file from the current template.
Config-aware Cognito commands
Use the plugin config commands to inspect or sync the effective auth config file:
daycog auth-config print --json
daycog auth-config create --pool-name atlas-users --client-name web --profile dev-aws --region us-west-2
daycog auth-config update --pool-name atlas-users --client-name web --profile dev-aws --region us-west-2
auth-config createwrites a new flat config file from live AWS state.auth-config updaterefreshes an existing flat config file from live AWS state.auth-config printshows the currently selected file and resolved values.
Inspect and bootstrap
daycog status
daycog list-pools --profile dev-aws --region us-west-2
daycog setup --name atlas-users --profile dev-aws --region us-west-2
setup provisions or reuses a pool and app client, writes the effective config file, and can attach a Hosted UI domain. It supports callback/logout URL overrides, domain prefix control, Google bootstrap, password policy flags, MFA mode, OAuth flow selection, app client secret generation, and --print-exports for AWS SDK env exports only.
App client lifecycle
daycog list-apps --pool-name atlas-users --profile dev-aws --region us-west-2
daycog add-app \
--pool-name atlas-users \
--app-name web \
--callback-url https://app.example.com/auth/callback \
--logout-url https://app.example.com/logout \
--profile dev-aws \
--region us-west-2
daycog edit-app --pool-name atlas-users --app-name web --new-app-name web-v2 --profile dev-aws --region us-west-2
daycog remove-app --pool-name atlas-users --app-name web-v2 --profile dev-aws --region us-west-2 --force
daycog fix-auth-flows
remove-app no longer edits config files directly; it prints a reminder to run daycog auth-config update if the config should be repointed.
Google federation
daycog add-google-idp \
--pool-name atlas-users \
--app-name web \
--google-client-json ./google-client.json \
--profile dev-aws \
--region us-west-2
daycog setup-with-google \
--name atlas-users \
--client-name web \
--google-client-json ./google-client.json \
--profile dev-aws \
--region us-west-2
daycog setup-google --client-id "$GOOGLE_CLIENT_ID" --client-secret "$GOOGLE_CLIENT_SECRET"
setup-with-googleprovisions the pool/app if needed, configures Google IdP, and writes Google credentials into the effective config file.add-google-idpconfigures Google IdP on an existing pool/app.setup-googleupdatesGOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRETin the effective config file and prints the redirect URI to register in Google Cloud Console.
User and group operations
daycog list-users
daycog add-user alice@example.com --password "Secure1234"
daycog set-password --email alice@example.com --password "EvenMoreSecure1234"
daycog ensure-group atlas-admins --description "Atlas administrators"
daycog add-user-to-group --email alice@example.com --group atlas-admins
daycog set-user-attributes --email alice@example.com --attribute custom:tenant_id=tenant-1
daycog export --output ./cognito-users.json
These commands use the effective config file plus AWS resolution rules described above.
Destructive operations
daycog delete-user --email alice@example.com --force
daycog delete-all-users --force
daycog delete-pool --pool-name atlas-users --profile dev-aws --region us-west-2 --force
daycog teardown --force
delete-poolis the primary pool-deletion command.teardownremains available for compatibility, but it still operates through the current config-backed model.
Repo Map
daylily_cognito/auth.py:CognitoAuth, token verification, customer-user lifecycle, password flows, and Cognito admin helpersdaylily_cognito/fastapi.py: shared FastAPI bearer dependency wiringdaylily_cognito/web_session.py: Hosted UI login redirect, callback completion, session middleware, normalized principal persistence, and session invalidationdaylily_cognito/plugins/core.py:daycogcommandsdaylily_cognito/config.py: flat-file config model andCognitoConfigdaylily_cognito/cli.pyanddaylily_cognito/spec.py: CLI entrypoint andcli-core-yospecdaylily_cognito/oauth.py: Cognito Hosted UI URL builders and token exchangedaylily_cognito/google.py: Google OAuth helpers and Cognito auto-create flowdaylily_cognito/tokens.py: JWT decode and claim verification helpersdaylily_cognito/jwks.py: JWKS fetching, caching, and signature verificationdaylily_cognito/domain_validator.py: allow/block email-domain policydaylily_cognito/_app_client_update.py: safe app-client update request builders
Development Notes
Recommended local loop:
source ./activate
daycog --help
pytest -q
Recommended habits in this repo:
- activate the repo environment before doing anything else
- use
daycoginstead of raw AWS Cognito mutations for operational flows - keep docs and examples aligned with the current package surface and CLI output
Version metadata is derived with setuptools-scm.
For AI Users
Treat this README as the current repo overview and command map. Treat AGENTS.md and AI_DIRECTIVE.md as repo-specific operating policy.
Key rules:
- always start from repo root with
source ./activate - use
daycog ...as the primary interface for Cognito operations - do not bypass
daycogwith directaws cognito-idp ..., ad hoc boto3 scripts, or manual config-file edits for normal operational work - prefer
daycog config path,daycog config init, anddaycog auth-config print --jsonfor orientation - keep Hosted UI behavior aligned with the current contract: exchange tokens during callback, persist normalized principal/session state, and avoid storing raw OAuth tokens in the session
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file daylily_cognito-1.1.5.tar.gz.
File metadata
- Download URL: daylily_cognito-1.1.5.tar.gz
- Upload date:
- Size: 88.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b85da6b8db06bc3083eebf829e8962275ead7b5232638fa433400e89fe16f97
|
|
| MD5 |
c9d9b7fd7e3cf257bf8b068b06ec86f0
|
|
| BLAKE2b-256 |
ae4d481608ce95d72eb292ca4aeed1088ef118be18617f51472e1397cd6a9996
|
File details
Details for the file daylily_cognito-1.1.5-py3-none-any.whl.
File metadata
- Download URL: daylily_cognito-1.1.5-py3-none-any.whl
- Upload date:
- Size: 51.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9fbe67966e2353e5041f5f84e9429ab6db97c2a98ea5b165d7a860ae1df8677
|
|
| MD5 |
670514d9684db68674c984f848e7d8f2
|
|
| BLAKE2b-256 |
01416f4afa81f229bd11beeaf82b8a1970554e20f77a4db0cb0414f426f1f5d1
|