{"id":18284509,"url":"https://github.com/pplu/perl-rds-iam-authentication","last_synced_at":"2026-04-30T15:31:31.706Z","repository":{"id":66753299,"uuid":"119210444","full_name":"pplu/perl-rds-iam-authentication","owner":"pplu","description":"How to use RDS IAM authentication","archived":false,"fork":false,"pushed_at":"2018-01-31T16:04:59.000Z","size":20,"stargazers_count":1,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-09T05:46:45.235Z","etag":null,"topics":["aurora","aws","iam","iam-credentials","rds","rds-authentication","rds-database"],"latest_commit_sha":null,"homepage":null,"language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pplu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-27T23:11:10.000Z","updated_at":"2019-12-04T23:51:29.000Z","dependencies_parsed_at":"2023-02-22T19:15:20.131Z","dependency_job_id":null,"html_url":"https://github.com/pplu/perl-rds-iam-authentication","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/pplu/perl-rds-iam-authentication","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pplu%2Fperl-rds-iam-authentication","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pplu%2Fperl-rds-iam-authentication/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pplu%2Fperl-rds-iam-authentication/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pplu%2Fperl-rds-iam-authentication/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pplu","download_url":"https://codeload.github.com/pplu/perl-rds-iam-authentication/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pplu%2Fperl-rds-iam-authentication/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32469344,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"ssl_error","status_checked_at":"2026-04-30T13:12:06.837Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aurora","aws","iam","iam-credentials","rds","rds-authentication","rds-database"],"created_at":"2024-11-05T13:13:46.481Z","updated_at":"2026-04-30T15:31:31.688Z","avatar_url":"https://github.com/pplu.png","language":"Perl","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Connecting to an RDS or Aurora database with IAM authentication\n\nAmazon Web Services RDS (Relational Database Service) hosts MySQL databases in the AWS cloud for you. The hosted\nMySQLs are mostly like any standard MySQL that you would install on an EC2 instance with a couple of tricks down\ntheir sleeves. One of the said tricks is letting you authenticate to the database with IAM credentials (the Access\nKeys and Secret Keys that you use to authenticate to the APIs) instead of using MySQLs traditional users and \npasswords.\n\n## Why use IAM credentials for databases\n\nRDS databases start out with one initial user and password that you have configured. That user is an administrative\n\"root\" user that has lots of power. You shouldn't be using those credentials in your applications!\n\n- Using IAM, the database users are defined outside of your databases, so you can define from IAM to what RDS instances\n- You can use IAM roles to connect to your RDS instances so that you don't need to manage long-term Access and Secret Keys\n\n## I want to do that too\n\nIf you like the idea of using IAM credentials to connect to your RDS instance, and you read the RDS manual about \nthis feature, you might think \"this isn't for me\" since the manual only explains how to connect with the \n[mysql command line client](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.Connecting.AWSCLI.html) and \n[Java](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.Connecting.html).\n\n## Tell me how it works\n\nBasically, you need to create an RDS with the \"IAM database authentication\" feature enabled, and an IAM user that lets you\n\n```\n{ \"Version\":\"2012-10-17\",\n  \"Statement\":[{\n    \"Effect\":   \"Allow\",\n    \"Action\":   [\"rds-db:connect\"],\n    \"Resource\": [\"arn:aws:rds-db:eu-west-1:AWS_ACCOUNT_ID:dbuser:RDS_INSTANCE_IDENTIFIER/DATABASEUSER\"]\n  }]\n}\n```\n\n`AWS_ACCOUNT_ID` is your 12 digit AWS account identifier, which you can find in the upper right part of the AWS console (or in any ARN for your resources. See below in the example how you can obtain it).\n\n`RDS_INSTANCE_ID` is the RDS \"Resource Id\" (watch out! It's not the RDS instance name!) of an RDS instance, or `*` to grant permission to authenticate to any RDS instance.\n\n`DATABASEUSER` is the name of a user created in the MySQL database with a `CREATE USER` statement, and later a `GRANT`, so it can access\nsome database.\n\nYou also have to appropriately set up a database user to be able to authenticate with the new scheme (note that you can still create and use non-IAM-authenticated MySQL users since the IAM authenticated ones have to be explicitly enabled).\n\n```\nCREATE USER DATABASEUSER IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';\nGRANT ALL ON mydb.* TO DATABASEUSER\\@'%';\n```\n\nYou may have thought that you were going connect to the RDS instance with the Access Key as the user and the Secret Key as the password to your database. One little-known thing about how AWS authenticates API requests is that the Secret Key never leaves the client machine (it never gets transmitted to the servers). Instead, the Secret Key is used to sign a request, so that AWS can verify that it's been signed with the Secret Key. This means that requests can get intercepted, and that isn't enough for the interceptor to generate new requests. So the RDS IAM authentication uses the same signing scheme that the APIs use.\n\nSince the authentication scheme has to transmit a signature, we have to use a little-known capability of the MySQL client to transmit passwords in clear. The default protocol of MySQL sends the password that you specify to the MySQL client hashed to the server. Since we have a signature that has to arrive intact to the MySQL server, it shouldn't get manipulated (if it gets hashed, then the server cannot make sense of it), and that's why we use MySQL clients capability of sending whatever you specify as a password over the wire.\n\nFor added protection, you __have__ to encrypt the MySQL connection to use the IAM authentication scheme (or else the database will not authenticate the user).\n\n## Show me how to do it!\n\nThese instructions are made so you can copy and paste them into your console session. You need the `aws` command line client installed and configured.\n\nFirst we create an RDS instance with MySQL\n```\nRDS_NAME=RDSIAMTest\nRDS_REGION=eu-west-1\nDB_NAME=ExampleDB\nDB_ROOT_USER=master\nDB_ROOT_PASS=master123\naws rds create-db-instance \\\n    --region $RDS_REGION \\\n    --db-instance-identifier $RDS_NAME \\\n    --db-instance-class db.t2.micro \\\n    --engine MySQL \\\n    --port 3306 \\\n    --allocated-storage 5 \\\n    --db-name $DB_NAME \\\n    --master-username $DB_ROOT_USER \\\n    --master-user-password $DB_ROOT_PASS \\\n    --backup-retention-period 0 \\\n    --enable-iam-database-authentication \\\n    --publicly-accessible \\\n    --no-multi-az\n```\n\nOpen the RDS instance so you can connect to it\n\n```\nRDS_SG=`aws rds describe-db-instances --region $RDS_REGION --db-instance-identifier $RDS_NAME --query DBInstances[0].VpcSecurityGroups[0].VpcSecurityGroupId --output text`\nMY_IP=`curl -s http://checkip.amazonaws.com/`\naws ec2 authorize-security-group-ingress --region $RDS_REGION --group-id $RDS_SG --protocol all --port 3306 --cidr $MY_IP/32\n```\n\nCreate an IAM user with a policy that will let us connect to the database\n\n```\nIAM_USER=rdsiamtest\naws iam create-user --user-name $IAM_USER\nAWS_ACCOUNT_ID=`aws iam get-user --user-name $IAM_USER --query User.Arn --output text | cut -d: -f5`\nRDS_RESOURCE_ID=`aws rds describe-db-instances --region $RDS_REGION --db-instance-identifier $RDS_NAME --query DBInstances[0].DbiResourceId --output text`\nDB_CONNECT_USER=dbiamuser\n\nIAM_POLICY_ARN=`aws iam create-policy --policy-name ${IAM_USER} --policy-document \"{\\\"Version\\\":\\\"2012-10-17\\\",\\\"Statement\\\":[{\\\"Effect\\\":\\\"Allow\\\",\\\"Action\\\":[\\\"rds-db:connect\\\"],\\\"Resource\\\":[\\\"arn:aws:rds-db:eu-west-1:$AWS_ACCOUNT_ID:dbuser:$RDS_RESOURCE_ID/$DB_CONNECT_USER\\\"]}]}\" --query Policy.Arn --output text`\naws iam attach-user-policy --user-name $IAM_USER --policy-arn $IAM_POLICY_ARN\nAWS_SECRET_KEY=`aws iam create-access-key --user-name $IAM_USER --output text --query AccessKey.SecretAccessKey`\nAWS_ACCESS_KEY=`aws iam list-access-keys --user-name $IAM_USER --output text --query AccessKeyMetadata[0].AccessKeyId`\n```\n\nNow we're going to create a MySQL user that lets you connect to the database with `dbiamuser`. Wait for the RDS instance to be completely created before executing the following commands.\n\n```\nDB_HOST=`aws rds describe-db-instances --region $RDS_REGION --db-instance-identifier $RDS_NAME --query DBInstances[0].Endpoint.Address --output text`\n\necho \"CREATE USER $DB_CONNECT_USER IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS'\" | mysql -h $DB_HOST -u $DB_ROOT_USER -p$DB_ROOT_PASS\necho \"GRANT ALL ON $DB_NAME.* TO $DB_CONNECT_USER@'%'\" | mysql -h $DB_HOST -u $DB_ROOT_USER -p$DB_ROOT_PASS\n```\n\nAnd now \"la piece de résistance\"! We're going to connect to the RDS instance!\n\nI've chosen to do this with Perl, since it has standard libraries to connect to MySQL, and I want to feel the experience of getting something not documented to work. There is a script in this repository that will connect you to the RDS instance, calculating the signature beforehand, and setting the appropriate client options to connect. Other languages libraries will certainly have similar options, but I'm sure that seeing how it's done in Perl will help you.\n\n```\n./rds_iam_connect.pl $DB_HOST $DB_CONNECT_USER $AWS_ACCESS_KEY $AWS_SECRET_KEY\n```\n\nNote: if you get an errors talking about \"can't use DBI\" or \"can't find the MySQL driver\", you may need to install Perls DataBase Interface. `apt-get install -y libdbd-mysql-perl` will do all the magic for you if you're on Debian/Ubuntu.\n\n## Some observations\n\n- The first time you connect, there will be a small delay, but don't despair. Subsequent connections are immediate\n- The fact that you have to connect to the database to enable a user to connect with IAM credentials can be a bit frustrating if you're creating new RDS instances, via CloudFormation, for example. A workaround can be creating the RDS instances from database snapshots that already have the users created.\n- If the instance that connects to your RDS is running in EC2 or ECS don't generate an IAM user, and instead, use an IAM Role so that you don't have to manage the Access and Secret keys!\n- Administrative IAM users (all actions on all resources) will also be able to authenticate to your RDS instance with any IAM-enabled user. This may not be apparent when you enable the IAM authentication feature.\n- The fact that an IAM user can authenticate on an instance doesn't mean he can do so from any place. Remember that Security Groups have to be properly open to the origin of the connection\n- When creating the IAM policy, the IAM console warns about the policy \"not granting any permissions\", and the service \"rds-db\" not being recognized. Don't worry about it (just check that your policy is correct), as the policy validators don't seem to know about these policies yet.\n- The first time I built a restrictive IAM policy for connecting to an RDS instance I put the RDS instance name in the place of the RDS_RESOURCE_ID field `arn:aws:rds-db:eu-west-1:$AWS_ACCOUNT_ID:dbuser:$RDS_RESOURCE_ID/$DB_CONNECT_USER`. They are not the same (and thus the policy won't work). To find the correct RDS_RESOURCE_ID, you have to look in the Details section of your RDS instance.\n\n## More info\n\n[How to generate auth tokens](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.Connecting.Java.html)\n\n[Notes on how to build the IAM policy](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.IAMPolicy.html)\n\n[DBD::MySQL options](https://metacpan.org/pod/DBD::mysql#mysql_ssl)\n\n[MySQL client cleartext password documentation](https://dev.mysql.com/doc/refman/5.5/en/cleartext-pluggable-authentication.html)\n\n## Author, Copyright and License\n\nThis article was authored by Jose Luis Martinez Torres\n\nThis article is (c) 2018 CAPSiDE, Licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)\n\nThe canonical, up-to-date source is [GitHub](https://github.com/pplu/perl-rds-iam-authentication). Feel free to\ncontribute back\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpplu%2Fperl-rds-iam-authentication","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpplu%2Fperl-rds-iam-authentication","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpplu%2Fperl-rds-iam-authentication/lists"}