postgrest icon indicating copy to clipboard operation
postgrest copied to clipboard

Investigating Possibility of supporting IAM authentication

Open kojiromike opened this issue 3 years ago • 12 comments

Environment

  • PostgreSQL version: Amazon Aurora RDS (PostgreSQL 12 Compat)
  • PostgREST version: main branch
  • Operating system: …

Description of issue

AWS offers IAM authentication, which we would like to take advantage of. I'm not very well versed in Haskell, so it would take me a bit to get off the ground, but if I were to build a feature in postgrest to take advantage of IAM authentication, would it be well-received here?

kojiromike avatar Jan 06 '21 21:01 kojiromike

Hey @kojiromike,

Sure! Integrating with IAM sounds interesting.

I think this would go on our Auth.hs module. You could try using https://hackage.haskell.org/package/amazonka-1.6.1/docs/Network-AWS-Auth.html. I haven't used it before, but looks like it could work.

steve-chavez avatar Jan 06 '21 23:01 steve-chavez

I think this would go on our Auth.hs module.

Maybe I misunderstand, but isn't the Auth.hs module for authenticating to postgrest via JWT? Here I'm talking about providing another way for postgrest to authenticate to postgresql besides a static password in a config file.

The database password provided through IAM seems to be the url (without the protocol) of a request signed with AWS signature v4 request signing.

There is a library in hackage, aws-general, that seems like it can do that signing. The real trick is that I can't just embed the "password" in config. After 15 minutes, the password expires and I have to generate a new one. I am currently thinking about writing this into App.hs.

I guess the config should have a passwordless db-uri in this case, and a flag indicating the user wants to use aws auth:

db-uri = "postgres://[email protected]/dbname"
db-use-aws-iam-auth = true
…

Does this seem reasonable?

kojiromike avatar Jan 07 '21 04:01 kojiromike

I guess the config should have a passwordless db-uri in this case, and a flag indicating the user wants to use aws auth:

db-uri = "postgres://[email protected]/dbname"
db-use-aws-iam-auth = true
…

Does this seem reasonable?

Instead of making something that is specific for the AWS IAM use-case only, what do you think about making this more general?

I'm thinking about something like just a config option db-password-command that takes a shell command to return a password to use. You could then create a shell script that does all the AWS IAM stuff. We could add this to the still-to-be-set-up postgrest-contrib repo.

wolfgangwalther avatar Jan 07 '21 08:01 wolfgangwalther

You could then create a shell script that does all the AWS IAM stuff.

That certainly would make things easier and more extensible. How can I help with that?

kojiromike avatar Jan 07 '21 14:01 kojiromike

How can I help with that?

Feel free to open a PR for db-password-command support. I've got too much other things on my plate right now, just wanted to suggest ;)

wolfgangwalther avatar Jan 07 '21 15:01 wolfgangwalther

Did anyone pick this up? otherwise I think i can spare some time

raamheineken avatar Jun 08 '21 08:06 raamheineken

Not that I know more. You're more than welcome to!

wolfgangwalther avatar Jun 08 '21 16:06 wolfgangwalther

I think it would be easier for users if the configuration followed the standard postgres variables: POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD etc instead of requiring a ready constructed db-uri. Does anyone have any thoughts on this?

See https://github.com/PostgREST/postgrest/issues/1991#issuecomment-1003910285. This can be done already by using db-uri="postgresql://" and then using PGUSER, PGPASSWORD etc. (see https://www.postgresql.org/docs/current/libpq-envars.html).

#1823 / #2112 will just make this the default.

wolfgangwalther avatar Jan 20 '22 14:01 wolfgangwalther

This can be done already by using db-uri="postgresql://" and then using PGUSER, PGPASSWORD etc.

Unfortunately, IAM authentication comes with one really sticky sticking point: The token expires in 15 minutes, and there is no configuration option to change it. So postgrest would have to renew the token automatically to renew its connection, and unless I misunderstand what you're saying, we would have to renew the environment to use PGPASSWORD to make that work.

I have, in fact, written a Docker implementation that does just this, for a PoC. And it's as bad as you might think; postgrest is offline for a few seconds every 15 minutes.

kojiromike avatar Jan 20 '22 14:01 kojiromike

Unfortunately, IAM authentication comes with one really sticky sticking point: The token expires in 15 minutes, and there is no configuration option to change it. So postgrest would have to renew the token automatically to renew its connection, and unless I misunderstand what you're saying, we would have to renew the environment to use PGPASSWORD to make that work.

I have, in fact, written a Docker implementation that does just this, for a PoC. And it's as bad as you might think; postgrest is offline for a few seconds every 15 minutes.

Sorry - I didn't cite properly. I didn't respond to the thread's topic in general, but to a specific comment, which was - unfortunately - deleted in the meantime. I added the citation now.

wolfgangwalther avatar Jan 20 '22 14:01 wolfgangwalther

I am sorry, I deleted the comment because I found exactly what you wrote here in a different issue (maybe it could be added to the docs?). My apologies again, thought I would avoid cluttering this thread 🙁 Thanks anyway!

MargaretKrutikova avatar Jan 20 '22 14:01 MargaretKrutikova

maybe it could be added to the docs?

Yes, will do so when writing the docs for #2112.

wolfgangwalther avatar Jan 20 '22 14:01 wolfgangwalther