Scaling AuthZ with Amplify
Tags: aws, appsync, authorization, amplify
Published: 2020-12-29 01:05:12

[AppSync](https://aws.amazon.com/appsync/) is an amazing tool for building APIs. It's serverless- so you can spend more time building what matters. It also has integrations to resources like AWS Cognito and schema generation from [AWS Amplify](https://aws.amazon.com/amplify/), your schema and authorizations can all live in one place.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/k4gjhhcxxoo8lu20c7xu.png)

### Scaling with `@auth`

If you've ever worked with Amplify you know how great the framework is at simplifying the complexity of AWS. Amplify helps you build the latest and greatest in serverless architecture, in the simplest possible way. It's a new framework with a bright future but isn't without growing pains.

For AppSync APIs in more complex authorization schemes (multi-tenant, multi-many-to-many), using just 'owner' and 'group' settings for the `@auth` directive provided by Amplify starts to get tricky. You may run into situations where it's unclear how to authorize certain data without substantially altering your schema design. Well don't throw in the towel quite yet- there's still hope!

## The power of AppSync IAM authorization

Want to write less VTL, more Javascript, and still get the benefits of Amplify's codegen? Then you'd be happy to find out that you can leverage AppSyncs IAM auth to do just that.

👇 This `@auth` transformer rule is pure ✨magic✨- and here's why:

{% gist https://gist.github.com/r0zar/168e2d73c19d09a3b060016107ac474e %}

# The Proxy-Dispatcher pattern

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/bmymu59x443x9j39y9qs.png)

The concept is simple, in place of owner and group `@auth`- leverage IAM auth and run queries from a `@function` resolver.

Consider a "simple" schema with a few many-to-many relationships...

{% gist https://gist.github.com/r0zar/0c175c49d24e46d8ee7be13f8ecbdbbc %}

Apologies that you had to scroll through all of that. Lengthy for sure, but consider how little code is required in the schema to fully authorize it.

You may have actually noticed that a client-side application would have _zero_ access to data with the above schema, and that's intentional. We'll be adding a few new operations for the client to use:

{% gist https://gist.github.com/r0zar/28612fbf2f4c868519b01803d9e0ac37 %}

The `@aws_iam` and `@aws_cognito_user_pools` directives are just native AppSync ones, and what `@auth([{allow: private}])` would transform into, so either form works.

The final step is to deploy a `@function` resolver that can handle the above operations and return data to the user based on the custom business logic. That'll be for my next blog post!

## Final thoughts

Not sure if this approach is for you? If you have an AppSync APIs and are managing many-to-many models, you've either battled or currently are wrestling with these scenarios. If your API is relatively simple, stick with the owner/group `@auth` directives provided by Amplify. They're easy to implement and will keep your app secure with little complexity overhead.

You can expect the queries to be slower, due to cold starts and the extra AppSync request. While this can help with corner cases for tough authorizations, you'll still need to have a working understanding of VTL if you want to optimize your common case queries.

Another downside to this approach is having to manually add input types to the schema to have feature parity with the generated filters and conditionals generated by Amplify. I'm currently working on a new Amplify GraphQL Transformer that will eliminate this redundant code and could open the door to some cool, new schema designs as well.

If you found this useful or would like to hear more- leave a comment, 🖤 and subscribe! Thanks.