Srini Reddy
Srini Reddy

Reputation: 9

RDS Proxy IAM Authentication from Python Lambda

I am trying to connect to an RDS Proxy with IAM authentication and getting invalid credentials error.

Error: Proxy authentication with IAM authentication failed for user "lambda_user" with TLS on. Reason: Invalid credentials. If you provide an IAM token, make sure to either use the correct password or enable IAM authentication

I added full RDS permissions to the Lambda and also attached database proxy to it.

def get_db_token():
    db_client = rds_client('rds', region_name="us-east-1")
    database_token = db_client.generate_db_auth_token(
        DBHostname='test-rds.proxy-xxxxxxxx.us-east-1.rds.amazonaws.com',
        Port=5432,
        DBUsername='lambda_user')
    return database_token

db_token = get_db_token()
f"postgresql://lambda_user:{db_token}@test-rds.proxy-xxxxxxx.us-east-1.rds.amazonaws.com:5432/TestDatabase?sslmode=require"

IAM policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "rds-db:connect",
            "Resource": "arn:aws:rds-db:*:xxxxxxxxxx:dbuser:*/*"
        }
    ]
}

Lambda Database Proxies Config

I tried enhanced logging in RDS proxy but not clear on why IAM token is invalid.

Upvotes: 0

Views: 1907

Answers (3)

Jamaal Scarlett
Jamaal Scarlett

Reputation: 3

I recently ran into the same problem and finally got things working after two months of banging my head against the keyboard. The issue is how you create the client. You need to pass the aws_access_key_id, aws_secret_access_key and aws_session_token as parameters to boto3.client.

Try this:

import os
def get_db_token():
    db_client = rds_client(
        service_name="rds",
        region_name="us-east-1",
        aws_access_key_id=os.environ["AWS_ACCESS_KEY_ID"],
        aws_secret_access_key=os.environ["AWS_SECRET_ACCESS_KEY"],
        aws_session_token=os.environ["AWS_SESSION_TOKEN"]
    )
    database_token = db_client.generate_db_auth_token(
        DBHostname="test-rds.proxy-xxxxxxxx.us-east-1.rds.amazonaws.com",
        Port=5432,
        DBUsername="lambda_user")
    return database_token

Upvotes: 0

Srini Reddy
Srini Reddy

Reputation: 9

As of the suggestion from Bguess, I got it working by enabling the iam authentication on my RDS database.

The below code is working for me.


    region_name: str = environ.get('AWS_REGION')
            db_client: BaseClient = rds_client('rds', region_name=region_name)
            db_auth_token = db_client.generate_db_auth_token(
                DBHostname=db_endpoint,
                Port=5432,
                DBUsername=db_user_name,
                Region=region_name)
    
    args = {   'host'    : db_endpoint,
               'user'    :  db_user,
               'password': db_auth_token,
               'port'    : 5432,
               'dbname'  : db,
               'sslmode' : 'require' }
    
    self.engine = create_engine("postgresql://",
                                 connect_args=args,
                                 pool_size=50,
                                 echo=False)

Lambda IAM permissions:

{
      "Sid": "RdsProxyPermissions",
      "Effect": "Allow",
      "Action": ["rds-db:connect"],
      "Resource": "arn:aws:rds-db:${region}:${account}:dbuser:${db_proxy_id}/*"
}

Upvotes: 0

Related Questions