AWS Cognito Authentication
AWS Cognito provides enterprise-grade user authentication and management for BoilStream. This guide covers setting up Cognito User Pools for JWT token authentication.
Overview
AWS Cognito integration provides:
- Enterprise User Management: Centralized user authentication and management
- JWT Token Validation: Secure token-based authentication using RSA signatures
- Group-based Authorization: Map Cognito groups to BoilStream permissions
- OAuth 2.0 Scopes: Fine-grained API access control
- High Availability: AWS-managed service with 99.99% uptime SLA
Prerequisites
- AWS Account with appropriate permissions
- AWS CLI configured (optional, for setup)
- Cognito User Pool with users and groups configured
AWS Cognito Setup
1. Create User Pool
If you don't have a Cognito User Pool yet, create one:
# Create user pool
aws cognito-idp create-user-pool \
--pool-name "boilstream-users" \
--policies '{
"PasswordPolicy": {
"MinimumLength": 8,
"RequireUppercase": true,
"RequireLowercase": true,
"RequireNumbers": true,
"RequireSymbols": false
}
}' \
--auto-verified-attributes "email" \
--alias-attributes "email"
{
"PoolName": "boilstream-users",
"Policies": {
"PasswordPolicy": {
"MinimumLength": 8,
"RequireUppercase": true,
"RequireLowercase": true,
"RequireNumbers": true,
"RequireSymbols": false
}
},
"AutoVerifiedAttributes": ["email"],
"AliasAttributes": ["email"]
}
2. Create User Pool Client
Create an app client for BoilStream:
aws cognito-idp create-user-pool-client \
--user-pool-id "us-east-1_ABC123DEF" \
--client-name "boilstream-client" \
--generate-secret \
--explicit-auth-flows "ADMIN_NO_SRP_AUTH" "ALLOW_USER_PASSWORD_AUTH" "ALLOW_REFRESH_TOKEN_AUTH" \
--supported-identity-providers "COGNITO" \
--token-validity-units '{
"AccessToken": "hours",
"IdToken": "hours",
"RefreshToken": "days"
}' \
--access-token-validity 1 \
--id-token-validity 1 \
--refresh-token-validity 30
3. Create Groups
Create groups for authorization mapping:
# Admin group
aws cognito-idp create-group \
--group-name "boilstream-admins" \
--user-pool-id "us-east-1_ABC123DEF" \
--description "BoilStream administrators"
# Write group
aws cognito-idp create-group \
--group-name "data-producers" \
--user-pool-id "us-east-1_ABC123DEF" \
--description "Data producers and writers"
# Read group
aws cognito-idp create-group \
--group-name "data-analysts" \
--user-pool-id "us-east-1_ABC123DEF" \
--description "Data analysts and viewers"
4. Create Test Users
# Create admin user
aws cognito-idp admin-create-user \
--user-pool-id "us-east-1_ABC123DEF" \
--username "admin@company.com" \
--user-attributes Name=email,Value=admin@company.com \
--temporary-password "TempPass123!" \
--message-action SUPPRESS
# Add user to admin group
aws cognito-idp admin-add-user-to-group \
--user-pool-id "us-east-1_ABC123DEF" \
--username "admin@company.com" \
--group-name "boilstream-admins"
BoilStream Configuration
Environment Variables
Configure BoilStream to use your Cognito User Pool:
# Enable Cognito authentication
export AUTH_PROVIDERS="cognito"
# Cognito configuration (REQUIRED)
export COGNITO_USER_POOL_ID="us-east-1_ABC123DEF"
export COGNITO_REGION="us-east-1"
# Optional: Specify expected audience
export COGNITO_AUDIENCE="4n8j9k2l1m3n4o5p6q7r"
# Authorization groups
export ADMIN_GROUPS="boilstream-admins"
export WRITE_GROUPS="data-producers,etl-services"
export READ_ONLY_GROUPS="data-analysts,business-users"
Docker Compose Example
version: '3.8'
services:
boilstream:
image: boilstream:latest
environment:
# Cognito Authentication
AUTH_PROVIDERS: "cognito"
COGNITO_USER_POOL_ID: "us-east-1_ABC123DEF"
COGNITO_REGION: "us-east-1"
COGNITO_AUDIENCE: "4n8j9k2l1m3n4o5p6q7r"
# Authorization
ADMIN_GROUPS: "boilstream-admins"
WRITE_GROUPS: "data-producers"
READ_ONLY_GROUPS: "data-analysts"
# Other BoilStream config...
S3_BUCKET: "my-data-lake"
AWS_REGION: "us-east-1"
JWT Token Claims
BoilStream extracts the following claims from Cognito JWT tokens:
Standard Claims
sub
- User ID (subject)iss
- Issuer (Cognito User Pool)aud
- Audience (Client ID)exp
- Expiration timestampiat
- Issued at timestamptoken_use
- Token type ("access" or "id")
Cognito-Specific Claims
cognito:groups
- Array of group namesscope
- Space-separated OAuth scopesusername
- Cognito usernameemail
- User email address
Example JWT Claims
{
"sub": "12345678-1234-1234-1234-123456789abc",
"iss": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_ABC123DEF",
"aud": "4n8j9k2l1m3n4o5p6q7r",
"token_use": "access",
"scope": "aws.cognito.signin.user.admin",
"username": "admin@company.com",
"exp": 1735689600,
"iat": 1735686000,
"cognito:groups": [
"boilstream-admins",
"data-engineers"
]
}
Authorization Mapping
BoilStream maps Cognito claims to authorization context:
Groups Mapping
# Cognito groups -> BoilStream authorization
cognito:groups: ["boilstream-admins"] -> Admin privileges
cognito:groups: ["data-producers"] -> Write access
cognito:groups: ["data-analysts"] -> Read access
Scopes Mapping
# OAuth scopes -> API permissions
scope: "boilstream:admin" -> Admin operations
scope: "boilstream:write" -> Write operations
scope: "boilstream:read" -> Read operations
Client Integration
Getting JWT Tokens
Use AWS Cognito SDK to obtain JWT tokens:
import boto3
# Create Cognito client
cognito = boto3.client('cognito-idp', region_name='us-east-1')
# Authenticate user
response = cognito.admin_initiate_auth(
UserPoolId='us-east-1_ABC123DEF',
ClientId='4n8j9k2l1m3n4o5p6q7r',
AuthFlow='ADMIN_NO_SRP_AUTH',
AuthParameters={
'USERNAME': 'admin@company.com',
'PASSWORD': 'YourPassword123!'
}
)
# Extract access token
access_token = response['AuthenticationResult']['AccessToken']
print(f"Bearer {access_token}")
const AWS = require('aws-sdk');
const cognito = new AWS.CognitoIdentityServiceProvider({
region: 'us-east-1'
});
async function getToken() {
const params = {
AuthFlow: 'ADMIN_NO_SRP_AUTH',
UserPoolId: 'us-east-1_ABC123DEF',
ClientId: '4n8j9k2l1m3n4o5p6q7r',
AuthParameters: {
USERNAME: 'admin@company.com',
PASSWORD: 'YourPassword123!'
}
};
const result = await cognito.adminInitiateAuth(params).promise();
const accessToken = result.AuthenticationResult.AccessToken;
console.log(`Bearer ${accessToken}`);
}
# Get token using AWS CLI
aws cognito-idp admin-initiate-auth \
--user-pool-id "us-east-1_ABC123DEF" \
--client-id "4n8j9k2l1m3n4o5p6q7r" \
--auth-flow "ADMIN_NO_SRP_AUTH" \
--auth-parameters USERNAME=admin@company.com,PASSWORD=YourPassword123! \
--query 'AuthenticationResult.AccessToken' \
--output text
DuckDB Integration
-- Install and load the airport extension
INSTALL airport FROM community;
LOAD airport;
-- Create authentication secret with your Cognito JWT token
CREATE SECRET boilstream_cognito (
type airport,
auth_token 'eyJraWQiOiJ6YWZsU0RYQnorRWFyQUgyc1Nwa2pBZE5ja0JoZjVwQUtPTnNjZzlpSW04PSIsImFsZyI6IlJTMjU2In0...',
scope 'grpc+tls://localhost:50051/'
);
-- Connect to BoilStream with TLS and authentication
ATTACH 'boilstream' (TYPE AIRPORT, location 'grpc+tls://localhost:50051/');
-- Start streaming data (requires appropriate permissions)
CREATE TABLE boilstream.s3.events (id INT, data VARCHAR);
INSERT INTO boilstream.s3.events VALUES (1, 'authenticated data');
Get Cognito Token for DuckDB
# Get token using our setup script
./scripts/cognito_test_setup.sh
# Or manually with AWS CLI
aws cognito-idp admin-initiate-auth \
--user-pool-id "eu-west-1_gti5vAfvC" \
--client-id "7ml47mngu8lrcb198epbkkfi5s" \
--auth-flow "ADMIN_NO_SRP_AUTH" \
--auth-parameters USERNAME=testuser,PASSWORD=TempPass123! \
--query 'AuthenticationResult.AccessToken' \
--output text
Security Considerations
✅ Best Practices
- Use ID Tokens: Use ID tokens for user identity, access tokens for API access
- Short Token Lifetime: Keep access tokens short-lived (1 hour or less)
- Secure Token Storage: Store tokens securely, never in plain text
- Group-based Authorization: Use Cognito groups rather than individual user permissions
⚠️ Security Warnings
- Client Secrets: Protect client secrets in server-side applications only
- Token Transmission: Always use HTTPS/TLS for token transmission
- Token Validation: BoilStream validates signatures, expiration, and issuer automatically
Network Security
# Ensure BoilStream can reach Cognito JWKS endpoint
curl -v "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_ABC123DEF/.well-known/jwks.json"
# Expected response: JSON with RSA public keys
{
"keys": [
{
"alg": "RS256",
"e": "AQAB",
"kid": "abc123...",
"kty": "RSA",
"n": "xyz789...",
"use": "sig"
}
]
}
Troubleshooting
Common Issues
"Authentication failed" errors:
# Check user pool ID and region
aws cognito-idp describe-user-pool --user-pool-id "us-east-1_ABC123DEF"
# Verify JWKS endpoint accessibility
curl "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_ABC123DEF/.well-known/jwks.json"
"Authorization denied" errors:
# Check user group membership
aws cognito-idp admin-list-groups-for-user \
--user-pool-id "us-east-1_ABC123DEF" \
--username "admin@company.com"
# Verify group configuration in BoilStream
echo $ADMIN_GROUPS
echo $WRITE_GROUPS
echo $READ_ONLY_GROUPS
Token validation failures:
# Enable debug logging
export RUST_LOG="boilstream::auth=debug"
# Check token claims manually
echo "$TOKEN" | cut -d'.' -f2 | base64 -d | jq .
Debug Logging
Enable detailed authentication logging:
export RUST_LOG="boilstream::auth::cognito=debug,boilstream::auth::manager=debug"
Advanced Configuration
Custom Scopes
Configure custom OAuth scopes in Cognito:
- Go to Cognito User Pool → App integration → Resource servers
- Create resource server with identifier
boilstream
- Add custom scopes:
read
,write
,admin
- Configure app client to use resource server scopes
# Use scope-based authorization
export REQUIRED_READ_SCOPES="boilstream:read"
export REQUIRED_WRITE_SCOPES="boilstream:write"
export REQUIRED_ADMIN_SCOPES="boilstream:admin"
Multi-Region Setup
For multi-region deployments, ensure all regions can access JWKS:
# Configure region-specific endpoints
export COGNITO_REGION="us-east-1"
# BoilStream automatically constructs JWKS URL:
# https://cognito-idp.${region}.amazonaws.com/${user_pool_id}/.well-known/jwks.json
Next Steps
- Azure AD Integration - Add Microsoft identity support
- Google Cloud Integration - Add Google Workspace support
- Troubleshooting Guide - Debug authentication issues