aws-amplify / amplify-cli

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development.
Apache License 2.0
2.81k stars 820 forks source link

RFC: Auth Enhancements - Admin Tasks #766

Closed undefobj closed 4 years ago

undefobj commented 5 years ago

Overview: Currently the Amplify CLI supports provisioning Cognito User Pools and Cognito Identity Pools with a handful of options such as:

Customer feedback and interviews, as well as triaging common issues for building apps we have found that there are many common "administrative tasks" that we can automate and setup with enhancements to the CLI auth category, reducing the need to manually connect things within the AWS console. This RFC is a proposal for feedback on workflow and requirements as part of this effort.

Common asks/current feature plans: Below are the common asks we have heard from the community, please reply with a +1 or detailed comment on a feature if you have specific thoughts around how it should work:

Please comment with any additional thoughts not covered in the above list. Thank you.

bilal-korir commented 5 years ago

Your post covers it all! almost, it's hard to come up with a new suggestion :)

I have one suggestion please: I would like for Cognito to have a built-in monitoring/analytics dashboard. (I know we could use analytics services provided by AWS such Pinpoint) It would be nice to see a user's(s) behavior for the last day/week/month/year. The idea is, instead of using Pinpoint, for example, to have detailed analytics I just want to look at Cognito Dashboard and quickly conclude:

  1. How many new users registered today
  2. How many users logged in today
  3. A specific user's behavior (today she logged in twice, at what time? she logged out, at what time? etc)
  4. Who changes his profile info today (phone numbers, email, etc.) how often users change their profile (Not very important, but it would be nice to have)

I'm a big fan of Cognito and Amplify! You guys are doing a great job. With Amplify framework you guys took development simplicity and speed to the next level, for real Thank you very much indeed!

fullStackDataSolutions commented 5 years ago

The three features I would like are the ability to select from an existing Cognito User Pool, to attach an identity pool to it and to create an user pool client.

The major issue I have is actually based around SAML though. There is no suppor for SAML from the React Amplify library so I’m forced to use the hosted UI, which isn’t the best for user experience.

khola commented 5 years ago

All the things would be really useful, especially the triggers!

One thing about Hosted UI - it would be nice to have the ability to customize the look using css file. It's possible using API but AFAIK not using CFN.

heauton commented 5 years ago

Would you be able to automate having two GraphQL APIs for unauthenticated/guest users (using IAM_AUTH or API_KEY) and authenticated users (using COGINITO USER POOL)? Automating it or providing documentation of how to manually set it up would be wonderful.

ghost commented 5 years ago
      The three features I would like are the ability to select from an existing Cognito User Pool, to attach an identity pool to it and to create an user pool client.

The major issue I have is actually based around SAML though. There is no suppor for SAML from the React Amplify library so I’m forced to use the hosted UI, which isn’t the best for user experience.

as it is, amplify is horrible in importing existing configurations. I think it's on purpose. IMHO, if they ever implemented it, it would be as part of a framework wide effort to allow importing existing DynamoDB tables and S3 buckets, and Roles, and what have you.

What I would like, is to use only Identity Pools without User pools. Since my app is Android only (with a web admin component), every user will have a Google account and I'd like the users to log in only with a Google account, and not creating username/passwords. Even if AWS will take care of 90% of managing the credentials, I can still mess it up, and I don't want to risk that.

RBAC is also important for us, CLI could ask to open a custom YAML file for mapping, the initial file prepopulated with example Role to Users

Also I'd like to give a huge thank you to the Amplify team for having a dialog with us. It's super important to have someone to talk to, and to know that our issues are being looked into and dealt with. I wish other AWS teams would join you.

flowirtz commented 5 years ago

Re: Cognito Groups

@undefobj thanks for pointing me here. Looks good! A post-signup trigger seems like a great start. Now, of course, it would be amazing to change the group at any given point in time, and not only post-signup. But, if the post-signup is a lambda, I think that even is an option. Simply calling the given lambda addToGroup(username, group) that's called on the lambda trigger from Amplify seems feasible. Would that work with the RFC or did I misunderstand that?

