How to exclude attribute from Amplify DataStore query?

0

Hi there, I have two apps, one is an Amplify web app where users can issue API Keys and the second has a custom API Gateway Authorizer that verifies the API Keys. The Amplify web app authenticates via Cognito User Pools and the other app via AWS IAM. Also, I want users to be able to view the API key only once, at creation, for security reasons. On the other hand, the Authorizer must be able to query by apiKey to verify it. Therefore, I added apiKey: String! @aws_iam to prevent the Amplify app from accessing apiKey and it works as expected. However, now a query like DataStore.query(ApiKeys, null, {age: 0, limit: 100}); throws Not Authorized to access apiKey on type ApiKeys.

Is it possible to instruct the query to NOT retrieve the apiKey attribute? Something like projections in MongoDb would make sense.

Thanks!

schema.graphql

type ApiKeys @model @auth(rules: [{allow: owner}]) {
  id: ID!
  name: String
  apiKey: String! @index @aws_iam
  owner: String
}

Full error from https://<redacted>.appsync-api.us-east-1.amazonaws.com/graphql

 "errors": [
        {
            "path": [
                "syncApiKeys",
                "items",
                0,
                "apiKey"
            ],
            "data": null,
            "errorType": "Unauthorized",
            "errorInfo": null,
            "locations": [
                {
                    "line": 11,
                    "column": 7,
                    "sourceName": null
                }
            ],
            "message": "Not Authorized to access apiKey on type ApiKeys"
        },
]
1 Answer
0

In AWS AppSync and AWS Amplify, you can control the fields that are returned in a query response by specifying the @auth directive and using field-level authorization rules. However, when you use @aws_iam as you've done to restrict access to the apiKey field, it enforces that restriction at the field level and not the query level. This means that even if you specify a query that doesn't request the apiKey field, the authorization rules applied to the field itself will still trigger an unauthorized error.

To allow users to query for records without retrieving the apiKey field, you can consider a couple of approaches:

First Approach Create a Custom Resolver: Create a custom resolver for the query that retrieves the data from your DynamoDB table. In the custom resolver, you can control which fields are returned. This allows you to exclude the apiKey field from the response. There are some steps to help achieve that:

  1. In your AWS AppSync API, go to the schema and create a new query (e.g., listApiKeysWithoutApiKey) that doesn't include the apiKey field.

  2. Create a custom resolver for this query. In the resolver mapping template, you can specify which fields to fetch from the DynamoDB table, excluding the apiKey field.

  3. Ensure that the IAM permissions for the custom resolver allow the query to execute without any restrictions on the apiKey field.

Second Approach If you want to handle this client-side, you can retrieve the full records (including the apiKey field) from the query, but then filter out the apiKey field on the client side before displaying it to the user. This way, the field is still retrieved from the server, but it's not displayed to the user. This approach allows you to retrieve the complete data but exclude the sensitive apiKey field before returning it to the user.

The custom resolver approach gives you more control over what data is retrieved from the server, while the client-side projection approach allows you to retrieve all data but control what is displayed to the user.

Please let us know if this was helpful!

profile pictureAWS
answered 8 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions