Privilege relationship between indexes and collections

Hi all! Loving Fauna so far and am prototyping a few ideas just to make sure I know how everything is working.

I’m attempting to set up some more advanced ABAC roles and am running into an issue with inflated read ops on querying indexes. Anyway, I’m working with the below schema:

type User {
  name: String
  email: String!

  organizations: [OrganizationMember!] @relation
}

enum OrganizationMemberRole {
  OWNER
  MEMBER
  GUEST
}

type OrganizationMember {
  user: User!
  organization: Organization!
  role: OrganizationMemberRole!
}

type Organization {
  name: String!
  description: String

  items: [Item!] @relation
  members: [OrganizationMember!]! @relation
}

type Item {
  name: String!
  isPublic: Boolean

  createdBy: User!
  origin: Organization!
}

I set up an index to make checking the user to organization relationship easier:

{
  name: "organization_membership",
  unique: true,
  serialized: true,
  source: "OrganizationMember",
  terms: [
    {
      field: ["data", "user"]
    },
    {
      field: ["data", "organization"]
    }
  ],
  values: [
    {
      field: ["data", "role"]
    }
  ]
}

Setting up read privileges on the Item collection as follows, I would expect inflated read ops from the default index (that uses no terms)… after all, we have to select data from each ref.

Lambda(
  "itemRef",
  Exists(
    Match(Index("organization_membership"), [
      Identity(),
      Select(["data", "origin"], Get(Var("itemRef")))
    ])
  )
)

So, the natural solution would be to create an index in order to reduce our read ops. That index looks something like this (note, I’ve also added specific values and had the same result):

{
  name: "items_for_organization",
  unique: false,
  serialized: true,
  source: "Item",
  terms: [
    {
      field: ["data", "origin"]
    }
  ]
}

Based on my understanding, reading from this index (using the below query) would only use read ops as they relate to the index itself since we’re never retrieving any data from the Item refs, just the data stored in the index.

Paginate(
  Match(
    Index("items_for_organization"),
    Ref(Collection("Organization"), "_id")
  )
)

However, the ABAC rules for the Item collection are also triggering when the index is read. Furthermore, if I revoke read access for the Item collection, no results are returned at all when reading the index.

Isn’t the data stored directly on the index in this case? I know a user would need write access to the collection in order to update the index, but I’m unsure on why read access is required.

It’s probably something obvious I’m missing, but I’d love to understand this more fully. Thanks for your help!

1 Like