Skip to content
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

Custom authorizer for AWS AppSync #2

Open
itrestian opened this issue Feb 27, 2019 · 9 comments

Comments

@itrestian
Copy link

commented Feb 27, 2019

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

See related issue:
#1

@jeff-shep

This comment has been minimized.

Copy link

commented Mar 22, 2019

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

Context:

  • We are not using Cognito as an Identity Provider and this is a constraint of the AppSync solution we implement.
  • We have a client (front end) and a machine (lambda) accessing the AppSync API. We are using a JWT for both types of access but the OIDC provider of the token is different - the difference being we are using the client credential grant for the machine. This is again a constraint of the AppSync solution we implement.

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

This comment has been minimized.

Copy link

commented Mar 27, 2019

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.

@appwiz appwiz added this to To do in AWS AppSync Features May 3, 2019

@buggy

This comment has been minimized.

Copy link

commented May 15, 2019

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

This comment has been minimized.

@buggy

This comment has been minimized.

Copy link

commented May 16, 2019

@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

This comment has been minimized.

Copy link

commented Jun 5, 2019

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

This comment has been minimized.

@dashmug

This comment has been minimized.

Copy link

commented Jul 5, 2019

We need this as well.

@bmilesp

This comment has been minimized.

Copy link

commented Aug 8, 2019

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
7 participants
You can’t perform that action at this time.