PostgREST / postgrest

REST API for any Postgres database
https://postgrest.org
MIT License
23.51k stars 1.03k forks source link

Investigating Possibility of supporting IAM authentication #1727

Open kojiromike opened 3 years ago

kojiromike commented 3 years ago

Environment

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?

steve-chavez commented 3 years ago

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.

kojiromike commented 3 years ago

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://user@some-db.cluster-chabtts532c6.us-west-2.rds.amazonaws.com/dbname"
db-use-aws-iam-auth = true
…

Does this seem reasonable?

wolfgangwalther commented 3 years ago

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://user@some-db.cluster-chabtts532c6.us-west-2.rds.amazonaws.com/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.

kojiromike commented 3 years ago

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?

wolfgangwalther commented 3 years ago

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 ;)

raamheineken commented 3 years ago

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

wolfgangwalther commented 3 years ago

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

wolfgangwalther commented 2 years ago

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.

kojiromike commented 2 years ago

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.

wolfgangwalther commented 2 years ago

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.

MargaretKrutikova commented 2 years ago

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!

wolfgangwalther commented 2 years ago

maybe it could be added to the docs?

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

endgame commented 4 months ago

FYI, since this bug was raised, someone implemented https://github.com/avanov/amazonka-contrib-rds-utils which might be a good place to start. Also, amazonka had a 2.0 release to Hackage which might give you more useful API actions.