You can find code example for this chapter here.
AppSync supports a couple of directives to control access to fields in the schema. What we'll implement here is to deny the Query.allUsers
to non-administrator users. This is rather easy, as AppSync integrates with Cognito and supports granting and denying access based on the users' groups.
The solution is a simple directive in this case:
type Query {
allUsers: [User]
@aws_cognito_user_pools(cognito_groups: ["admin"])
}
But as usual, there is some fine print here. So instead of stopping there, we'll look into the details of how the access control directives work in AppSync.
AppSync uses different directives depending on whether Cognito is the only authorization provider or other ones are defined as well.
When Cognito is the only one defined, the @aws_auth
directive controls access:
type Query {
allUsers: [User]
@aws_auth(cognito_groups: ["admin"])
}
But when there is another authorization provider, the @aws_cognito_user_pools
is effective:
type Query {
allUsers: [User]
@aws_cognito_user_pools(cognito_groups: ["admin"])
}
This means adding an additional provider disables all access-related directives on all fields and types. Moreover, there are differences between how the two directives work.
Because of this, I recommend always adding a second authorization provider even if you don't plan to use it. The safest and easiest way to do this is to add IAM as a secondary.
As we've seen previously, AppSync supports multiple authorization providers. They define the different modes of access, such as Cognito User Pools, or IAM. It is also possible to add multiple providers to a single API.
For example, it's common for end users to log in via Cognito while some admin processes use IAM. By adding both to the API makes both use-cases possible.