effect icon indicating copy to clipboard operation
effect copied to clipboard

Support dynamic password callback for IAM authentication

Open godu opened this issue 3 weeks ago • 0 comments

What is the problem this feature would solve?

When using AWS RDS or Aurora DSQL with IAM database authentication, the authentication token expires after a fixed period (15 minutes for RDS, 60 minutes for DSQL). The current PgClientConfig only accepts a static Redacted for the password field, which means:

  1. The token is generated once at connection pool creation time
  2. After the token expires, new connections fail with "Signature expired" errors
  3. Even with connectionTTL set to recycle connections, the same expired token is reused

What is the feature you are proposing to solve the problem?

The underlying pg library (node-postgres) has supported https://github.com/brianc/node-postgres/issues/1873. When the password is a function, pg invokes it for each new connection authentication:

 // From pg/lib/client.js
 if (typeof this.password === 'function') {
   this._Promise
     .resolve()
     .then(() => this.password())  // Invokes password function
     .then((pass) => { /* use pass for auth */ })
 }

Use Case: AWS DSQL / RDS IAM Authentication with @effect-aws/dsql

 import { DsqlSigner } from '@effect-aws/dsql';
 import * as PgClient from '@effect/sql-pg/PgClient';
 import * as Layer from 'effect/Layer';

 // Desired API (with this feature)
 const pgLayer = PgClient.layer({
   host: hostname,
   username: 'admin',
   database: 'postgres',
   password: DsqlSigner.getDbConnectAdminAuthToken(), // Effect<string>
 }).pipe(
   Layer.provide(DsqlSigner.layer({ hostname }))
 );

Each new connection will run the Effect to get a fresh token, integrating cleanly with the Effect ecosystem and the @effect-aws/dsql package.

Additional context

  • pg version: 8.x (supports password callbacks)
  • Related: https://github.com/brianc/node-postgres/pull/1926 - feat: Add dynamic retrieval for client password
  • This pattern is common for AWS IAM database authentication where tokens are short-lived

What alternatives have you considered?

Current workaround: Using @aws-sdk/dsql-signer directly with a type cast:

 import { DsqlSigner } from '@aws-sdk/dsql-signer';
 import * as PgClient from '@effect/sql-pg/PgClient';
 import * as Layer from 'effect/Layer';
 import * as Redacted from 'effect/Redacted';

 const signer = new DsqlSigner({ hostname });

 const pgLayer = PgClient.layer({
   host: hostname,
   username: 'admin',
   database: 'postgres',
   password: Redacted.make(() => signer.getDbConnectAdminAuthToken()) as unknown as Redacted.Redacted<string>,
 });

This works at runtime because Redacted.value() returns whatever was passed to Redacted.make(), and pg accepts the function. However, it requires an unsafe type assertion (as unknown as).

godu avatar Dec 10 '25 14:12 godu