The database module v2 supports AWS RDS IAM authentication with automatic token generation and refresh. This eliminates the need to manage database passwords and provides enhanced security through AWS IAM.
- Automatic Token Generation: IAM auth tokens are automatically generated using AWS credentials
- Automatic Token Refresh: Tokens are refreshed before expiration (15-minute lifetime)
- Password Placeholder Handling: Any password in the DSN (including placeholders like
$TOKEN) is automatically stripped and replaced - Connection Recovery: Connections are automatically recreated on authentication failures
- Zero Configuration Password Management: No need to manually manage or rotate database passwords
When AWS IAM authentication is enabled, any password in the DSN is ignored and stripped. This means you can use placeholder values for backward compatibility or clarity:
# All of these DSN formats work identically with IAM auth:
dsn: "postgresql://myapp_user:$TOKEN@host.rds.amazonaws.com:5432/mydb"
dsn: "postgresql://myapp_user:PLACEHOLDER@host.rds.amazonaws.com:5432/mydb"
dsn: "postgresql://myapp_user@host.rds.amazonaws.com:5432/mydb"The password portion ($TOKEN, PLACEHOLDER, or empty) is completely ignored when IAM auth is enabled.
The database username is extracted from the DSN or can be explicitly specified:
# Option 1: Username in DSN (extracted automatically)
dsn: "postgresql://myapp_user:$TOKEN@host.rds.amazonaws.com:5432/mydb"
aws_iam_auth:
enabled: true
region: us-east-1
# Option 2: Username in config (overrides DSN username)
dsn: "postgresql://ignored_user:$TOKEN@host.rds.amazonaws.com:5432/mydb"
aws_iam_auth:
enabled: true
region: us-east-1
db_user: myapp_user # This takes precedence- Module strips any password from the DSN
- Username is extracted from DSN or config
- AWS credentials are loaded (environment, instance profile, etc.)
- RDS IAM auth token is generated using AWS SDK
- Connection is established using the generated token
- Token is automatically refreshed before expiration
database:
default: writer
connections:
writer:
driver: postgres
# DSN with $TOKEN placeholder - will be automatically stripped
dsn: "postgresql://myapp_user:$TOKEN@mydb-instance.cluster-xyz.us-east-1.rds.amazonaws.com:5432/myappdb?sslmode=require"
max_open_connections: 25
max_idle_connections: 10
connection_max_lifetime: 1h
connection_max_idle_time: 30m
aws_iam_auth:
enabled: true
region: us-east-1
# db_user is optional - extracted from DSN if not specified
connection_timeout: 10sexport DB_WRITER_DRIVER=postgres
export DB_WRITER_DSN="postgresql://myapp_user:$TOKEN@host.rds.amazonaws.com:5432/mydb?sslmode=require"
export DB_WRITER_AWS_IAM_AUTH_ENABLED=true
export DB_WRITER_AWS_IAM_AUTH_REGION=us-east-1
export DB_WRITER_MAX_OPEN_CONNECTIONS=25Enable IAM authentication on your RDS instance:
- For PostgreSQL: Set
rds.force_ssl=1and enable IAM authentication - For MySQL: Enable IAM authentication in the RDS console
Create a database user configured for IAM authentication:
PostgreSQL:
CREATE USER myapp_user WITH LOGIN;
GRANT rds_iam TO myapp_user;
GRANT ALL PRIVILEGES ON DATABASE myappdb TO myapp_user;MySQL:
CREATE USER myapp_user IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';
GRANT ALL PRIVILEGES ON myappdb.* TO myapp_user@'%';The AWS principal (user/role) must have rds-db:connect permission:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["rds-db:connect"],
"Resource": [
"arn:aws:rds-db:us-east-1:123456789012:dbuser:cluster-XXXXX/myapp_user"
]
}
]
}Finding your Resource ARN:
- Format:
arn:aws:rds-db:REGION:ACCOUNT:dbuser:RESOURCE_ID/DB_USERNAME - Get RESOURCE_ID from RDS console (cluster identifier starts with
cluster-) - Example:
arn:aws:rds-db:us-east-1:123456789012:dbuser:cluster-ABC123DEF456/myapp_user
The module uses the standard AWS SDK credential chain:
- Environment variables (
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY) - Shared credentials file (
~/.aws/credentials) - IAM instance profile (when running on EC2)
- IAM role (when running on ECS/EKS)
If you're currently using password-based authentication and want to migrate to IAM:
database:
connections:
writer:
driver: postgres
dsn: "postgresql://myuser:MySecretP@ssword@host.rds.amazonaws.com:5432/mydb"database:
connections:
writer:
driver: postgres
# Replace password with $TOKEN placeholder (or remove it entirely)
dsn: "postgresql://myuser:$TOKEN@host.rds.amazonaws.com:5432/mydb"
aws_iam_auth:
enabled: true
region: us-east-1The password portion is completely ignored when IAM auth is enabled.
Here is a complete example DSN for an RDS Aurora PostgreSQL cluster:
postgresql://myapp_user:$TOKEN@mydb-instance.cluster-abc123def456.us-east-1.rds.amazonaws.com:5432/myappdb?sslmode=require
This is the correct format. Here's what happens:
- ✅ The module sees
aws_iam_auth.enabled: true - ✅ The
$TOKENplaceholder is automatically stripped from the DSN - ✅ The username
myapp_useris extracted and used for IAM authentication - ✅ AWS credentials are loaded from your environment
- ✅ An RDS IAM token is generated automatically
- ✅ The token is refreshed every ~15 minutes automatically
- ✅ No manual password management required!
The database module v2 includes comprehensive diagnostic logging for IAM authentication. When IAM auth fails, you'll see detailed error messages with troubleshooting steps.
Enable Debug Logging to see the complete IAM authentication flow:
// Set your logger to debug level to see detailed diagnostics
app.Logger().SetLevel("debug")What Gets Logged:
-
Configuration Phase:
- AWS region being used
- Database driver type
- DSN processing (without exposing sensitive data)
- Username extraction
-
Setup Phase:
- AWS configuration loading
- RDS endpoint extraction
- Database name and options parsing
- Credential store creation
-
Connection Phase:
- Database connector creation
- Connection pool configuration
- Connection test (ping) results
-
Error Details:
- Specific error messages with context
- Possible causes for each failure
- Actionable troubleshooting steps
Example Log Output (Debug Level):
INFO Starting AWS IAM authentication setup region=us-east-1 driver=postgres
DEBUG Loading AWS configuration region=us-east-1
DEBUG AWS configuration loaded successfully
DEBUG Processing DSN for IAM authentication original_dsn_length=142
DEBUG Password stripped from DSN cleaned_dsn_length=128
INFO Extracted RDS endpoint endpoint=mydb.cluster-xyz.us-east-1.rds.amazonaws.com:5432
DEBUG Extracted database configuration database=mydb options_count=1
DEBUG Extracted username from DSN username=myapp_user
INFO IAM authentication will use database user username=myapp_user
DEBUG Determined database driver configuration driver=pgx port=5432
INFO Creating AWS RDS credential store endpoint=mydb... region=us-east-1 username=myapp_user
DEBUG AWS RDS credential store created successfully
INFO Database connection with AWS IAM authentication configured successfully
DEBUG Testing database connection timeout=10s
INFO Database connection test successful
Example Error Output:
ERROR Failed to load AWS configuration
error="NoCredentialProviders: no valid providers in chain"
region=us-east-1
possible_causes="Missing AWS credentials, invalid region, or network issues"
When experiencing connection failures, the module provides detailed diagnostics:
1. AWS Configuration Errors
If you see:
ERROR Failed to load AWS configuration
error="NoCredentialProviders: no valid providers in chain"
Solutions:
- Set AWS environment variables:
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY - Configure
~/.aws/credentialsfile - Ensure IAM instance profile is attached (EC2/ECS/EKS)
- Verify AWS region is valid
2. Endpoint Extraction Errors
If you see:
ERROR Failed to extract RDS endpoint from DSN
error="could not extract endpoint from DSN"
dsn_format="Expected format: postgresql://user@host:port/db"
Solutions:
- Verify DSN format is correct
- Example:
postgresql://user@host.rds.amazonaws.com:5432/dbname - Ensure host:port is properly formatted
3. Username Not Found
If you see:
ERROR Database username not found
dsn_has_username=false
config_has_db_user=false
Solutions:
- Include username in DSN:
postgresql://username@host/db - OR set
aws_iam_auth.db_userin configuration - Verify the username exists in the database
4. Credential Store Creation Failed
If you see:
ERROR Failed to create AWS RDS credential store
endpoint=mydb.rds.amazonaws.com:5432
region=us-east-1
username=myuser
possible_causes="Invalid AWS credentials, network issues, or incorrect endpoint"
Solutions:
- Verify AWS credentials have necessary permissions
- Test AWS connectivity:
aws sts get-caller-identity - Check network connectivity to AWS APIs
- Verify endpoint is correct RDS hostname
5. Connection Ping Failures
If you see:
ERROR Database ping failed with IAM authentication
error="pq: password authentication failed"
timeout=10s
possible_causes=["IAM token generation failed", "Database user doesn't have rds_iam role", ...]
Solutions - Check each possible cause:
- Verify IAM policy: Ensure
rds-db:connectpermission is granted - Check region: Ensure
aws_iam_auth.regionmatches your RDS region - Verify username: Ensure the database user exists and has
rds_iamrole (PostgreSQL) - AWS credentials: Verify AWS credentials are available (
aws sts get-caller-identity) - Network connectivity: Ensure security groups allow connections from your application
- Database user setup: Check the user has the
rds_iamrole granted
Tokens are automatically refreshed by the go-db-credential-refresh library. If you see authentication errors:
- The library automatically retries with a fresh token
- Check logs for "credential refresh" messages
- Ensure your application has continuous AWS credentials access
You can test IAM authentication manually:
# Generate a token
TOKEN=$(aws rds generate-db-auth-token \
--hostname mydb-instance.cluster-xyz.us-east-1.rds.amazonaws.com \
--port 5432 \
--username myapp_user \
--region us-east-1)
# Connect using the token
PGPASSWORD=$TOKEN psql \
-h mydb-instance.cluster-xyz.us-east-1.rds.amazonaws.com \
-p 5432 \
-U myapp_user \
-d myappdb- No Password Management: No need to store or rotate database passwords
- Centralized Access Control: Use IAM policies to control database access
- Audit Trail: All authentication attempts are logged in CloudTrail
- Short-Lived Credentials: Tokens expire after 15 minutes
- Automatic Rotation: Tokens are automatically refreshed
- AWS Integration: Works seamlessly with other AWS services