Skip to content

Issues when using RDS Proxy with IAM Authentication #288

@jordonias

Description

@jordonias

I was trying to replace pg with postgres.js and ran into issues when trying to use IAM Authentication.
I've code of a simple handler I have been testing with. Unfortunately to test this requires setting up some infrastructure on AWS, I could possibly create something with aws-cdk over the weekend to make this easier but don't currently have the time.

You can see below I have two boolean (usePostgresJs, useIAM) values I switch to test different scenarios.
usePostgresJS = true && useIAM = true HANGS
usePostgresJS = true && useIAM = false OK
usePostgresJS = false && useIAM = true OK
usePostgresJS = false && useIAM = false OK

The difference between using IAM Authentication and not is the use of a token to authenticate with the RDS proxy. This token is 1000+ characters. I though this might be a good place to start looking so I tried to do some digging around and comparing against how pg serializes and sends the password vs how it's done in postgres.js to no avail. I'm not even sure if this is the issue, but maybe this could be a lead for anyone trying to figure out what's wrong.

Let me know if there's any information I can provide to help with this. If I have time I will create something with aws-cdk so this could be tested more easily.

import postgres from 'postgres';
import { Client } from 'pg';
import AWS from 'aws-sdk';

const handler = async () => {
  const usePostgresJS = true;
  const useIAM = true; // Enable/disable IAM auth in RDS Proxy when changing this

  const options = { 
    user: process.env['DATABASE_USER'],
    host: process.env['DATABASE_HOST'],
    ssl: {
      rejectUnauthorized: false,
    },  
  };

  if(useIAM) {
    const signer = new AWS.RDS.Signer({
      region: process.env['AWS_REGION'],
      hostname: process.env['DATABASE_HOST'],
      port: 5432,
      username: process.env['DATABASE_USER'],
    }); 

    const token = signer.getAuthToken({
      username: process.env['DATABASE_USER'],
    }); 

    options.password = token;
  } else {
    options.password = process.env['DATABASE_PASSWORD'];
  }

  if(usePostgresJS) {
    const sql = postgres(options);
    await sql`SELECT 1`; // Hangs here when useIAM=true
  } else {
    const client = new Client(options);
    await client.connect();
    client.query('SELECT 1');
  }
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions