skip to Main Content

I’m trying to connect my Cloud Run Function using IAM auth but it always errors saying that the password must be a string. How do I connect to my DB without the need of setting a password?

Code example:

  const connector = new Connector();
  const clientOpts = await connector.getOptions({
    instanceConnectionName: "project:us-central1:instance",
    ipType: IpAddressTypes.PRIVATE,
    authType: AuthTypes.IAM,
  })

  const pool = new Pool({
    ...clientOpts,
    user: 'sample-service-account@developer',
    database: 'my-db',
    max: 1,
  });

  const {rows} = await pool.query('SELECT NOW()');
  console.table(rows); 

  await pool.end();
  connector.close();

Error:

Unhandled error Error: SASL: SCRAM-SERVER-FIRST-MESSAGE: client password must be a string
    at /workspace/node_modules/pg-pool/index.js:45:11
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async /workspace/lib/exampleFunction.js:15:22
    at async /workspace/lib/lib/infrastructure/functions/functionWrapper.js:27:24
    at async /workspace/lib/lib/infrastructure/functions/onPublicCall.js:11:12
    at async /workspace/node_modules/firebase-functions/lib/common/providers/https.js:467:26

2

Answers


  1. Chosen as BEST ANSWER

    I figured it out. Apart from adding the roles to my IAM user, I also need to add the IAM user to my DB instance. Go to your instance -> Users -> Add User Account -> Cloud IAM. There, you add the full email of the service account your service is being deployed. Then you need to grant access of all tables/schemas to this user.


  2. I’m not a nodejs developer but I’m just reading the connector documentation.

    Firstly, because you are using postgres, the service account email must end by .iam as mentioned in the example in the documentation

    Postgres: For an IAM user account, this is the user’s email address. For a service account, it is the service account’s email without the .gserviceaccount.com domain suffix.

    const pool = new Pool({
      ...clientOpts,
      user: '[email protected]',
      database: 'db-name',
      max: 5,
    });
    

    Then, because you use a private IP, I guess you have a serverless VPC connector plugged on your Cloud Functions. Are you sure you are in the same VPC?

    Finally, I would recommend to use the GoogleAuth authentication, that will use IAM but, above all, detect automatically the runtime service account and you won’t have to manage it by a variable during your deployment in different environment. It will be automatic

    const connector = new Connector({
      auth: new GoogleAuth({
        scopes: ['https://www.googleapis.com/auth/sqlservice.admin']
      }),
    });
    

    I’m sure the scope is optional, you can test without

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search