diff --git a/docs/docs/api-overview/data/delete-data.md b/docs/docs/api-overview/data/delete-data.md index c967a06b4..fe8ba7d4d 100644 --- a/docs/docs/api-overview/data/delete-data.md +++ b/docs/docs/api-overview/data/delete-data.md @@ -9,12 +9,17 @@ You can delete any stored relation tuples or attributes with following API **Path:** POST /v1/tenants/{tenant_id}/data/delete -| Required | Argument | Type | Default | Description | +[![View in Swagger](http://jessemillar.github.io/view-in-swagger-button/button.svg)](https://permify.github.io/permify-swagger/#/Data/data.delete) + +| Required | Argument | Type | Description | |----------|----------|---------|---------|-------------------------------------------------------------------------------------------| -| [x] | tenant_id | string | - | identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant `t1` for this field. -| [x] | entity | object | - | contains entity type and id of the entity. Example: repository:1”. -| [x] | relation | string | - | relation of the given entity | -| [ ] | subject | object | - | the user or user set. It contains type and id of the subject. || +| [x] | tenant_id | string | identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant `t1` for this field. +| [x] | tuples_filter | object |filter to delete relational tuples. Contains **entity**, **relation** and **subject**. +| [x] | attribute_filter | object | filter to delete attributes. Contains **entity** and **attributes**. +| [x] | entity | object | contains entity type and id of the entity. Example: repository:1”. +| [x] | relation | string | relation of the given entity | +| [x] | attribute | string array | attributes to be deleted | +| [ ] | subject | object | the user or user set. It contains type and id of the subject. || diff --git a/docs/docs/api-overview/data/read-attributes.md b/docs/docs/api-overview/data/read-attributes.md new file mode 100644 index 000000000..517089690 --- /dev/null +++ b/docs/docs/api-overview/data/read-attributes.md @@ -0,0 +1,105 @@ +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Read Attributes + +Read API allows for directly querying the stored graph data to display and filter stored attributes. + +## Request + +**Path:** POST /v1/tenants/{tenant_id}/data/attributes/read + +[![View in Swagger](http://jessemillar.github.io/view-in-swagger-button/button.svg)](https://permify.github.io/permify-swagger/#/Data/data.attributes.read) + +| Required | Argument | Type | Description | +|----------|----------|---------|---------|-------------------------------------------------------------------------------------------| +| [x] | tenant_id | string | identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant `t1` for this field. +| [ ] | snap_token | string | the snap token to avoid stale cache, see more details on [Snap Tokens](../../reference/snap-tokens) | +| [x] | entity | object | contains entity type and id of the entity. Example: repository:1”. +| [x] | attributes | string array | attributes of the given entity | + + + + + +```go +rr, err: = client.Data.Relationship.Read(context.Background(), & v1.Data.RelationshipReadRequest { + TenantId: "t1", + Metadata: &v1.Data.RelationshipReadRequestMetadata { + SnapToken: "" + }, + Filter: &v1.TupleFilter { + Entity: &v1.EntityFilter { + Type: "organization", + Ids: []string {"1"} , + }, + Relation: "member", + Subject: &v1.SubjectFilter { + Type: "", + Id: []string {""}, + Relation: "" + }} +}) +``` + + + + + +```javascript +client.data.relationship.read({ + tenantId: "t1", + metadata: { + snap_token: "", + }, + filter: { + entity: { + type: "organization", + ids: [ + "1" + ] + }, + relation: "member", + subject: { + type: "", + ids: [], + relation: "" + } + } +}).then((response) => { + // handle response +}) +``` + + + + +```curl +curl --location --request POST 'localhost:3476/v1/tenants/{tenant_id}/data/relationships/read' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + metadata: { + snap_token: "", + }, + filter: { + entity: { + type: "organization", + ids: [ + "1" + ] + }, + relation: "member", + subject: { + type: "", + ids: [], + relation: "" + } + } +}' +``` + + + +## Need any help ? + +Our team is happy to help you get started with Permify. If you'd like to learn more about using Permify in your app or have any questions about this example, [schedule a call with one of our Permify engineer](https://meetings-eu1.hubspot.com/ege-aytin/call-with-an-expert). diff --git a/docs/docs/api-overview/data/read-relationships.md b/docs/docs/api-overview/data/read-relationships.md index 0b822f70b..9d9d8f6bd 100644 --- a/docs/docs/api-overview/data/read-relationships.md +++ b/docs/docs/api-overview/data/read-relationships.md @@ -9,6 +9,8 @@ Read API allows for directly querying the stored graph data to display and filte **Path:** POST /v1/tenants/{tenant_id/data/relationships/read +[![View in Swagger](http://jessemillar.github.io/view-in-swagger-button/button.svg)](https://permify.github.io/permify-swagger/#/Data/data.relationships.read) + | Required | Argument | Type | Default | Description | |----------|----------|---------|---------|-------------------------------------------------------------------------------------------| | [x] | tenant_id | string | - | identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant `t1` for this field. diff --git a/docs/docs/api-overview/data/write-data.md b/docs/docs/api-overview/data/write-data.md index bf53daeeb..9b50fa2ae 100644 --- a/docs/docs/api-overview/data/write-data.md +++ b/docs/docs/api-overview/data/write-data.md @@ -1,9 +1,9 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -# Write Data +# Write Authorization Data -In Permify, relations between your entities, objects and users stored as [relational tuples] in a [preferred database]. Since relations and authorization data's are live instances these relational tuples can be created with an simple API call in runtime. +In Permify, relations between your entities, objects and users stored as [relational tuples] in a [preferred database]. Since relations and authorization data's are live instances these relational tuples can be created with an simple API call in runtime. When using Permify, 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 relational tuples to keep [preferred database] up-to-date. Besides, each relational tuple should be created according to its authorization model, Permify Schema. @@ -14,21 +14,34 @@ Another example: when one a company executive grant admin role to user (lets say [relational tuples]: ../../getting-started/sync-data [preferred database]: ../../getting-started/sync-data#where-relational-tuples-used -## Request +## Write Request -So if user:3 has been granted an admin role in organization:1, relational tuple `organization:1#admin@user:3` must be created by using **/v1/data/write** endpoint. +:::info +You can use the **/v1/tenants/{tenant_id}/data/write** endpoint for both creating **relation tuples** and for creating **attribute data**. +::: **Path:** POST /v1/tenants/{tenant_id}/data/write -| Required | Argument | Type | Default | Description | -|----------|-------------------|--------|---------|-------------| -| [x] | tenant_id | string | - | identifier of the tenant, if you are not using multi-tenancy (have only one tenant in your system) use pre-inserted tenant **t1** for this field. -| [x] | tuples | array | - | Can contain multiple relation tuple object| -| [x] | entity | object | - | Type and id of the entity. Example: "organization:1”| -| [x] | relation | string | - | Custom relation name. Eg. admin, manager, viewer etc.| -| [x] | subject | string | - | User or user set who wants to take the action. | -| [ ] | schema_version | string | 8 | Version of the schema | +[![View in Swagger](http://jessemillar.github.io/view-in-swagger-button/button.svg)](https://permify.github.io/permify-swagger/#/Data/data.write) +#### Glossary for parameters & payload objects: + +| Required | Argument | Type | Default | Description | +| -------- | -------------- | ------ | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| [x] | tenant_id | string | - | identifier of the tenant, if you are not using multi-tenancy (have only one tenant in your system) use pre-inserted tenant **t1** for this parameter. | +| [ ] | schema_version | string | 8 | Version of the schema. | +| [x] | tuples | array | - | Array of objects that are used to define relationships. Each object contains **entity**, **relation**, and **subject** arguments.| +| [x] | attributes | array | - | Array of objects that are used to define relationships. Each object contains **entity**, **attribute**, and **value** arguments. | +| [x] | entity | object | - | Type and id of the entity. Example: "organization:1” | +| [x] | subject | string | - | User or user set who wants to take the action. | +| [x] | relation | string | - | Custom relation name. Eg. admin, manager, viewer etc. | +| [x] | attribute | string | - | Custom attribute name. | +| [x] | value | object | - | Represents value and type of the attribute data. | + + +### Creating Relational Tuple + +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: @@ -60,25 +73,29 @@ rr, err: = client.Data.Write(context.Background(), & v1.DataWriteRequest { ```javascript -client.data.write({ +client.data + .write({ tenantId: "t1", metadata: { - schemaVersion: "" + schemaVersion: "", }, - tuples: [{ + tuples: [ + { entity: { - type: "organization", - id: "1" + type: "organization", + id: "1", }, relation: "admin", subject: { - type: "user", - id: "3" - } - }] -}).then((response) => { + type: "user", + id: "3", + }, + }, + ], + }) + .then((response) => { // handle response -}) + }); ``` @@ -107,6 +124,87 @@ curl --location --request POST 'localhost:3476/v1/tenants/{tenant_id}/data/write ] }' ``` + + + + +### Creating Attribute Data + +You can use `attributes` argument to create attribute/attributes, similarly the `tuples`. + +Let's conitnue with an example: Assume user:1 has been granted an admin role in organization:1 and organization:1 is a private (boolean) organization: + +:::warning **value** field +**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** +::: + + + + +```go + +``` + + + + + +```javascript + +``` + + + + +```curl +curl --location --request POST 'localhost:3476/v1/tenants/{tenant_id}/data/write' \ +--header 'Content-Type: application/json' \ +--data-raw '{ +{ + "metadata": { + "schema_version": "" + }, + "tuples": [ + { + "entity": { + "type": "organization", + "id": "1" + }, + "relation": "admin", + "subject": { + "type": "user", + "id": "1" + } + } + ], + "attributes": [ + { + "entity": { + "type": "organization", + "id": "1" + }, + "attribute": "private", + "value": { + "@type": "type.googleapis.com/base.v1.BooleanValue", + "value": "true" + } + } + ] +} +}' +``` + @@ -114,7 +212,7 @@ curl --location --request POST 'localhost:3476/v1/tenants/{tenant_id}/data/write ```json { - "snap_token": "FxHhb4CrLBc=" + "snap_token": "FxHhb4CrLBc=" } ``` @@ -122,14 +220,15 @@ You can store that snap token alongside with the resource in your relational dat See more details on what is [Snap Tokens](../../reference/snap-tokens) and how its avoiding stale cache. -## Suggested Workflow +## 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 +To give more concurrent example of this action, let's take a look at below createDocument function ```go func CreateDocuments(db *gorm.DB) error { @@ -138,7 +237,7 @@ func CreateDocuments(db *gorm.DB) error { defer func() { if r := recover(); r != nil { tx.Rollback() - // if transaction fails, then delete malformed relation tuple + // if transaction fails, then delete malformed relation tuple permify.DeleteData(...) } }() @@ -149,24 +248,25 @@ func CreateDocuments(db *gorm.DB) error { if err := tx.Create(docs).Error; err != nil { tx.Rollback() - // if transaction fails, then delete malformed relation tuple + // if transaction fails, then delete malformed relation tuple permify.DeleteData(...) return err } - // if transaction successful, write relation tuple to Permify + // if transaction successful, write relation tuple to Permify permify.WriteData(...) return tx.Commit().Error } ``` + 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, +For example, you can model a simple project management authorization in Permify as follows, ```perm entity user {} @@ -193,4 +293,4 @@ This **team member** relation won't need to be stored in the application databas ## Need any help ? -Our team is happy to help you get started with Permify. If you'd like to learn more about using Permify in your app or have any questions about this example, [schedule a call with one of our Permify engineer](https://meetings-eu1.hubspot.com/ege-aytin/call-with-an-expert). \ No newline at end of file +Our team is happy to help you get started with Permify. If you'd like to learn more about using Permify in your app or have any questions about this example, [schedule a call with one of our Permify engineer](https://meetings-eu1.hubspot.com/ege-aytin/call-with-an-expert). diff --git a/docs/docs/api-overview/permission/check-api.md b/docs/docs/api-overview/permission/check-api.md index c90230276..8f8cbbf06 100644 --- a/docs/docs/api-overview/permission/check-api.md +++ b/docs/docs/api-overview/permission/check-api.md @@ -16,6 +16,8 @@ In this section we'll look at the resource based check request of Permify. You c **Path:** POST /v1/permissions/check +[![View in Swagger](http://jessemillar.github.io/view-in-swagger-button/button.svg)](https://permify.github.io/permify-swagger/#/Permission/permissions.check) + | Required | Argument | Type | Default | Description | |----------|-------------------|---------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | [x] | tenant_id | string | - | identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant `t1` for this field. | diff --git a/docs/docs/api-overview/permission/expand-api.md b/docs/docs/api-overview/permission/expand-api.md index 1a26387e8..ea91bb1f5 100644 --- a/docs/docs/api-overview/permission/expand-api.md +++ b/docs/docs/api-overview/permission/expand-api.md @@ -13,6 +13,8 @@ Expand is designed for reasoning the complete set of users that have access to t It is not designed to use as a check access. Expand request has a high latency which can cause a performance issues when its used as access check. ::: +[![View in Swagger](http://jessemillar.github.io/view-in-swagger-button/button.svg)](https://permify.github.io/permify-swagger/#/Permission/permissions.expand) + diff --git a/docs/docs/api-overview/permission/lookup-entity.md b/docs/docs/api-overview/permission/lookup-entity.md index 85425b6a2..687963951 100644 --- a/docs/docs/api-overview/permission/lookup-entity.md +++ b/docs/docs/api-overview/permission/lookup-entity.md @@ -20,6 +20,8 @@ In this endpoint you'll get directly the IDs' of the entities that are authorize **POST** /v1/permissions/lookup-entity +[![View in Swagger](http://jessemillar.github.io/view-in-swagger-button/button.svg)](https://permify.github.io/permify-swagger/#/Permission/permissions.lookupEntity) + | Required | Argument | Type | Default | Description | |----------|-------------------|--------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | [x] | tenant_id | string | - | identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant `t1` for this field. | @@ -137,6 +139,8 @@ The difference between this endpoint from direct Lookup Entity is response of th **POST** /v1/permissions/lookup-entity-stream +[![View in Swagger](http://jessemillar.github.io/view-in-swagger-button/button.svg)](https://permify.github.io/permify-swagger/#/Permission/permissions.lookupEntityStream) + | Required | Argument | Type | Default | Description | |----------|-------------------|--------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | [ ] | schema_version | string | 8 | Version of the schema | diff --git a/docs/docs/api-overview/permission/lookup-subject.md b/docs/docs/api-overview/permission/lookup-subject.md index 63bc07150..baaacd6bd 100644 --- a/docs/docs/api-overview/permission/lookup-subject.md +++ b/docs/docs/api-overview/permission/lookup-subject.md @@ -19,6 +19,8 @@ In this endpoint you'll get directly the IDs' of the subjects that are authorize **POST** /v1/permissions/lookup-subject +[![View in Swagger](http://jessemillar.github.io/view-in-swagger-button/button.svg)](https://permify.github.io/permify-swagger/#/Permission/permissions.lookupSubject) + | Required | Argument | Type | Default | Description | |----------|---------------------|----------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | [x] | tenant_id | string | - | identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant `t1` for this field. | diff --git a/docs/docs/api-overview/permission/subject-permission.md b/docs/docs/api-overview/permission/subject-permission.md index 4911b14e9..9048b33ca 100644 --- a/docs/docs/api-overview/permission/subject-permission.md +++ b/docs/docs/api-overview/permission/subject-permission.md @@ -19,6 +19,8 @@ In this endpoint, you'll receive a map of permissions and their statuses directl **Path:** POST /v1/permissions/subject-permission +[![View in Swagger](http://jessemillar.github.io/view-in-swagger-button/button.svg)](https://permify.github.io/permify-swagger/#/Permission/permissions.subjectPermission) + | Required | Argument | Type | Default | Description | |----------|-------------------|---------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | [x] | tenant_id | string | - | identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant `t1` for this field. | diff --git a/docs/docs/api-overview/schema/write-schema.md b/docs/docs/api-overview/schema/write-schema.md index 3cf22fcbc..05620bece 100644 --- a/docs/docs/api-overview/schema/write-schema.md +++ b/docs/docs/api-overview/schema/write-schema.md @@ -21,6 +21,8 @@ Permify Schema needed to be send to API endpoint **/v1/schemas/write"** for conf **POST** /v1/tenants/{tenant_id}/schemas/write +[![View in Swagger](http://jessemillar.github.io/view-in-swagger-button/button.svg)](https://permify.github.io/permify-swagger/#/Schema/schemas.write) + | Required | Argument | Type | Default | Description | |----------|-------------------|--------|---------|-------------| | [x] | tenant_id | string | - | identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant `t1` for this field. diff --git a/docs/docs/api-overview/tenancy/create-tenant.md b/docs/docs/api-overview/tenancy/create-tenant.md index 412ddaec4..69a7a6ff7 100644 --- a/docs/docs/api-overview/tenancy/create-tenant.md +++ b/docs/docs/api-overview/tenancy/create-tenant.md @@ -13,6 +13,8 @@ We have a pre-inserted tenant - **t1** - by default for the ones that don't use **POST /v1/tenants/create** +[![View in Swagger](http://jessemillar.github.io/view-in-swagger-button/button.svg)](https://permify.github.io/permify-swagger/#/Tenancy/tenants.create) + diff --git a/docs/docs/api-overview/tenancy/delete-tenant.md b/docs/docs/api-overview/tenancy/delete-tenant.md index d8bd4a431..a74a11e8b 100644 --- a/docs/docs/api-overview/tenancy/delete-tenant.md +++ b/docs/docs/api-overview/tenancy/delete-tenant.md @@ -9,6 +9,8 @@ You can delete a tenant with following API. **DELETE /v1/tenants/{id}** +[![View in Swagger](http://jessemillar.github.io/view-in-swagger-button/button.svg)](https://permify.github.io/permify-swagger/#/Tenancy/tenants.delete) + diff --git a/docs/docs/api-overview/watch/watch-changes.md b/docs/docs/api-overview/watch/watch-changes.md index 921fac97e..ff48c0979 100644 --- a/docs/docs/api-overview/watch/watch-changes.md +++ b/docs/docs/api-overview/watch/watch-changes.md @@ -72,6 +72,8 @@ service: **Path:** POST /v1/watch/watch +[![View in Swagger](http://jessemillar.github.io/view-in-swagger-button/button.svg)](https://permify.github.io/permify-swagger/#/Watch/watch.watch) + | Required | Argument | Type | Default | Description | |----------|------------|--------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | [x] | tenant_id | string | - | identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant `t1` for this field. |