aws / aws-appsync-community

The AWS AppSync community
https://aws.amazon.com/appsync
Apache License 2.0
506 stars 32 forks source link

Custom authorizer for AWS AppSync #2

Closed itrestian closed 3 years ago

itrestian commented 5 years ago

Customers have expressed interest in a custom authorizer for AWS AppSync where they can configure a custom lambda to authorize requests.

See related issue: https://github.com/aws/aws-appsync-community/issues/1

jeff-shep commented 5 years ago

Having reviewed the related issue, I believe our use case sits under this requirement.

Context:

Our solution: We have deployed Pipeline Resolvers that trigger a Custom Authoriser Lambda that we pass the JWT to for verification and check the roles/scopes included in the token against the various AppSync Fields. This returns a True/False and we interrogate that response in the Response Mapping Template and either return 'Unauthorised' or allow the next Function in the Pipeline Resolver to go and 'complete the action' - be that get a value from Dynamo or hit some external API.

The sticking point: We pass the AppSync API key in the request as well, so that we can get through the 'front door' and then execute our custom auth in the backend. We don't want to do this and introducing Cognito into the system is not desirable for reasons I won't detail here.

In an ideal world we would like the AppSync Managed Service to allow us to configure two OIDC providers when using OPENID_CONNECT as the security type. Failing this, we would like the 'plumbing' for a custom authorizer to be part of the service to simplify our deployment process and remove the need for us to send an API Key in the request as well.

Potential solution (just my thoughts..) AppSync exposes an API that we can call to upload our custom auth code - the service handles deploying that for us and returns the standard lambda response (ARN etc...) We use the ARN when defining the DataSource for our Custom Auth Function. AppSync then exposes a new type of Security option (Custom) and this doesn't require us to provide an API Key but defaults to Unauthorized until we explicitly resolve the Fields using a Pipeline Resolver.

There is much detail here and it would be interesting to know how others have attempted to solve this Custom Auth issue in lieu of it being integrated into the AppSync Managed Service. We have an Enterprise Support argeement with AWS and so I will inform our Technical Account Manager of this issue too in the event you would like to discuss this in a private forum to fully understand our use-case.

buggy commented 5 years ago

I think it would make sense to mimic the API Gateway Lambda authorizer approach. Incoming requests trigger a Lambda that responds with an IAM policy. AppSync would assume that policy when handling this request. It's basically AWS IAM authentication but the policy is returned from Lambda instead of based on who signs the request. You can also pass back additional information that will be available as part of the $ctx.identity.

buggy commented 5 years ago

An important part of the API Gateway Lambda/Custom Authorizer implementation is the ability to set a context which is passed as part of the users identity.

In SaaS apps this provides an opportunity to efficiently load user permissions once at the start of the request instead of needing to reload them in every resolver.

Example: We store the tenantId with every record in DynamoDB. Users may have access to multiple tenants with different levels of permissions. I'd like to be able to set the context in the customer authorizer to something like:

context = {
  "tenant1": { "canRead": true, "canUpdate": true },
  "tenant2": { "canRead": true, "canUpdate": false }
}

In the resolver template I could use the tenantId from the DynamoDB record combined with $ctx.identity.context.TENANT_ID.canRead to quickly determine if someone has access to a record or not.

This is partly related to #9.

appwiz commented 5 years ago

https://twitter.com/richbuggy/status/1128472544074276864?s=21

buggy commented 5 years ago

@appwiz The video isn't up yet but I'll attach a link when it is.

I spent a lot of time looking into SaaS user models a few months ago and concluded that there are three common models:

  1. The user is the tenant. Examples: Twitter
  2. All tenants share a single user pool. Examples: Github, Facebook Business Manager
  3. Each tenant has their own user pool. Examples: Shopify, Slack, most enterprise apps

The first model is really simple to implement and well supported today. Both models 2 and 3 can have complex permissions models. Model 2 can be implemented today with some effort but model 3 requires custom authorizers.