Long-run it would be nice to define groups in some sort of cloudformation/terraform-esque style of syntax. I love how Amplify helps me create all my resources and creates .cf files for them, but I would love to adapt them to my needs. But I guess that tackles a bigger architecture discussion after all.

So: RFC sounds like a great start, would be amazing if the lambda triggered by postSignup was "recyclable" for things like adding users to groups at any given point in time.

(Came here from aws-amplify/amplify-js#1213)

joebernard commented 5 years ago

Support for passwordless sign up / sign in It is possible to configure passwordless login with Cognito and Lambda triggers (see here) but not with Amplify. This is becoming a common requirement for apps and should be an option during amplify auth add. I'd like to see expanded documentation around how to get this working, and support for this config within Amplify itself.

Auth / Unauth support +1. This is a common use case but currently a pain to implement in Cognito. We should be able to trigger a login prompt manually while provisioning unauthenticated users with guest credentials to access certain services. AppSync should also support these guest users without the need for a separate guest API or other complex configuration.

I believe both of these scenarios can be built now, just not with Amplify. While this RFC is getting finalized could we get some more documentation on these configurations? I have immediate requirements for both and feel lost getting these working.

ceich commented 5 years ago

+1 on Hosted UI with Federation

flybayer commented 5 years ago

Support setting UsernameAttributes for Cognito user pools

I think it's usually a far better UX for users to sign up/in with email as username instead of a seperate username. At the very least I want the CLI to add this as an option (I've been manually modifing the CFN template). At the best, I'd love the default to be changed to email as username and the default amplify-js auth screen updated to match.

Also add my vote for passwordless support

jonsmirl commented 5 years ago

This is an underlying issue with Cognito Identify and User pools which is not specific to Amplify...

In the current model there has to be a 1:1 relationship between the User pool and the Identity pool. Another model would be to allow User pool to be a subset of the attached Indentity Pool.

We have issues with the disconnect between Cognito Identity pools and Cognito User pools. We have many casual users that log in via Identity pools for a free service. Many of those users (likely bots) touch our system for a few minutes and then never return. That is working fine without any problem.

Now lets say they convert to a paid user. At that point I'd like to create a Cognito User pool entry for them and give them more Auth tokens but there is no mechanism to do that. You can't create a Cognito User pool entry that wraps an existing Cognito Indentity entry. Instead Cognito User pool forces you to make a different Cognito Indentity pool entry that is under its control. And of course that different Congnito Identity entry messes up all of the dynamodb indices based on the previous id.

We don't want every user in the Cognito User pool since the bots generate a lot of junk. That would generate a lot of unwanted entries in the User pool for humans to sift through. Our preferred model is for the free accounts to stay in the Identity pool and then give us a mechanism to attach a User pool entry without disturbing the existing Identity pool ID. That way if the user has created something under the free account they will still have it when they convert to paid.

What is missing is a way to say -- using this currently authenticated user (via the Identity pool), create a corresponding User pool entry. That's the API we would hit when they convert from free to paid. Also a corresponding one for removing the User pool entry (without deleting the Identity pool entry) when they stop paying.

Note: we currently deal with this by ignoring User Pools and then having our own Auth system inside of the app which is based on an Indentity pool only.

ceich commented 5 years ago

@jonsmirl Agree with your concerns; in my app I'm using User Pool id as the app's user ID. The Identity Pool id does show up in S3 keys, but we simply capture those as opaque DDB attributes rather than parse/construct them.

undefobj commented 5 years ago

I have one suggestion please: I would like for Cognito to have a built-in monitoring/analytics dashboard. (I know we could use analytics services provided by AWS such Pinpoint) It would be nice to see a user's(s) behavior for the last day/week/month/year. The idea is, instead of using Pinpoint, for example, to have detailed analytics I just want to look at Cognito Dashboard and quickly conclude:

  1. How many new users registered today
  2. How many users logged in today
  3. A specific user's behavior (today she logged in twice, at what time? she logged out, at what time? etc)
  4. Who changes his profile info today (phone numbers, email, etc.) how often users change their profile (Not very important, but it would be nice to have)

