Skip to main content
Version: 1.0 RC1 (Latest)

Restrict documents access

Document Access Control describes who should be allowed to do what on the documents in a collection. At a high level, these are the steps to set it up:

When access control is configured, each actor should authenticate with their private key. An actor that creates a document in a permissioned collection owns the document. Authenticated requests can see public documents and the private documents they have permission to; unauthenticated requests can access only public documents.

Create policies

A policy is the set of rules to enforce on the documents it will be applied to.

Example – policy.yml
name: A basic policy
description: Thou shall read but not pass
resources:
- name: books
relations:
- name: reader
- name: updater
- name: deleter
permissions:
- name: read
expr: reader
- name: update
expr: updater + deleter
- name: delete
expr: deleter
  • name – Policy name.
  • description (optional) – Policy description.
  • resources – List of permissions definitions.
    • name – Permission object name (refer to this when creating a permissioned collection).
    • relations – List of relations that actors may be given to act on documents (similar to user roles).
      • name – Relation name.
    • permissions – List specifying which relation will get which permission.
      • name – Permission name (read, update, delete).
      • expr (optional) – Expression involving relations names. Actors who fulfill the expression get the permission. Supported operators are union + and subtraction -.
Constraints for a policy to be valid
  • The permissions list must include all of read, update, delete, even if expr is not specified. You can include more permissions: DefraDB will ignore them, but other applications may use them.
note
  • The document creator gets all permissions, even if you omit a permission expression. For example, this policy grants read permission to reader actors and write permissions only to the document creator:
    - name: read
    expr: reader
    - name: update
    - name: delete
  • Relations allowed to update or delete automatically get permission to read. Subtract those relations if you don't want that:
    name: read
    expr: reader - updater - deleter

Relation managers

The owner of a document has always the privilege to grant permissions to other actors. The relation type manages gives other actors the permission to grant permissions (i.e. create relations) of the specified type. They become managers of the relations given in the manages list.

Relation "admin" has privilege to grant the "reader" relation
relations:
- name: reader
- name: admin
manages:
- reader

Register policies

A policy doesn't do anything until it's added into DefraDB. The request to register a policy must be authenticated. The returned PolicyID allows you to attach the policy to a collection.

Register a policy via the CLI command defradb client acp document policy add. The example sources the policy from file, but argument string and stdin are supported too.

defradb client acp document policy add -f policy.yml \
--identity b17a7b973f629b900cf23654db9c4be935f90281707dd3e2cd7a56bdd2c1bf4f
Result
{
"PolicyID": "9528839e7dac8d2c236ced23d49dcfb1cc1ece86a1329c7c512755ba1f56ca37"
}

Create permissioned collections

For a policy to apply to some documents, the policy needs to be registered with the collection holding such documents. Use the @policy directive to attach a policy to a collection, providing the policy ID and the name of the resource to attach. The result (and further calls to defradb client collection describe) shows the details under the Policy key.

type Book @policy(
id: "9528839e7dac8d2c236ced23d49dcfb1cc1ece86a1329c7c512755ba1f56ca37",
resource: "books"
) {
title: String
}
Result
[
{
"Name": "Book",
"VersionID": "bafyreihfhq442e6dand4n35dkwmaiwsmoiqytp2prz7eqzrikpgupwpj5u",
"CollectionID": "bafyreihfhq442e6dand4n35dkwmaiwsmoiqytp2prz7eqzrikpgupwpj5u",
"CollectionSet": null,
"Query": null,
"PreviousVersion": null,
"Fields": [
{
"FieldID": "bafyreihqzhiz3iwro4jozp6kphq4sosg6ccoqcbiaf7rg5dmvea7aux55a",
"Name": "_docID",
"Kind": 1,
"Typ": 0,
"RelationName": null,
"IsPrimary": false,
"DefaultValue": null,
"Size": 0
},
{
"FieldID": "bafyreihfb2izf5akjuua5jkijrgsgievsspboopupjq2its25owgle5pzm",
"Name": "title",
"Kind": 11,
"Typ": 1,
"RelationName": null,
"IsPrimary": false,
"DefaultValue": null,
"Size": 0
}
],
"Indexes": [],
"EncryptedIndexes": [],
"Policy": {
"ID": "9528839e7dac8d2c236ced23d49dcfb1cc1ece86a1329c7c512755ba1f56ca37",
"ResourceName": "book"
},
"IsActive": true,
"IsMaterialized": true,
"IsBranchable": false,
"IsEmbeddedOnly": false,
"IsPlaceholder": false,
"VectorEmbeddings": []
}
]

