Write Authorization Data
In Permify, attributes and relations between your entities, objects and users represents your authorization data. These data stored as tuples in a preferred database.
Since these attributes and relations are live instances, meaning they can be affected by specific user actions within the application, they can be created/deleted with a simple Permify API call at runtime.
More specifically, the application client should update preferred database about the changes happening in entities or resources that are related to the authorization structure.
If we consider a document system; when some user joins a group that has edit access on some documents, the application side needs to write tuples to keep preferred database up-to-date. Besides, each attribute or relationship should be created according to its authorization model, Permify Schema.
Another example: when one a company executive grant admin role to user (lets say with id = 3) on their organization, application side needs to tell that update to Permify in order to reform that as tuples and store in preferred database.
You can use the /v1/tenants/{tenant_id}/data/write
endpoint for both creating relation tuples and for creating attribute data.
Path:
Content
- Example Relationship Creation
- Example Attributes Creation
- Creating Attributes and Relationship In Single Request
- Suggested Workflow
- Parameters & Properties
Example Relationship Creation
Let’s create an example relation tuple. If user:3 has been granted an admin role in organization:1, relational tuple organization:1#admin@user:3
should be created as follows:
Example Attribute Creation
You can use attributes
argument to create attribute/attributes with a single API call, similarly creating a relational tuple
.
Let’s say document:1 is a private (boolean) document, that only specific users have view access - document:1$is_private|boolean:true
.
As you noticed, the attribute tuple syntax differs from the relationship syntax, structured similarly as:
entity $ attribute | value
value field is mandatory on attribute data creation!
Here are the available attribute value types:
- type.googleapis.com/base.v1.StringValue
- type.googleapis.com/base.v1.BooleanValue
- type.googleapis.com/base.v1.IntegerValue
- type.googleapis.com/base.v1.DoubleValue
- type.googleapis.com/base.v1.StringArrayValue
- type.googleapis.com/base.v1.BooleanArrayValue
- type.googleapis.com/base.v1.IntegerArrayValue
- type.googleapis.com/base.v1.DoubleArrayValue
Creating Attributes and Relationship In Single Request
Assume we want to both create relational tuple and attribute within in single request. Specifically we want to create following tuples,
document:1#editor@user:1
document:1$is_private|boolean:true
Suggested Workflow
The most of the data that should written in Permify also needs to be write or engage with applications database as well. So where and how to write relationships into both applications database and Permify ?
Two Phase Commit Approach
In a standard relational based databases, the suggested place to write relationships to Permify is sending the write request in database transaction of the client action: such as storing the owner of the document when an user creates a document.
To give more concurrent example of this action, let’s take a look at below createDocument function
The key point to take way from above approach is if the transaction fails for any reason, the relation will also be deleted from Permify to provide maximum consistency.
Data That Not Stored In Application Database
Although ownership generally stored in application databases, there are some data that not needed to be stored in your actual database. Such as defining organizational roles, group members, project editors etc.
For example, you can model a simple project management authorization in Permify as follows,
This team member relation won’t need to be stored in the application database. Storing it only in Permify - preferred database - is enough. In that situation, WriteData
can be performed in any logical place in your stack.
Parameters & Properties
Path Parameters
Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant <code>t1</code> for this field. Required, and must match the pattern \“[a-zA-Z0-9-,]+\“, max 64 bytes.
Body
DataWriteRequest defines the structure of a request for writing data. It contains the necessary information such as tenant_id, metadata, tuples and attributes for the write operation.
DataWriteRequestMetadata defines the structure of metadata for a write request. It includes the schema version of the data to be written.
tuples contains the list of tuples (entity-relation-entity triples) that need to be written.
attributes contains the list of attributes (entity-attribute-value triples) that need to be written.
Response
DataWriteResponse defines the structure of the response after writing data. It contains the snap_token generated after the write operation.
The snap token to avoid stale cache, see more details on Snap Tokens.