@bilal-korir thank you for the feedback. As we are not the Cognito team, this is not something we can directly influence but we can pass along the feedback. However I also suggest that you independently raise a feature request on the Cognito team's forum: https://forums.aws.amazon.com/forum.jspa?forumID=173

rawadrifai commented 5 years ago

Hello - just weighing in on our use case. I am not entirely sure cognito is the best place to manage users. It's the best place to manage authentication only, but all other user info you store it in dynamo. Use the user sub (passed in the header if user is authenticated) as a partition key.

It would be nice to have the following features, depending on what the vision is for cognito (user management or authentication/authorization only).

  1. scan all users in user pool
  2. get item (single user)
  3. update/delete user.. enable/disable. basically all the things you would want control over as an admin of a deployed app.
undefobj commented 5 years ago

The three features I would like are the ability to select from an existing Cognito User Pool, to attach an identity pool to it and to create an user pool client.

@blazestudios23 Thanks for this feedback, we'll take a look at the feasibility of this. There are some technical difficulties with existing resources as the underlying implementation of Amplify CLI uses Cloudformation, so it might mean that functionality becomes disabled with existing resources.

The major issue I have is actually based around SAML though. There is no suppor for SAML from the React Amplify library so I’m forced to use the hosted UI, which isn’t the best for user experience.

While we can look into the CLI provisioning the SAML federation, for the JS library it would be best if you open this as a feature request in that repo directly as this RFC is for the CLI automation: https://github.com/aws-amplify/amplify-js/issues

undefobj commented 5 years ago

Would you be able to automate having two GraphQL APIs for unauthenticated/guest users (using IAM_AUTH or API_KEY) and authenticated users (using COGINITO USER POOL)? Automating it or providing documentation of how to manually set it up would be wonderful.

@eunsanghouse we are looking to automate the configuration of unauthenticated and authenticated access with IAM auth as part of this project. If AppSync supported more than one Authorization type for a single API, would you still need the automation for two APIs?

undefobj commented 5 years ago

What I would like, is to use only Identity Pools without User pools. Since my app is Android only (with a web admin component), every user will have a Google account and I'd like the users to log in only with a Google account, and not creating username/passwords. Even if AWS will take care of 90% of managing the credentials, I can still mess it up, and I don't want to risk that.

@doom777 this is possible today from the JS and native libraries: https://aws-amplify.github.io/docs/js/authentication#federated-sign-in https://aws-amplify.github.io/docs/android/authentication#federated-identities-social-sign-in https://aws-amplify.github.io/docs/android/ios#federated-identities-social-sign-in

Is your question more around having the CLI only create an Identity Pool and configuring that federation only?

RBAC is also important for us, CLI could ask to open a custom YAML file for mapping, the initial file prepopulated with example Role to Users

Good suggestion, and we are thinking of this in terms of the runtime role assignment using Identity Pools as outlined above. Is there a reason a YAML makes sense as opposed to a CSV or other format? Do you have an example flow for this?

Also I'd like to give a huge thank you to the Amplify team for having a dialog with us. It's super important to have someone to talk to, and to know that our issues are being looked into and dealt with. I wish other AWS teams would join you.

Thanks!

undefobj commented 5 years ago

Long-run it would be nice to define groups in some sort of cloudformation/terraform-esque style of syntax. I love how Amplify helps me create all my resources and creates .cf files for them, but I would love to adapt them to my needs. But I guess that tackles a bigger architecture discussion after all.

@FWirtz do you have an example in mind or rough sketch of this? Another person @doom777 above suggested YAML for a similar concept that applies to dynamic IAM roles rather than groups, but the concept is the same. If mappings are of similar concepts but different implementations for the scenario, I'd like to have a single declarative mechanism that is simple to use (YAML, CSV, JSON, etc.). Open to hearing ideas/opinions here from anyone reading.

So: RFC sounds like a great start, would be amazing if the lambda triggered by postSignup was "recyclable" for things like adding users to groups at any given point in time.

Good idea. Noted.

undefobj commented 5 years ago