At piiq we currently use model 2. Application level permissions like support or admin that I give to piiq staff use Cognito User Pool groups but tenant permissions are stored in DynamoDB. I'm happy to provide more details about this and the challenges we've had offline. Suffice to say, it would make life easier if we could use a custom authorizer to load tenant permissions once per request.

harveyramer commented 5 years ago

I also need exactly this solution. Our basic architecture is derived from this AWS sample project: https://github.com/aws-quickstart/saas-identity-cognito

buggy commented 5 years ago

@appwiz The video I mentioned is now available at https://anz-resources.awscloud.com/aws-summit-sydney-2019-build/securing-saas-applications-built-on-serverless-microservices-3.

dashmug commented 5 years ago

We need this as well.

bmilesp commented 5 years ago

+1

mathiasmoeller commented 4 years ago

+1

emanuelherrmann commented 4 years ago

+1

surakshith1 commented 4 years ago

+1

robertfarnum commented 4 years ago

+1

DaveLo commented 4 years ago

This feature would be hugely useful, we are exploring unifying some legacy apis behind appsync.

Our internal users would be fairly easy to port over into cognito, but we have a class of internal users that have alternate logins (PIN codes) for some kiosk style apps which would require some custom authentication but would follow the same permission group structure as the full login users.

jagabs commented 4 years ago

Do we have a tentative release date for this? This would be really useful!! Thank you everyone.

55Cancri commented 4 years ago

Please allow custom authorizer with lambda. Also, why does every example of appsync include amplify and cognito user pools? Anyone have any examples using authentication other than user pools? Using aws cdk, no amplify, and apollo react on client.

EralpB commented 4 years ago

+4

ghost commented 3 years ago

I guess this is already supported? https://aws.amazon.com/blogs/mobile/appsync-custom-auth/

mathiasmoeller commented 3 years ago

The problem there (IMHO) is that you still need to use the API Keys which are not very flexible.

buggy commented 3 years ago

@dusan-dragon it's still not supported :(

jbailey2010 commented 3 years ago

Hi all,

@awsed announced last week that this is, in fact, coming! I can't share timelines with you (yet), but stay tuned 😄

nicolobissaccowarda commented 3 years ago

+1

jonathanarevalogaray commented 3 years ago

Any news on this? Looking forward to seeing this happen! :)

ursixc9 commented 3 years ago

Any update is greatly appreciated. I would like to know the status on this as well. Thanks!

slikk66 commented 3 years ago

hi, im starting out with Appsync + Cognito.. my plan was to have one AWS account at our Org level that holds our cognito. I was planning to hold users in that user pool, and have that cognito be the authorizer for Appsync in multiple other accounts. I've been searching for a while for "cross account cognito appsync" and was lead here. It seems like this is not possible at this time until this feature on this issue is added? My appsync api seems to work with the "cross cognito" if I set it to ALLOW, which appears that it would let any Cognito token work, which is obviously not what I want. Thanks!

rraczae commented 3 years ago

+1. this is blocking us as well

Liooo commented 3 years ago

@mk0a1a @slikk66 @rraczae

FYI: We were able to work around this appsync cross account cognito thing by using OpenID Connect as the authorization mode and setting the issuer URL to https://cognito-idp.{region}.amazonaws.com/{userPoolId}.

rraczae commented 3 years ago

hey @Liooo, thank you we actually ended up doing something similar. For us it's a bit more complicated because we are using amplify as well and then the whole thing snowballs not just appsync. Eventually we created a 2nd cognito pool and connected that to the "main" pool through OIDC. It works well, however it's definitely an extra layer and plus cost.

joekendal commented 3 years ago

+1

jonathanarevalogaray commented 3 years ago

Any news on this? Huge blocker.

Jonathan34 commented 3 years ago

See https://aws.amazon.com/blogs/mobile/appsync-lambda-auth/ :)

KoldBrewEd commented 3 years ago

We just launched Lambda Auth support for AppSync. You can find details in the docs:

https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html#aws-lambda-authorization

Thank you all for the feedback.

joekendal commented 3 years ago

Hi, does this new feature have any performance improvements over the pipeline resolver method?