amplify-category-api
amplify-category-api copied to clipboard
Field level authorization with multiple owners per field
Amplify CLI Version
12.6.0
Question
I'm building a dual approval process in Amplify using AppSync and Cognito auth, where the confirmation of both the two actors, ActorA and ActorB, is needed to consider the process approved. In our scenario only ActorA, aka "sender", can initiate the process and ActorB, aka "recipient", can confirm or reject the approval delayed.
In order to implement that, I'm using
- field level authorization https://docs.amplify.aws/gen1/javascript/tools/cli-legacy/auth-directive/#field-level-authorization
- custom ownerField https://docs.amplify.aws/gen1/javascript/build-a-backend/graphqlapi/customize-authorization-rules/#per-user--owner-based-data-access
- multiple owners per field. Although it works, there is no mention of it in the docs.
With this scenario, the field level authorization is completely handled by amplify autogenerated resolvers. Moreover, I rely on Lambda custom VTL resolvers only for user input data validation and some business logic.
Attached to the Approval
DynamoDB table there is a DynamoDB Stream triggered lambda that marks as Approved or Rejected the relevant document status, based on our custom logic.
The schema.grapql
looks like:
type Approval @model @auth(rules: [{ allow: owner}]) {
id: ID! @auth(rules: [{ allow: owner, operations: [update,create,read], ownerField: "senderOwner"},{ allow: owner, operations: [read, update], ownerField: "recipientOwner"}])
senderOwner: String @auth(rules: [{ allow: owner, operations: [create,read], ownerField: "senderOwner"},{ allow: owner, operations: [read], ownerField: "recipientOwner"}]) @index(name: "senderOwnerIndex", queryField: "getApprovalBysenderOwner")
recipientOwner: String @auth(rules: [{ allow: owner, operations: [read], ownerField: "senderOwner"},{ allow: owner, operations: [read], ownerField: "recipientOwner"}]) @index(name: "recipientOwnerIndex", queryField: "getApprovalByrecipientOwner")
documentId: String @auth(rules: [{ allow: owner, operations: [create,read], ownerField: "senderOwner"},{ allow: owner, operations: [read], ownerField: "recipientOwner"}]) @index(name: "documentIdIndex", queryField: "getApprovalByDocumentId")
senderStatus: String @auth(rules: [{ allow: owner, operations: [read,update], ownerField: "senderOwner"},{ allow: owner, operations: [read], ownerField: "recipientOwner"}])
recipientStatus: String @auth(rules: [{ allow: owner, operations: [read], ownerField: "senderOwner"},{ allow: owner, operations: [read,update], ownerField: "recipientOwner"}])
}
type Document @model(subscriptions: null) @auth(rules: [{ allow: private, operations: [read] }]) {
id: ID!
name: String!
status: DocumentStatus!
}
enum DocumentStatus {
new
approved
rejected
}
The system works as expected but I'm a little worried because "multiple owners per field" seems a not documented feature. Can I rely on that?