This is an underlying issue with Cognito Identify and User pools which is not specific to Amplify... In the current model there has to be a 1:1 relationship between the User pool and the Identity pool. Another model would be to allow User pool to be a subset of the attached Indentity Pool. We have issues with the disconnect between Cognito Identity pools and Cognito User pools.

@jonsmirl understood. As we are not the Cognito team, this is not something we can directly influence but we can pass along the feedback. However I also suggest that you independently raise a feature request on the Cognito team's forum: https://forums.aws.amazon.com/forum.jspa?forumID=173

undefobj commented 5 years ago

Hello - just weighing in on our use case. I am not entirely sure cognito is the best place to manage users. It's the best place to manage authentication only, but all other user info you store it in dynamo. Use the user sub (passed in the header if user is authenticated) as a partition key.

@rawadrifai why do you say "I am not entirely sure cognito is the best place to manage users"? Is there a reason you think all attributes should be in a separate store? We could actually automate this, but I'm curious of the motivation or business use case behind your statement.

It would be nice to have the following features, depending on what the vision is for cognito (user management or authentication/authorization only).

  1. scan all users in user pool
  2. get item (single user)
  3. update/delete user.. enable/disable. basically all the things you would want control over as an admin of a deployed app.

Noted - we will address these in the "Admin Queries" portion of the RFC.

jonsmirl commented 5 years ago

Hello - just weighing in on our use case. I am not entirely sure cognito is the best place to manage users. It's the best place to manage authentication only, but all other user info you store it in dynamo. Use the user sub (passed in the header if user is authenticated) as a partition key.

@rawadrifai why do you say "I am not entirely sure cognito is the best place to manage users"? Is there a reason you think all attributes should be in a separate store? We could actually automate this, but I'm curious of the motivation or business use case behind your statement.

@undefobj - we are doing the same thing. We only use the identity pool to authenticate and then all of the user attributes are in a dynamodb table indexed by the cognito-id. I explained above why we do this -- it is to deal with junk accounts created by bots trying to post spam. We don't want that junk inside the system where humans see the user lists. It just collects in the identity pool and no one ever looks at it.

Alternatively if I could put those user attributes into an auth token which was available in my lambda functions, i could save the dynamodb lookup on each call.

flowirtz commented 5 years ago

@undefobj thanks for the reply!

@FWirtz do you have an example in mind or rough sketch of this? Another person @doom777 above suggested YAML for a similar concept that applies to dynamic IAM roles rather than groups, but the concept is the same. If mappings are of similar concepts but different implementations for the scenario, I'd like to have a single declarative mechanism that is simple to use (YAML, CSV, JSON, etc.). Open to hearing ideas/opinions here from anyone reading.

Okay so here is what I'm doing now (and am also quite happy with): Cognito has User Groups that you can attach to users. You can even write them down in Cloudformation. From what I am understanding you can even attach IAM roles to the user groups, thus managing the permissions accordingly. Though I am not using the IAM part atm, I feel like managing the groups as close to the Cloudformation templates generated by Amplify would be the best.