Private and public documents

Permissioned collections can contain both private and public documents. Documents created without an identity are visible to all actors; documents created with an identity are subject to the permission rules of the policy attached to the collection. For information on how to authenticate with an identity, see Authentication.

Create a public document
defradb client query '
mutation {
add_Book(input: {
title: "1984",
}) {
_docID
title
}
}
Create a private document
defradb client query --identity b17a7b973f629b900cf23654db9c4be935f90281707dd3e2cd7a56bdd2c1bf4f '
mutation {
add_Book(input: {
title: "Animal Farm",
}) {
_docID
title
}
}
The public (or any unauthorized identity) can't see private documents
defradb client query '
{
Book {
_docID
title
}
}
'
Result
{
"data": {
"Book": [
{
"_docID": "bae-72bb6e1c-479f-584c-8f63-2756c3bd63ca",
"title": "1984"
}
]
}
}
Private documents and P2P

Private documents get synced to other nodes only if their identities have the appropriate permissions in the node serving the documents. However, local policies don't get synced together with the private documents they are attached to. For more information, see P2P and private documents.

Grant permissions to other actors

To give another actor permission to access or alter a document, create a relation between the actor and the document ID. The relation defines what type of permission (according to the collection's policy) the actor will get. You can think that the relation assigns the identity a role (ex. reader) with respect to a specific document. Target actors are identified by their DID key.

The only actors allowed to grant permissions to others are the policy creator and the identities with the appropriate manage relation. The request to create a relation must be authenticated.

important

You can only create relations to private documents (i.e. documents created with an identity). Public documents are not registered in the DAC system and cannot be permissioned.

Give an actor permissions to a given document via the CLI command defradb client acp document relationship add

defradb client acp document relationship add \
--collection Book \
--docID bae-04ba3b88-1ac9-54f0-89b5-6abedff7201f \
--relation reader \
--actor did:key:z7r8osuVyok8SVnHH5tsyNDRGyniu9pQoqBt7misXTEJAon5vYCt72NmFpya4NUiLjPfyDvvayNMbYRrnqLMYjpD1cAgp \
--identity b17a7b973f629b900cf23654db9c4be935f90281707dd3e2cd7a56bdd2c1bf4f
Result
{
"ExistedAlready": false
}
note

Adding an already-existing relation doesn't result in an error: the return value ExistedAlready shows whether the relation is new or was already in place.

Grant permissions to everybody

To grant a specific permission to any actor, use the wildcard "*" as value for the actor's identity.

defradb client acp document relationship add \
--collection Book \
--docID bae-04ba3b88-1ac9-54f0-89b5-6abedff7201f \
--relation reader \
--actor "*" \
--identity b17a7b973f629b900cf23654db9c4be935f90281707dd3e2cd7a56bdd2c1bf4f

Revoke permissions

To revoke an actor's document permissions, delete their relation with the given document ID. Revoking relations granted to any actor with "*" only revokes that individual relation: it doesn't revoke all relations registered for any actor.

The only actors allowed to revoke permissions are the policy creator and the identities with the appropriate manage relation. The request to delete a relation must be authenticated.

Revoke an actor's permissions to a given document via the CLI command defradb client acp document relationship delete

defradb client acp document relationship delete \
--collection Book \
--docID bae-04ba3b88-1ac9-54f0-89b5-6abedff7201f \
--relation reader \
--actor did:key:z7r8osuVyok8SVnHH5tsyNDRGyniu9pQoqBt7misXTEJAon5vYCt72NmFpya4NUiLjPfyDvvayNMbYRrnqLMYjpD1cAgp \
--identity b17a7b973f629b900cf23654db9c4be935f90281707dd3e2cd7a56bdd2c1bf4f
Result
{
"RecordFound": true
}
note

Deleting a non-existing relation doesn't result in an error: the return value RecordFound shows whether the relation existed or not prior to deletion.