1

The object that will be changed by a mutation contains a permissions array that contains user objects that consist of a userId and a write permission boolean. If a user's userId is present in the list, the user has read permission on the object. If write is set to true, the user also has write permission.

This makes modifying the object easier from a mutation perspective, but it makes handling subscriptions much more difficult, since I don't have access to the object being updated at subscription creation. Thus, I am unable to ensure that user's will only get updates to the object if they have the appropriate permissions.

I don't think it makes a difference (since I can't handle this on the client-side securely), but I'm building a React web client.

Is there any feasible way around this?

foxtrotuniform6969
  • 3,527
  • 7
  • 28
  • 54

1 Answers1

2

One possible solution would be to setup a server-side job which subscribes to all new mutations. This server-side listener would receive every new mutation, look into the permissions list, and publish to the authorized user using a None datasource resolver. The users will only be allowed to subscribe to a subscription with their user id.

The schema would look something like this:

type Object {
  permissions: [User]
  //.. Other fields
}

type User {
  userId: ID!
  write: Boolean
}

// The server listener will populate this
type PublishPayload {
  userId: ID!
  objectToPublish: Object
}

type Mutation {
  // The original mutation
  updateObject(): Object

  // The server-side listener will use this to publish. Attach a None Resolver to it.
  publishToUser(userId: ID!): PublishPayload
}

type Subscription {
  // This subscription is used by the server to listen to all updateObject mutations
  serverSubscription(): Object
  @aws_subscribe(mutations:["updateObject"])

  // This subscription is used by the users. 
  // You would add a resolver to it that fails authorization if they try to subscribe to a different user.
  userSubscription(userId: ID!): PublishPayload
  @aws_subscribe(mutations:["publishToUser"])

//.. More schema

Hope this helps!

  • 1
    That's an excellent idea. I will give it a try tonight and let you know how it goes. I can't help but feel that, in general, I'm applying a lot of "workarounds" in order to use AppSync as a SaaS provider, but I suppose for the price point there's no beating it. I just hope that it proves to be maintainable going forward. – foxtrotuniform6969 Oct 23 '18 at 14:25
  • Wouldn't the server-side listener in this case need to be an EC2 instance or container, since Lambda is short-lived? – foxtrotuniform6969 Nov 10 '18 at 16:53