This poses more of a general Amplify architecture question though, imo: Can we, in a nice way, allow users to extend/edit/overwrite the generated Cloudformation templates? I feel like this is needed anyways long term (because stock doesn't work for everybody). I know this is possible, emphasis here on the "in a nice way": When tweaking the Cloudformation files I don't want Amplify to trash all my changes when editing the configs via the CLI etc. etc. etc.

flowirtz commented 5 years ago

Also, to weigh in on the @rawadrifai @jonsmirl "user attributes outside cognito with mapping" thing (maybe worth it's own issue cuz I'm kinda loosing track here): We are actually doing exactly the same thing, storing the user in our DB schema and then just referencing the Cognito one via a sub field.

Why?

Because I personally feel it's nicer. For one, you need to map users to other DB objects anyways, so always going back and forth between Cognito and our DB schema seems very odd.

Example

Users can write Posts. Now, a user has a name and an email, and posts consist of title and body, and also an author (the user). So basically User 1 <---> n Post(s).

Next, I want to get all Posts with their authors.

Solution A: User attributes all in Cognito

If my users and their attributes were only stored in Cognito, I'd need to query the DB AND Cognito - speaking as Cognito's API is ... special (to put it mildly) ... that would result in a lot of API calls and weird merging in the end (or you proxy/wrap the whole Cognito API but that's also weird special.

Solution B: User attributes in DB with reference to sub

Now, this time, I'll put all userdata in the DB as well and link to the Cognito sub. This way, when I want to get all Posts with their authors, I'll just query our DB (maybe even just one call - go GraphQL!!!). From there I will directly get all needed data, no merging, no nothing.

Why do you map the Cognito sub then anyways?

To do authentication and authorisation. The user logs in to our app via Cognito (don't want to be managing them passwords ourselves). Then, we get his JWT Access Token and use it to call our own non-amplify made API and ... (feel like the rest doesn't matter to this elaboration).

Okay sorry for the long post but I didn't see any shorter way to describe it and I thought it was important to explain.

undefobj commented 5 years ago

@jonsmirl @FWirtz understood. Up leveling a bit, you're storing the authorization metadata in attributes of a DynamoDB record for access control rather than going back and forth against Cognito. This is exactly the implementation pattern that the GraphQL Transformer @auth command does: https://aws-amplify.github.io/docs/cli/graphql#auth

The nuance being, today the GraphQL transformer only support Cognito User Pool controls (usernames, Groups, etc.) and not IAM. If we were to expand the @auth directive of the GraphQL transformer for some of these use cases inclusive of IAM would it help?

cc @mikeparisstuff

undefobj commented 5 years ago

This poses more of a general Amplify architecture question though, imo: Can we, in a nice way, allow users to extend/edit/overwrite the generated Cloudformation templates?

This is possible today and we're adding more functionality for this in the future (see: https://github.com/aws-amplify/amplify-cli/pull/581). I don't want to go into details on this thread so that we can keep the topic on the RFC, so please open a new issue if you need guidance for this.

ceich commented 5 years ago

@jonsmirl @FWirtz understood. Up leveling a bit, you're storing the authorization metadata in attributes of a DynamoDB record for access control rather than going back and forth against Cognito. This is exactly the implementation pattern that the GraphQL Transformer @auth command does: https://aws-amplify.github.io/docs/cli/graphql#auth

The reason I don't use Cognito Groups to model my application's "account membership" is the limit of 25 per UP. I do appreciate the dynamic group authorization that @auth already supports!

undefobj commented 5 years ago

@jonsmirl @FWirtz understood. Up leveling a bit, you're storing the authorization metadata in attributes of a DynamoDB record for access control rather than going back and forth against Cognito. This is exactly the implementation pattern that the GraphQL Transformer @auth command does: https://aws-amplify.github.io/docs/cli/graphql#auth

The reason I don't use Cognito Groups to model my application's "account membership" is the limit of 25 per UP. I do appreciate the dynamic group authorization that @auth already supports!

This is helpful. We have had similar requests (see: https://github.com/aws-amplify/amplify-cli/issues/318) and can look at incorporating this work as part of this project during the design.

jonsmirl commented 5 years ago

We pre-date the GraphQL support. Is this part of the docs correct? "Object types that are annotated with @auth are protected by a set of authorization rules. Currently, @auth only supports APIs with Amazon Cognito User Pools enabled. Types that are annotated with @auth must also be annotated with @model."

Is that User pool or Indentity pool? If it is Identity pool I can look into using it.

undefobj commented 5 years ago

Is that User pool or Indentity pool? If it is Identity pool I can look into using it.

Correct it's only User Pools as per my statement above: "The nuance being, today the GraphQL transformer only support Cognito User Pool controls (usernames, Groups, etc.) and not IAM. If we were to expand the @auth directive of the GraphQL transformer for some of these use cases inclusive of IAM would it help?"

sceptyk commented 5 years ago

Correct it's only User Pools as per my statement above: "The nuance being, today the GraphQL transformer only support Cognito User Pool controls (usernames, Groups, etc.) and not IAM. If we were to expand the @auth directive of the GraphQL transformer for some of these use cases inclusive of IAM would it help?"

@undefobj Hi, there. We also have set up access to API for guest and auth users using IAM authentication as suggested in other issues. Having fine-grained access control using @auth directive would be great.

It seems like there was before a way to access $ctx.identity fields but was changed here #354 to enable access to claims. Would it be possible to separate those two with identityField and claimField maybe?

jonsmirl commented 5 years ago

Is that User pool or Indentity pool? If it is Identity pool I can look into using it.

Correct it's only User Pools as per my statement above: "The nuance being, today the GraphQL transformer only support Cognito User Pool controls (usernames, Groups, etc.) and not IAM. If we were to expand the @auth directive of the GraphQL transformer for some of these use cases inclusive of IAM would it help?"

@undefobj - I will need to go read about the ability of Identity pool to log you in with different IAM users (we pre-date that feature) and see if we can make use of it. It does seem like another possibility.

buggy commented 5 years ago

@joebernard Amplify (the core library) has supported passwordless authentication for a while. I'm not sure about the Amplify UI libraries or Amplify CLI

@ceich the 25 group limit on Cognito Users Pools is a soft limit. You can ask AWS to increase it.

why do you say "I am not entirely sure cognito is the best place to manage users"? Is there a reason you think all attributes should be in a separate store? We could actually automate this, but I'm curious of the motivation or business use case behind your statement.

@undefobj YES YES YES YES!!!!! Everyone misses that changing the attributes on a user pool requires replacement. All of your users and groups will be deleted. Like @rawadrifai, @jonsmirl and @FWirtz I keep user data in DynamoDB and map between the two. This allows me to add/remove attributes later. I know one person says they merges the data using the pre-token generation trigger but I haven't tried it personally.

buggy commented 5 years ago

My thoughts on authentication and authorization based on how I'm currently using AppSync.

  1. Most people (not all) should use Cognito User Pools for authentication. It's a good default.

  2. Cognito User Pool groups should only be used for broad level access controls.

  1. Groups inside a tenant should be implemented as fine grained access controls (i.e. administrators for tenant 1234).

  2. Fine grained access controls should always be implemented in the request/response template or in your Lambda.

  3. Implementing fine grained access controls is a lot easier if you use pipeline resolvers and functions.

Q: Is it possible to terminate a pipeline resolver early so that it returns null? I've only seen examples returning errors.

  1. Store data used by fine grained access controls in DynamoDB so it can be accessed quickly (ideally with a single GetItem).

Wish list:

  1. Support for Cognito User Pools and API Keys at the same time. This would enable anonymous queries from clients and make it easier for back end services to trigger subscription notifications via mutations.

  2. It would be really nice if Cognito User Pools supported OAuth 1.0a/2.0 directly. I know it has OpenID Connect support but most OAuth providers don't support this. It might require defining Lambda's that run at certain steps in the process but a library of those for various providers would build up very quickly. I have a very ugly solution for this using passwordless login that I use with Shopify.

undefobj commented 5 years ago

why do you say "I am not entirely sure cognito is the best place to manage users"? Is there a reason you think all attributes should be in a separate store? We could actually automate this, but I'm curious of the motivation or business use case behind your statement.

@undefobj YES YES YES YES!!!!! Everyone misses that changing the attributes on a user pool requires replacement. All of your users and groups will be deleted. Like @rawadrifai, @jonsmirl and @FWirtz I keep user data in DynamoDB and map between the two. This allows me to add/remove attributes later. I know one person says they merges the data using the pre-token generation trigger but I haven't tried it personally.

@buggy I understand your concern around the Cognito Cloudformation replacement policy, but that's a workaround to an underlying implementation concern. We can account for this. Assuming that wasn't an issue, is there still a reason for the statement "I am not entirely sure cognito is the best place to manage users"? from yourself or @rawadrifai?

undefobj commented 5 years ago

Q: Is it possible to terminate a pipeline resolver early so that it returns null? I've only seen examples returning errors.

You can use #return for this - however let's please keep the conversation in this thread focused on the RFC related to Admin auth requirements, issues, and questions as we are gathering information for the upcoming work.

Wish list:

  1. Support for Cognito User Pools and API Keys at the same time. This would enable anonymous queries from clients and make it easier for back end services to trigger subscription notifications via mutations.

Multi-Auth is being looked at by the AppSync team. I will pass along the feedback however for official requests here please log a request on the AppSync forum: https://forums.aws.amazon.com/forum.jspa?forumID=280&start=0

  1. It would be really nice if Cognito User Pools supported OAuth 1.0a/2.0 directly. I know it has OpenID Connect support but most OAuth providers don't support this. It might require defining Lambda's that run at certain steps in the process but a library of those for various providers would build up very quickly. I have a very ugly solution for this using passwordless login that I use with Shopify.

I will pass along the feedback however for official requests to the Cognito team please log a request on the Cognito forum: https://forums.aws.amazon.com/forum.jspa?forumID=173

ceich commented 5 years ago

@buggy I understand your concern around the Cognito Cloudformation replacement policy, but that's a workaround to an underlying implementation concern. We can account for this. Assuming that wasn't an issue, is there still a reason for the statement "I am not entirely sure cognito is the best place to manage users"? from yourself or @rawadrifai?

  1. Sorry for harping on the 25-group limit, but that limit makes me think that Cognito is not designed for an application with O(# groups) === O(# users), i.e. my problem domain.
  2. The promise of GraphQL is "one API to rule####serve them all". I use Cognito Hosted UI so I don't have to think about signup/signin. I don't then want to have to decide, on a case-by-case basis, whether to make a Cognito call or an AppSync call.
undefobj commented 5 years ago

@ceich agreed, in general Group cardinality should be less than that of Users. This is why attributes exist. I think your second point is the more pertinent one, you basically want to do AuthN/AuthZ up front to have user identity as part of your application context when speaking to the backend, and set permissions on the API call for data as appropriate (rather than case-by-case calling multiple services) for that user depending on their group or attribute information. Is this an accurate summary?

ceich commented 5 years ago

@ceich agreed, in general Group cardinality should be less than that of Users. This is why attributes exist. I think your second point is the more pertinent one, you basically want to do AuthN/AuthZ up front to have user identity as part of your application context when speaking to the backend, and set permissions on the API call for data as appropriate (rather than case-by-case calling multiple services) for that user depending on their group or attribute information. Is this an accurate summary?

  1. I was thinking of using Groups to model a many-to-many Account<->User relationship, where each Account has ~10 users and each User is a member of ~3 Accounts (but I don't want hard limits!); not sure how flexible custom attributes (limited to 25 per user, with string values of <=32 characters) would be for that. Currently I'm 100% in agreement with @buggy's views.
  2. Good summary of my second point!
jonsmirl commented 5 years ago

I've read through the docs on Role-Based Access Control for Identity Pools. This could almost work but it is not flexible enough. The only way to choose a role at login is via claims in the JWT token. I can't control the claims in FB/Google/etc tokens.

I could have used this if there was a hook to call a lambda and have the lambda return the role to use. It would work just like the token support, except that after authenticating Identity pool would call out to a lambda which would look up the Cognito-ID and then return the appropriate role ARN. But there is no hook for doing that.

undefobj commented 5 years ago

I've read through the docs on Role-Based Access Control for Identity Pools. This could almost work but it is not flexible enough. The only way to choose a role at login is via claims in the JWT token. I can't control the claims in FB/Google/etc tokens.

RBAC in Identity Pools also works on Cognito User Pool Groups not just token claims.

I think some threads are mixing here as you might be trying to match up your specific use case with the general asks in the RFC. While the feedback is great, I'd ask do you have any specific requirements for "Admin Auth" in this RFC in addition to what is already in this issue thread? I want to ensure we're capturing customer requirements rather than going down any implementation specific rabbit holes.

undefobj commented 5 years ago

Note - We have published a sample of using Auth & UnAuth users in an AppSync API here: https://github.com/dabit3/appsync-auth-and-unauth

This uses AWS IAM via Cognito Identity. One of the RFC goals will be to make this automated. If you have any specific thoughts on this automation please comment in this issue.

heauton commented 5 years ago

we are looking to automate the configuration of unauthenticated and authenticated access with IAM auth as part of this project. If AppSync supported more than one Authorization type for a single API, would you still need the automation for two APIs?

@undefobj If AppSync supported multiple Authorization types, automating two APIs would not be necessary. The simplest example to understand use case would be something like Smashing Magazine where:

With multiple Authorization types, I guess I could have guest users use IAM or API KEY auth and authenticated users use COGNITO USER POOL auth for group-based authorization rules via GraphQL transform.

But meanwhile, I'd love to see some sample (like the auth & unauth user sample above) so I could set two GraphQL APIs manually.

KhaledSoliman commented 5 years ago

+1 the post-signup trigger for auto-adding cognito user groups.

And, is there by any chance any possibility of implementing some sort of trigger to use a custom SMS provider instead of SNS, as SNS doesn't support senderID in my country and costs double the normal fee for SMS providers in the MENA region

Jun711 commented 5 years ago

@undefobj

Yea, regarding disabling/delete users on another thread, it would be the 3rd point mentioned in this comment. https://github.com/aws-amplify/amplify-cli/issues/766#issuecomment-458792183

Enhancement: currently, I can use admin-disable-user or admin-delete-user to disable / delete users. However, it won't happen immediately because tokens are valid for at least an hour.

It would be great to have a user disabled immediately to prevent access to AWS services such as API Gateway endpoint authorized by Cognito token. Thanks

ceich commented 5 years ago

I also would like mixed AuthN between a User Pool and something, where the latter is used by a Sumerian scene that will be calling AppSync while running on a dedicated device. I can either create a UP entry for each device (weird but doable, and requires password management on-device), or create a cert or other credential for each device, and use that to get tokens for use in AWS APIs.

bradennapier commented 5 years ago

It is not possible to force unique emails and usernames (case sensitivity). Docs say that you can do this after the fact but you can not. You can not protect bots from signing up millions of times with the same email address and information.

undefobj commented 5 years ago

It would be great to have a user disabled immediately to prevent access to AWS services such as API Gateway endpoint authorized by Cognito token. Thanks

@Jun711 this is not something that the Amplify team can control. I will pass along the feedback to the Cognito team however I also recommend you log an official request to their forum: https://forums.aws.amazon.com/forum.jspa?forumID=173

undefobj commented 5 years ago

I also would like mixed AuthN between a User Pool and something, where the latter is used by a Sumerian scene that will be calling AppSync while running on a dedicated device. I can either create a UP entry for each device (weird but doable, and requires password management on-device), or create a cert or other credential for each device, and use that to get tokens for use in AWS APIs.

@ceich I'm not sure I understand this scenario. Can you go into more details on your use case?

ceich commented 5 years ago

I also would like mixed AuthN between a User Pool and something, where the latter is used by a Sumerian scene that will be calling AppSync while running on a dedicated device. I can either create a UP entry for each device (weird but doable, and requires password management on-device), or create a cert or other credential for each device, and use that to get tokens for use in AWS APIs.

@ceich I'm not sure I understand this scenario. Can you go into more details on your use case?

I want to ship a device (e.g. preconfigured tablet) to a person who will treat it as an appliance, i.e. turn it on and it works with no login step. Thus it needs to have credentials for accessing AWS (in particular, accessing one particular Account in my multi-tenant AppSync/S3/... application). For now I will create a User for the device (with a User Pool entry) and figure out a way to securely store its credentials. I was thinking an IoT approach might be better long-term, thus my desire for a second AuthN mode.

undefobj commented 5 years ago

@ceich This is interesting, but as you mention it's more of an IoT scenario. That doesn't mean it's necessarily something that we don't want to look at longer term in Amplify, however I'd call this out of scope for this RFC. Certificate management in general is a tricky thing to manage including the ownership chain, so I'm not sure what that would look like in something like Amplify. Could I suggest that if you think about this in more detail could you open up a new issue with the end to end desired experience and use case?

jonsmirl commented 5 years ago

@ceich Using a certificate to get credentials is already supported by AWS IOT. https://docs.aws.amazon.com/iot/latest/developerguide/authorizing-direct-aws.html It is not obvious to me how to implement the initial certificate based connection to AWS IOT from Amplify.