-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Multiple Authorization Types with an AWS AppSync Endpoint #1
Comments
Hi this sounds nice and is exactly what I need. So thanks for working on this! One question: Is it possible to define two objects (types and/or inputs) with the same name but different fields for two different ident methods? I see that I could do this with the in field declaration but it would be not that readable and more error prone then two separate objects. E.g. type Order { type Order @aws_api_key { Thanks for your amazing work and I'm looking forward for this feature. |
Hello, Firstly thank you for opening up the AppSync community, it's great to be able to contribute ideas and feedback to the development of the product. Adding a +1 for the authenticated and unauthenticated requests. It's something I've come across frequently. My preference would be to have an annotation which is completely public, rather than one needing an type Post @public {
id: ID!
author: String
title: String
content: String
restrictedContent: String!
@aws_iam
} Thank you for the continued development on AppSync, and like others I am looking forward to this feature. |
We don't use the code generation side within Amplify (currently only using the Amplify React and React Native libraries), but would absolutely love to see API_KEY + USER POOLS as auth options for a single API, for the anonymous access issue (as right now, we have to create an "anonymous" user in the user pool, which creates issues we have to work around).. I would just want good ways to set this up through the CLI and a coherent way to test easily which was in use in our resolvers. Ideally some way to tell that would be a fairly simple VTL check. |
There's already an schema {
query: Query
mutation: Mutation
}
type Query {
getPost(id: ID): Post
getAllPosts(): [Post]
@aws_auth(api_key: true)
}
type Mutation {
addPost(
id: ID!
author: String!
title: String!
content: String!
url: String!
): Post!
}
type Post @aws_auth(api_key: true) {
id: ID!
author: String
title: String
content: String
url: String
ups: Int!
downs: Int!
version: Int!
} Given that each authentication method is separate it would allow something like
This could imply Cogito users in the group Could there be an option to set the default to ALLOW/DENY for each authentication method similar to how Cognito User Pools does it? Example: A GraphQL API behind a public website. A few types/fields are only available with Cognito User Pool authentication but most types/fields are available regardless of whether an API key or Cognito User Pool token is used. With the current proposal I would need setup Cognito User Pools as the default authentication method then add I'd like to know more about how you add the extra authentication methods. Will this support CloudFormation? +1 for for true anonymous access (i.e. no API key, no AWS IAM, no authorization at all). |
Thank you for this proposal. This sounds like a great idea. |
@bboure Could you create a new issue in this repository requesting |
@Tixamala You wouldn't be able to define 2 object types with the same name in the same AWS AppSync API but with this proposal, you wouldn't need to do that. We would support multiple directives on the same object type definition and in the case of an unauth/auth mix on the AWS AppSync API, you would have access to fields marked as unauthenticated by supplying an authenticated authorization method configured on your AWS AppSync API. @jgunnink The reason for having an api key for unauthenticated access is that in the future we want to provide customers with the capability to throttle and for this we would need an identifier for customers to throttle on. However, yours is a legitimate request that we have heard in the past and I will +1 the internal feature request on your behalf. @joemastersemison This is entirely server-side. The CLI would leverage server-side auth capabilities. @buggy That is one of the paths we considered for this proposal. However, the @aws_auth directive currently works only on top level query and mutation types. We wanted to give users more flexibility when specifying directives such as placing them on object type definitions or individual fields within an object type definition. @bboure I have created the following feature request in this repo on your behalf that other users can +1. |
Thanks @itrestian |
@itrestian For instance, every unauthenticated user gets added to a unauthenticated group, and in that way we can define the scope of the authorization based on that group. type Query {
getPost(id: ID): Post
getAllPosts(): [Post]
@aws_auth(cognito_groups: ["unauthenticated"])
} Let me know if this makes sense for you guys. |
Yes, I understand the workaround. It is similar to what JeffB@AWS is suggesting here: https://forums.aws.amazon.com/thread.jspa?messageID=841543&tstart=0 One thing to note is that this accomplishes only part of the use case (public/private mix on the same AWS AppSync API) and not the admin combined with another authentication type. Also the guest user pool user would need to have a shadow profile and a password within the user pool itself. |
@itrestian |
I'm stoked that this thread exists and you all are looking to add something like this. I think I ended up using Cognito user pools to programmatically create / log in "server" users with the roles I want to have access to certain mutations since I haven't found a way to do so otherwise. This allows me to have multiple points of entry from the server via different lambda functions that I can lock down with certain roles without having to drop down to IAM and all of the downsides of doing so. I can just use the access token returned from my server authenticated Cognito user in the header to make the requests I need. This approach also allows me to have some semblance of "unauthenticated" users as well. If only one API key is supported, I don't know that this would address the types of role based access on the server side I would want. Hope this helps! |
@luillyfe get-id is a Cognito Federated Identities call, not a Cognito User Pools call. Yes, it would get you an unauthenticated identity in case you don't have a login from an authorized provider but you would need to have AWS_IAM enabled on your AppSync API, not AMAZON_COGNITO_USER_POOLS authorization since currently AWS_IAM and AMAZON_COGNITO_USER_POOLS are mutually exclusive on the same AWS AppSync API. Both have workarounds for achieving the unauthenticated/authenticated use case which are better explained in the post I linked. @lanceharper This proposal is not meant to address the RBAC use case that you brought up (totally valid use case) but mostly to allow mixing authorization providers on the same AWS AppSync API. What you are currently doing today would still be possible under this proposal. Not sure if this is what you meant but multiple API keys would be supported on the AWS AppSync API. Can you expand more on the challenges you are facing? Do you mean you don't have the SDK support to access the AppSync data plane server-side or are these challenges mostly in authenticating with Cognito from a server environment? |
I hear that but if the proposed approach is to remove the mutual exclusivity of authorization types, I don't know that merely allowing the current
If the current proposal to just support the authenticated vs unauthenticated use case, I think it is a step in the right direction, but I would probably not find it granular enough for a lot of use cases and would still require workarounds like using system generated users in Cognito. Would API Keys last more than seven days?
I'd like to be specific when it comes to the ability to trigger certain mutations (or even surfacing that they exist). I know that some of the issue is within the GraphQL spec itself. But I'd like to make it easier than it is now to have specific lambdas call specific mutations while still being able to use Cognito to manage users of the application. The AppSync library can be used in node to sign for IAM but that limits me to using Node if I want out of the box support and makes it challenging/impossible(?) to use user pools. My ideal scenario is a straightforward approach for using lambdas written in a non-Node language (e.g. F#) to trigger a mutation on AppSync such that I can easily leverage the subscriptions I've associated with it. I haven't seen any documentation or other examples other than the blog post I referenced above so my current workaround of using (fake) Cognito users has been the only workable solution I've found so far. Maybe I'm missing an easier approach though. |
I'd like like to +1 what @luillyfe suggested. This is probably a feature request for the Cognito team though. I guess that a workaround, for now, would be to programmatically generate a fake user, with a fake username and password and then update it if the user decides to sign-in. That is not an ideal solution though. Basically, what I suggest is something similar to guests in Identity pools, but for User Pools. |
@lanceharper 7 days is the default for API Keys, the maximum is 1 year: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-apikey.html Thank you, I understand your use case better at this point and providing better support when using AppSync from Lambda together with better examples is on our roadmap. @bboure Yes, that is a feature request on the Cognito team that I will pass along. |
Can you clarify the permission model a little more? I'm confused on when adding a directive will expand access vs restrict access. The first example of the proposal shows that adding It is very important to me that I can quickly reason about access grants when reviewing a schema. Thank you! |
But I would extend
I am in agreement with @buggy . I think extending the existing auth directive makes the most sense. And because Anonymous access is a huge issue it seems like making it a first class auth type makes sense. |
@michaelansel Just to explain better, what we are proposing is to have a default authentication type on the schema corresponding to the current authentication type on the GraphQL API. If you don't make any modifications to the schema or API settings, everything will work exactly the same way as it currently does. With this proposal, users would have the chance to add additional authentication providers as settings on their GraphQL API. These would be similar in shape to the existing settings that you can pass as authentication settings. Just adding additional authentication providers would still not have any effect on your GraphQL API because you haven't annotated your schema with directives. There are 2 places that you will be able to place directives: on fields inside a type and on object type definitions. Just to give an example of what happens when users are trying to query their AWS AppSync endpoint. Suppose your existing authenticationType setting is type Query {
getPost(id: ID): Post
getAllPosts(): [Post]
@openid_connect
} You can also specify directives on object type definitions to secure them. For example, you can specify that the type type Post @openid_connect
@aws_iam {
id: ID!
author: String
title: String
content: String
url: String
ups: Int!
downs: Int!
version: Int!
restrictedContent: String!
} If you want to further restrict the type Post @openid_connect
@aws_iam {
id: ID!
author: String
title: String
content: String
url: String
ups: Int!
downs: Int!
version: Int!
restrictedContent: String!
@aws_iam
} Now all fields inside Hope this explains it better. @clearly Thank you for the feedback. I will pass it on to the team. |
@itrestian With this proposal, could you set multiple default authorizers? For one of the AppSync APIs I work with it would be great to allow clients authorized via both IAM and Cognito UserPools, but I wouldn't want to have to specify that for almost every single type in my model. |
@lordpython That's a good point, I will bring it up with the team. |
@itrestian really need this feature. This feature can fix lots of problems. |
Yeah, API + Cognito User Pools (and especially more than one) would be incredibly helpful for us aswell. Hopefully it'll be implemented relatively soon! <3 |
I'm also looking forward to having this feature. I'm currently trying to change authentication from Amazon Cognito User Pool to IAM because I want to call AppSync from a lambda function but since I need the Cognito Sub for some of the calls it is rather difficult. @itrestian can you give a prediction for when this feature will be available? |
This is slightly off topic but will AppSync add Lambda authorizer (custom authorizer) to authorization types as for API Gateway? |
I will @appwiz ! I am still new to the project and don't have the details for our authentication flow. We are currently using a custom authorizer in API Gateway and we are investigating in possibilities to migrate to AppSync. |
Does additional authorization types support cloudformation? |
Yes, cloud formation support will be available. |
Hi, For amplify this pull request aims to solve multi auth for appsync. |
Perhaps having multi auth would simplify the process of triggering AppSync mutations over This assumes the front end would have access to the subscription using This also assumes we can leverage Social Identity Providers with AppSync while auth type is set to Perhaps having Lambdas use a dummy Cognito user to cause mutations is a valid approach, but seems less correct to me. |
I don't think it's officially announced yet, but this feature just got enabled for us in the AppSync console :) The aws-sdk-js seems ready aswell. |
@d2kx, @itrestian is hard at work rolling it out to all regions. |
Seems to have been rolled out! The documentation is also available. https://docs.aws.amazon.com/appsync/latest/devguide/security.html#using-additional-authorization-modes The groups for cognito can also be secured using Happy coding! |
And now the feature is live!!! |
Any information on how to configure it using CloudFormation? |
Is CLI support for the GraphQL Transformer (@auth directive for multiple auth methods, or whatever the equivalent of @aws_iam etc. from the console will be) till forthcoming? Or am I just blind :) |
The cli has a new If that is what you're looking for |
@d2kx @erezrokah we'll be adding multi-auth features to the Amplify CLI in the coming month(s). Please inquire additionally in that repo for functionality questions. |
@erezrokah CloudFormation docs will be out pretty soon. Here's an example on how to configure AdditionalAuhenticationProviders using CloudFormation on your GraphQLApi:
|
Thanks @itrestian I figured it out by following the |
Is there some plans to add this kind of directive to Graphql Transform? |
Is there any idea when and perhaps if this is already implemented in AWS Amplify? Unfortunately the documentation does not seem to mention much about these mixed Auth possibilities and it's a bit challenging to reverse engineer the above example in the AWS Amplify schema (https://aws-amplify.github.io/docs/cli-toolchain/graphql#auth) |
Has anyone been able to figure out how to apply group level access to queries/mutations when using the @aws_oidc directive? I am using Auth0 where I have "permissions" in my access token as a claim and I am trying to restrict access to certain queries/mutations based on the list of permissions. |
I am in the same ship, I doubt it is possible to setup fine grained authorization with @aws_oidc like cognito groups because AppSync documentation does not instruct any such thing. I had hopes with @auth directive but they are also diminishing more I dig deep. The amplify documentation also seems to suggest the same with its line '@auth Defines authorization rules for your @model types and fields' which means it can only be used with @model types? see here |
Multiple Authorization Types with an AWS AppSync Endpoint
Currently, AWS AppSync endpoints support 4 types of authorization: AWS_IAM, AMAZON_COGNITO_USER_POOLS, API_KEY, and OPENID_CONNECT. The 4 options are mutually exclusive meaning they can't be mixed inside the same AWS AppSync API.
We heard multiple times that customers want to mix authorization types with their AWS AppSync APIs and this proposal is seeking feedback on our current vision for doing so. Some of the most common scenarios we have heard customers ask for are the following:
With this proposal, users will have the ability to add additional authorization types to their AWS AppSync APIs through the console and the CLI.
We propose that, at the schema level, different authorization types can be specified using directives on the schema. Users can specify authorization modes on fields in their schema. For example, for API_KEY authorization one would use
@aws_api_key
on schema types/fields.We propose that we will maintain the existing setting with regards to authorization at the AWS AppSync API level. This setting will act as the default on the schema meaning that any type that doesn't have a specific directive will have to pass the API level authorization setting same as before so existing AWS AppSync APIs and schema will act exactly as before if users don't make any changes to their settings and schema. As mentioned before, developers will have access to directives only by adding additional authorization methods to their AWS AppSync APIs. Adding multiple Cognito User Pools/OIDC as authorization providers to your AWS AppSync API will be possible.
Example: If Cognito User Pools is currently enabled as the authorization type on a AWS AppSync API meaning all fields that don't have a directive on the schema need to pass Cognito User Pools authorization. API Key can also be enabled as another authorization provider on the AWS AppSync API and users can make a type available for API_KEY authorization by using a
@aws_api_key
directive against it on the schema such as below.Field-level auth with new auth directives
Auth directives can be specified on root level queries and mutations. They can also be specified on object type definitions and on individual fields. For the example above, we specify that getAllPosts can be accessed by using an Api Key. We are also specifically saying that Post can be accessed using an Api Key. Note that all the authenticated options such as AWS_IAM, Cognito User Pools, and OIDC can access Api key protected types/fields. This functions as an access control list such that if you go more specific and that in the Post for example, you restrict access to certain fields. For example we can add a restrictedContent field to the Post type and restrict access to it by using the
@aws_iam
directive. AWS_IAM authenticated requests would be able to access restrictedContent, however Api Key requests would not be able to access it.The text was updated successfully, but these errors were encountered: