snapshot of https://github.com/ory/keto.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
CI / Run lints and checks (push) Failing after 47s
CI / Run tests (push) Failing after 1s
CI / Run race tests (push) Failing after 5s
CI / Build CLI docs (push) Has been skipped
CI / Run buf actions (push) Failing after 5s
CodeQL / Analyze (go) (push) Failing after 3s
CodeQL / Analyze (javascript) (push) Failing after 2s
Docker Image Scanners / scanners (push) Failing after 3s
Format / format (push) Failing after 3s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Draft newsletter (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
Some checks failed
CI / Run lints and checks (push) Failing after 47s
CI / Run tests (push) Failing after 1s
CI / Run race tests (push) Failing after 5s
CI / Build CLI docs (push) Has been skipped
CI / Run buf actions (push) Failing after 5s
CodeQL / Analyze (go) (push) Failing after 3s
CodeQL / Analyze (javascript) (push) Failing after 2s
Docker Image Scanners / scanners (push) Failing after 3s
Format / format (push) Failing after 3s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Draft newsletter (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
This commit is contained in:
301
docs/.generated/proto-api.mdx
Normal file
301
docs/.generated/proto-api.mdx
Normal file
@@ -0,0 +1,301 @@
|
||||
---
|
||||
title: Protocol Buffers API
|
||||
---
|
||||
|
||||
<!-- This file is generated. Please edit the .proto files instead to update the documentation -->
|
||||
|
||||
The API is divided into the
|
||||
[read APIs](../concepts/25_api-overview.mdx#read-apis) and
|
||||
[write APIs](../concepts/25_api-overview.mdx#write-apis). Each service is
|
||||
annotated with the API it belongs to.
|
||||
|
||||
## ory/keto/acl/v1alpha1/acl.proto
|
||||
|
||||
### RelationTuple
|
||||
|
||||
RelationTuple defines a relation between an Object and a Subject.
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| --------- | ----------------------------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| namespace | [string](#string) | | The namespace this relation tuple lives in. |
|
||||
| object | [string](#string) | | The object related by this tuple. It is an object in the namespace of the tuple. |
|
||||
| relation | [string](#string) | | The relation between an Object and a Subject. |
|
||||
| subject | [Subject](#ory.keto.acl.v1alpha1.Subject) | | The subject related by this tuple. A Subject either represents a concrete subject id or a `SubjectSet` that expands to more Subjects. |
|
||||
|
||||
### Subject
|
||||
|
||||
Subject is either a concrete subject id or a `SubjectSet` expanding to more
|
||||
Subjects.
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ----------------------------------------------- | ----- | -------------------------------------------------------------------------------------------------------------------------- |
|
||||
| id | [string](#string) | | A concrete id of the subject. |
|
||||
| set | [SubjectSet](#ory.keto.acl.v1alpha1.SubjectSet) | | A subject set that expands to more Subjects. More information are available under [concepts](../concepts/15_subjects.mdx). |
|
||||
|
||||
### SubjectSet
|
||||
|
||||
SubjectSet refers to all subjects who have the same `relation` on an `object`.
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| --------- | ----------------- | ----- | ------------------------------------------------------------------------ |
|
||||
| namespace | [string](#string) | | The namespace of the object and relation referenced in this subject set. |
|
||||
| object | [string](#string) | | The object related by this subject set. |
|
||||
| relation | [string](#string) | | The relation between the object and the subjects. |
|
||||
|
||||
## ory/keto/acl/v1alpha1/check_service.proto
|
||||
|
||||
### CheckService
|
||||
|
||||
The service that performs authorization checks based on the stored Access
|
||||
Control Lists.
|
||||
|
||||
This service is part of the
|
||||
[read-APIs](../concepts/25_api-overview.mdx#read-apis).
|
||||
|
||||
| Method Name | Request Type | Response Type | Description |
|
||||
| ----------- | --------------------------------------------------- | ----------------------------------------------------- | -------------------------------- |
|
||||
| Check | [CheckRequest](#ory.keto.acl.v1alpha1.CheckRequest) | [CheckResponse](#ory.keto.acl.v1alpha1.CheckResponse) | Performs an authorization check. |
|
||||
|
||||
### CheckRequest
|
||||
|
||||
The request for a CheckService.Check RPC. Checks whether a specific subject is
|
||||
related to an object.
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| --------- | ----------------------------------------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| namespace | [string](#string) | | The namespace to evaluate the check.<br/>Note: If you use the expand-API and the check evaluates a RelationTuple specifying a SubjectSet as subject or due to a rewrite rule in a namespace config this check request may involve other namespaces automatically. |
|
||||
| object | [string](#string) | | The related object in this check. |
|
||||
| relation | [string](#string) | | The relation between the Object and the Subject. |
|
||||
| subject | [Subject](#ory.keto.acl.v1alpha1.Subject) | | The related subject in this check. |
|
||||
| latest | [bool](#bool) | | This field is not implemented yet and has no effect. <!-- Set this field to `true` in case your application needs to authorize depending on up to date ACLs, also called a "content-change check".<br/>If set to `true` the `snaptoken` field is ignored, the check is evaluated at the latest snapshot (globally consistent) and the response includes a snaptoken for clients to store along with object contents that can be used for subsequent checks of the same content version.<br/>Example use case: - You need to authorize a user to modify/delete some resource and it is unacceptable that if the permission to do that had just been revoked some seconds ago so that the change had not yet been fully replicated to all availability zones. --> |
|
||||
| snaptoken | [string](#string) | | This field is not implemented yet and has no effect. <!-- Optional. Like reads, a check is always evaluated at a consistent snapshot no earlier than the given snaptoken.<br/>Leave this field blank if you want to evaluate the check based on eventually consistent ACLs, benefiting from very low latency, but possibly slightly stale results.<br/>If the specified token is too old and no longer known, the server falls back as if no snaptoken had been specified.<br/>If not specified the server tries to evaluate the check on the best snapshot version where it is very likely that ACLs had already been replicated to all availability zones. --> |
|
||||
| max_depth | [int32](#int32) | | The maximum depth to search for a relation.<br/>If the value is less than 1 or greater than the global max-depth then the global max-depth will be used instead. |
|
||||
|
||||
### CheckResponse
|
||||
|
||||
The response for a CheckService.Check rpc.
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| --------- | ----------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| allowed | [bool](#bool) | | Whether the specified subject (id) is related to the requested object.<br/>It is false by default if no ACL matches. |
|
||||
| snaptoken | [string](#string) | | This field is not implemented yet and has no effect. <!-- The last known snapshot token ONLY specified if the request had not specified a snaptoken, since this performed a "content-change request" and consistently fetched the last known snapshot token.<br/>This field is not set if the request had specified a snaptoken!<br/>If set, clients should cache and use this token for subsequent requests to have minimal latency, but allow slightly stale responses (only some milliseconds or seconds). --> |
|
||||
|
||||
## ory/keto/acl/v1alpha1/expand_service.proto
|
||||
|
||||
### ExpandService
|
||||
|
||||
The service that performs subject set expansion based on the stored Access
|
||||
Control Lists.
|
||||
|
||||
This service is part of the
|
||||
[read-APIs](../concepts/25_api-overview.mdx#read-apis).
|
||||
|
||||
| Method Name | Request Type | Response Type | Description |
|
||||
| ----------- | ----------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------ |
|
||||
| Expand | [ExpandRequest](#ory.keto.acl.v1alpha1.ExpandRequest) | [ExpandResponse](#ory.keto.acl.v1alpha1.ExpandResponse) | Expands the subject set into a tree of subjects. |
|
||||
|
||||
### ExpandRequest
|
||||
|
||||
The request for an ExpandService.Expand RPC. Expands the given subject set.
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| --------- | ----------------------------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| subject | [Subject](#ory.keto.acl.v1alpha1.Subject) | | The subject to expand. |
|
||||
| max_depth | [int32](#int32) | | The maximum depth of tree to build.<br/>If the value is less than 1 or greater than the global max-depth then the global max-depth will be used instead.<br/>It is important to set this parameter to a meaningful value. Ponder how deep you really want to display this. |
|
||||
| snaptoken | [string](#string) | | This field is not implemented yet and has no effect. <!-- Optional. Like reads, a expand is always evaluated at a consistent snapshot no earlier than the given snaptoken.<br/>Leave this field blank if you want to expand based on eventually consistent ACLs, benefiting from very low latency, but possibly slightly stale results.<br/>If the specified token is too old and no longer known, the server falls back as if no snaptoken had been specified.<br/>If not specified the server tries to build the tree on the best snapshot version where it is very likely that ACLs had already been replicated to all availability zones. --> |
|
||||
|
||||
### ExpandResponse
|
||||
|
||||
The response for a ExpandService.Expand RPC.
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ------------------------------------------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| tree | [SubjectTree](#ory.keto.acl.v1alpha1.SubjectTree) | | The tree the requested subject set expands to. The requested subject set is the subject of the root.<br/>This field can be nil in some circumstances. |
|
||||
|
||||
### SubjectTree
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| --------- | ------------------------------------------------- | -------- | ------------------------------------------------------------------------------------ |
|
||||
| node_type | [NodeType](#ory.keto.acl.v1alpha1.NodeType) | | The type of the node. |
|
||||
| subject | [Subject](#ory.keto.acl.v1alpha1.Subject) | | The subject this node represents. |
|
||||
| children | [SubjectTree](#ory.keto.acl.v1alpha1.SubjectTree) | repeated | The children of this node.<br/>This is never set if `node_type` == `NODE_TYPE_LEAF`. |
|
||||
|
||||
### NodeType
|
||||
|
||||
| Name | Number | Description |
|
||||
| ---------------------- | ------ | ---------------------------------------------------------------------------------------------------------- |
|
||||
| NODE_TYPE_UNSPECIFIED | 0 | |
|
||||
| NODE_TYPE_UNION | 1 | This node expands to a union of all children. |
|
||||
| NODE_TYPE_EXCLUSION | 2 | Not implemented yet. |
|
||||
| NODE_TYPE_INTERSECTION | 3 | Not implemented yet. |
|
||||
| NODE_TYPE_LEAF | 4 | This node is a leaf and contains no children. Its subject is a `SubjectID` unless `max_depth` was reached. |
|
||||
|
||||
## ory/keto/acl/v1alpha1/read_service.proto
|
||||
|
||||
### ReadService
|
||||
|
||||
The service to query relation tuples.
|
||||
|
||||
This service is part of the
|
||||
[read-APIs](../concepts/25_api-overview.mdx#read-apis).
|
||||
|
||||
| Method Name | Request Type | Response Type | Description |
|
||||
| ------------------ | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | -------------------------- |
|
||||
| ListRelationTuples | [ListRelationTuplesRequest](#ory.keto.acl.v1alpha1.ListRelationTuplesRequest) | [ListRelationTuplesResponse](#ory.keto.acl.v1alpha1.ListRelationTuplesResponse) | Lists ACL relation tuples. |
|
||||
|
||||
### ListRelationTuplesRequest
|
||||
|
||||
Request for ReadService.ListRelationTuples RPC. See
|
||||
`ListRelationTuplesRequest_Query` for how to filter the query.
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----------- | ----------------------------------------------------------------------------------------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| query | [ListRelationTuplesRequest.Query](#ory.keto.acl.v1alpha1.ListRelationTuplesRequest.Query) | | All query constraints are concatenated with a logical AND operator.<br/>The RelationTuple list from ListRelationTuplesResponse is ordered from the newest RelationTuple to the oldest. |
|
||||
| expand_mask | [google.protobuf.FieldMask](#google.protobuf.FieldMask) | | This field is not implemented yet and has no effect. <!-- Optional. The list of fields to be expanded in the RelationTuple list returned in `ListRelationTuplesResponse`. Leaving this field unspecified means all fields are expanded.<br/>Available fields: "object", "relation", "subject", "namespace", "subject.id", "subject.namespace", "subject.object", "subject.relation" --> |
|
||||
| snaptoken | [string](#string) | | This field is not implemented yet and has no effect. <!-- Optional. The snapshot token for this read. --> |
|
||||
| page_size | [int32](#int32) | | Optional. The maximum number of RelationTuples to return in the response.<br/>Default: 100 |
|
||||
| page_token | [string](#string) | | Optional. An opaque pagination token returned from a previous call to `ListRelationTuples` that indicates where the page should start at.<br/>An empty token denotes the first page. All successive pages require the token from the previous page. |
|
||||
|
||||
### ListRelationTuplesRequest.Query
|
||||
|
||||
The query for listing relation tuples. Clients can specify any optional field to
|
||||
partially filter for specific relation tuples.
|
||||
|
||||
Example use cases (namespace is always required):
|
||||
|
||||
- object only: display a list of all permissions referring to a specific object
|
||||
- relation only: get all groups that have members; get all directories that have
|
||||
content
|
||||
- object & relation: display all subjects that have a specific permission
|
||||
relation
|
||||
- subject & relation: display all groups a subject belongs to; display all
|
||||
objects a subject has access to
|
||||
- object & relation & subject: check whether the relation tuple already exists
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| --------- | ----------------------------------------- | ----- | ------------------------------------ |
|
||||
| namespace | [string](#string) | | Required. The namespace to query. |
|
||||
| object | [string](#string) | | Optional. The object to query for. |
|
||||
| relation | [string](#string) | | Optional. The relation to query for. |
|
||||
| subject | [Subject](#ory.keto.acl.v1alpha1.Subject) | | Optional. The subject to query for. |
|
||||
|
||||
### ListRelationTuplesResponse
|
||||
|
||||
The response of a ReadService.ListRelationTuples RPC.
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| --------------- | ----------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------ |
|
||||
| relation_tuples | [RelationTuple](#ory.keto.acl.v1alpha1.RelationTuple) | repeated | The relation tuples matching the list request. |
|
||||
| next_page_token | [string](#string) | | The token required to get the next page. If this is the last page, the token will be the empty string. |
|
||||
|
||||
## ory/keto/acl/v1alpha1/version.proto
|
||||
|
||||
### VersionService
|
||||
|
||||
The service returning the specific Ory Keto instance version.
|
||||
|
||||
This service is part of the
|
||||
[read-APIs](../concepts/25_api-overview.mdx#read-apis) and
|
||||
[write-APIs](../concepts/25_api-overview.mdx#write-apis).
|
||||
|
||||
| Method Name | Request Type | Response Type | Description |
|
||||
| ----------- | ------------------------------------------------------------- | --------------------------------------------------------------- | --------------------------------------------- |
|
||||
| GetVersion | [GetVersionRequest](#ory.keto.acl.v1alpha1.GetVersionRequest) | [GetVersionResponse](#ory.keto.acl.v1alpha1.GetVersionResponse) | Returns the version of the Ory Keto instance. |
|
||||
|
||||
### GetVersionRequest
|
||||
|
||||
Request for the VersionService.GetVersion RPC.
|
||||
|
||||
### GetVersionResponse
|
||||
|
||||
Response of the VersionService.GetVersion RPC.
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ------- | ----------------- | ----- | -------------------------------------------- |
|
||||
| version | [string](#string) | | The version string of the Ory Keto instance. |
|
||||
|
||||
## ory/keto/acl/v1alpha1/write_service.proto
|
||||
|
||||
### WriteService
|
||||
|
||||
The write service to create and delete Access Control Lists.
|
||||
|
||||
This service is part of the
|
||||
[write-APIs](../concepts/25_api-overview.mdx#write-apis).
|
||||
|
||||
| Method Name | Request Type | Response Type | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
|
||||
| TransactRelationTuples | [TransactRelationTuplesRequest](#ory.keto.acl.v1alpha1.TransactRelationTuplesRequest) | [TransactRelationTuplesResponse](#ory.keto.acl.v1alpha1.TransactRelationTuplesResponse) | Writes one or more relation tuples in a single transaction. |
|
||||
| DeleteRelationTuples | [DeleteRelationTuplesRequest](#ory.keto.acl.v1alpha1.DeleteRelationTuplesRequest) | [DeleteRelationTuplesResponse](#ory.keto.acl.v1alpha1.DeleteRelationTuplesResponse) | Deletes relation tuples based on relation query |
|
||||
|
||||
### DeleteRelationTuplesRequest
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | --------------------------------------------------------------------------------------------- | ----- | ----------- |
|
||||
| query | [DeleteRelationTuplesRequest.Query](#ory.keto.acl.v1alpha1.DeleteRelationTuplesRequest.Query) | | |
|
||||
|
||||
### DeleteRelationTuplesRequest.Query
|
||||
|
||||
The query for deleting relation tuples
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| --------- | ----------------------------------------- | ----- | ------------------------------------ |
|
||||
| namespace | [string](#string) | | Optional. The namespace to query. |
|
||||
| object | [string](#string) | | Optional. The object to query for. |
|
||||
| relation | [string](#string) | | Optional. The relation to query for. |
|
||||
| subject | [Subject](#ory.keto.acl.v1alpha1.Subject) | | Optional. The subject to query for. |
|
||||
|
||||
### DeleteRelationTuplesResponse
|
||||
|
||||
### RelationTupleDelta
|
||||
|
||||
Write-delta for a TransactRelationTuplesRequest.
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| -------------- | ----------------------------------------------------------------------------- | ----- | -------------------------------------- |
|
||||
| action | [RelationTupleDelta.Action](#ory.keto.acl.v1alpha1.RelationTupleDelta.Action) | | The action to do on the RelationTuple. |
|
||||
| relation_tuple | [RelationTuple](#ory.keto.acl.v1alpha1.RelationTuple) | | The target RelationTuple. |
|
||||
|
||||
### TransactRelationTuplesRequest
|
||||
|
||||
The request of a WriteService.TransactRelationTuples RPC.
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| --------------------- | --------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| relation_tuple_deltas | [RelationTupleDelta](#ory.keto.acl.v1alpha1.RelationTupleDelta) | repeated | The write delta for the relation tuples operated in one single transaction. Either all actions succeed or no change takes effect on error. |
|
||||
|
||||
### TransactRelationTuplesResponse
|
||||
|
||||
The response of a WriteService.TransactRelationTuples rpc.
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ---------- | ----------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| snaptokens | [string](#string) | repeated | This field is not implemented yet and has no effect. <!-- The list of the new latest snapshot tokens of the affected RelationTuple, with the same index as specified in the `relation_tuple_deltas` field of the TransactRelationTuplesRequest request.<br/>If the RelationTupleDelta_Action was DELETE the snaptoken is empty at the same index. --> |
|
||||
|
||||
### RelationTupleDelta.Action
|
||||
|
||||
| Name | Number | Description |
|
||||
| ------------------ | ------ | ----------------------------------------------------------------------------------------------------------- |
|
||||
| ACTION_UNSPECIFIED | 0 | Unspecified. The `TransactRelationTuples` RPC ignores this RelationTupleDelta if an action was unspecified. |
|
||||
| INSERT | 1 | Insertion of a new RelationTuple. It is ignored if already existing. |
|
||||
| DELETE | 2 | Deletion of the RelationTuple. It is ignored if it does not exist. |
|
||||
|
||||
## Scalar Value Types
|
||||
|
||||
| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby |
|
||||
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ---------- | ----------- | ------- | ---------- | -------------- | ------------------------------ |
|
||||
| <a id="double" ></a> double | | double | double | float | float64 | double | float | Float |
|
||||
| <a id="float" ></a> float | | float | float | float | float32 | float | float | Float |
|
||||
| <a id="int32" ></a> int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
|
||||
| <a id="int64" ></a> int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum |
|
||||
| <a id="uint32" ></a> uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) |
|
||||
| <a id="uint64" ></a> uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) |
|
||||
| <a id="sint32" ></a> sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
|
||||
| <a id="sint64" ></a> sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum |
|
||||
| <a id="fixed32" ></a> fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) |
|
||||
| <a id="fixed64" ></a> fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum |
|
||||
| <a id="sfixed32" ></a> sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
|
||||
| <a id="sfixed64" ></a> sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum |
|
||||
| <a id="bool" ></a> bool | | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass |
|
||||
| <a id="string" ></a> string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) |
|
||||
| <a id="bytes" ></a> bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) |
|
||||
7
docs/README.md
Normal file
7
docs/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Documentation
|
||||
|
||||
Please find the documentation at
|
||||
[www.ory.com/docs/keto](https://www.ory.com/docs/keto).
|
||||
|
||||
To contribute to the documentation, please head over to:
|
||||
[github.com/ory/docs/tree/master/docs/keto](https://github.com/ory/docs/tree/master/docs/keto)
|
||||
358
docs/ory_permission_language_spec.md
Normal file
358
docs/ory_permission_language_spec.md
Normal file
@@ -0,0 +1,358 @@
|
||||
# The "Ory Permission Language" Specification
|
||||
|
||||
Enforcing fine-grained permissions is a critical building block of mature
|
||||
technology solutions that protect privacy and identity in the information age.
|
||||
Several proprietary languages to represent permission already exist, namely the
|
||||
[Authzed Schema Language](https://docs.authzed.com/reference/schema-lang) and
|
||||
[Auth0 FGA](https://docs.fga.dev/). Most permissions are defined by normal
|
||||
developers who typically are most familiar with Web technologies like JavaScript
|
||||
or Typescript. We see the need for a developer-friendly configuration language
|
||||
for permissions that has such a small learning curve that most developers can
|
||||
understand and use it with close to no effort. We therefore chose to define our
|
||||
permissions configuration language as a subset of the most common
|
||||
general-purpose programming language: JavaScript/TypeScript.
|
||||
|
||||
The Ory Permission Language is a syntactical subset of TypeScript. Along with
|
||||
type definitions for the syntax elements of the language (such as `Namespace` or
|
||||
`Context`), users can get context help from their IDE while writing the
|
||||
configuration.
|
||||
|
||||
## Notation
|
||||
|
||||
The syntax is specified using the Extended Backus-Naur Form (EBNF):
|
||||
|
||||
```ebnf
|
||||
Production = production_name "=" [ Expression ] "." .
|
||||
Expression = Alternative { "|" Alternative } .
|
||||
Alternative = Term { Term } .
|
||||
Term = production_name | token [ "…" token ] | Group | Option | Repetition .
|
||||
Group = "(" Expression ")" .
|
||||
Option = "[" Expression "]" .
|
||||
Repetition = "{" Expression "}" .
|
||||
```
|
||||
|
||||
Productions are expressions constructed from terms and the following operators,
|
||||
in increasing precedence:
|
||||
|
||||
```ebnf
|
||||
| alternation
|
||||
() grouping
|
||||
[] option (0 or 1 times)
|
||||
{} repetition (0 to n times)
|
||||
```
|
||||
|
||||
Lower-case production names are used to identify lexical tokens. Non-terminals
|
||||
are in CamelCase. Lexical tokens are enclosed in double quotes `""` or single
|
||||
quotes `''`.
|
||||
|
||||
The form `a … b` represents the set of characters from a through b as
|
||||
alternatives. The horizontal ellipsis `…` is also used elsewhere in the spec to
|
||||
informally denote various enumerations or code snippets that are not further
|
||||
specified.
|
||||
|
||||
## Configuraton text representation
|
||||
|
||||
The configuration is encoded in UTF-8.
|
||||
|
||||
## Lexical elements
|
||||
|
||||
### Comments
|
||||
|
||||
1. Line comments start with the character sequence `//` and stop at the end of
|
||||
the line.
|
||||
2. General comments start with the character sequence `/*` and stop with the
|
||||
first subsequent character sequence `*/`.
|
||||
3. Documentation comments start with the character sequence `/**` and stop with
|
||||
the first subsequent character sequence `*/`.
|
||||
|
||||
### Identifiers
|
||||
|
||||
Identifiers name program entities such as variables and types. An identifier is
|
||||
a sequence of one or more letters and digits. The first character in an
|
||||
identifier must be a letter.
|
||||
|
||||
```ebnf
|
||||
identifier = letter { letter | digit } .
|
||||
digit = "0" … "9" .
|
||||
letter = "A" … "Z" | "a" … "z" | "_" .
|
||||
```
|
||||
|
||||
### String literals
|
||||
|
||||
String literals represent string constants as sequences of characters.
|
||||
|
||||
```ebnf
|
||||
string_lit = single_quoted | double_quoted .
|
||||
single_quoted = "'" identifier "'" .
|
||||
double_quoted = '"' identifier '"' .
|
||||
```
|
||||
|
||||
### Keywords
|
||||
|
||||
The configuration language has the following keywords:
|
||||
|
||||
- `class`
|
||||
- `implements`
|
||||
- `related`
|
||||
- `permits`
|
||||
- `this`
|
||||
- `ctx`
|
||||
- `id`
|
||||
- `imports`
|
||||
- `exports`
|
||||
- `as`
|
||||
|
||||
### Builtin Types
|
||||
|
||||
The following types are built in:
|
||||
|
||||
- `Context`
|
||||
- `Namespace`
|
||||
- `Namespace[]`
|
||||
- `boolean`
|
||||
- `string`
|
||||
- `SubjectSet<T, R>`
|
||||
|
||||
In TypeScript, they would be defined as follows:
|
||||
|
||||
```typescript
|
||||
type Context = { subject: never }
|
||||
|
||||
interface Namespace {
|
||||
related?: { [relation: string]: Namespace[] }
|
||||
permits?: { [method: string]: (ctx: Context) => boolean }
|
||||
}
|
||||
|
||||
interface Array<Namespace> {
|
||||
includes(element: Namespace): boolean
|
||||
traverse(iteratorfn: (element: Namespace) => boolean): boolean
|
||||
}
|
||||
|
||||
type SubjectSet<A extends Namespace, R extends keyof A["related"]> =
|
||||
A["related"][R] extends Array<infer T> ? T : never
|
||||
```
|
||||
|
||||
### Operators
|
||||
|
||||
The following character sequences represent boolean operators:
|
||||
|
||||
| Operator | Signature | Semantic |
|
||||
| -------- | -------------- | ------------------------------------ |
|
||||
| `&&` | _x_ `&&` _y_ | true iff. both _x_ and _y_ are true |
|
||||
| `\|\|` | _x_ `\|\|` _y_ | true iff. either _x_ or _y_ are true |
|
||||
| `!` | `!` _x_ | true iff. _x_ is false |
|
||||
|
||||
The following character sequences represent miscellaneous operators:
|
||||
|
||||
| Operator | Example | Semantic |
|
||||
| -------- | ---------------------------------------- | ----------------------------------------------------------------- |
|
||||
| `(`, `)` | `x()` | call function `x` |
|
||||
| `[]` | `T[]` | `T` is an array type |
|
||||
| `<`, `>` | `SubjectSet<Group, "members">` | Type reference to the "members" relation of the "Group" namespace |
|
||||
| `{`, `}` | `class x {}` | Scope delimiters |
|
||||
| `=>` | `list.transitive(el => f(el))` | Lambda definition token. |
|
||||
| `.` | `this.x` | Property traversal token |
|
||||
| `:` | `relation: type` | Relation/type separator token |
|
||||
| `=` | `permits = {...}` | Assignment token |
|
||||
| `,` | `{x: 1, y: 2}` | Property separator |
|
||||
| `'` | `'string'` | Single quoted string literal |
|
||||
| `"` | `"string"` | Double quoted string literal |
|
||||
| `*` | `import * from @ory/permission-language` | Import glob |
|
||||
| `\|` | `(User \| Group)[]` | Type union |
|
||||
|
||||
## Statements
|
||||
|
||||
### Type declaration
|
||||
|
||||
The top level of the configuration consists of a list of `class` declarations
|
||||
for each namespace. Each `class` consists of relation declarations and
|
||||
permission declarations.
|
||||
|
||||
```ebnf
|
||||
Config = [ ClassDecl ] .
|
||||
ClassDecl = "class" identifier "implements" "Namespace" "{" ClassSpec "}" .
|
||||
ClassSpec = [ RelationDecls ] | [ PermissionDefns] .
|
||||
```
|
||||
|
||||
The following example declares the type _User_.
|
||||
|
||||
```ts
|
||||
class User implements Namespace {}
|
||||
```
|
||||
|
||||
### Relation declaration
|
||||
|
||||
The `related` section of type declarations defines relations. Unlike regular
|
||||
TypeScript, `RelationName` must be a unique identifier used as the relation
|
||||
strings in the tuples. The `TypeName` must be the name of another `type` that is
|
||||
defined above or below (in TypeScript: a class that implements `Namespace`).
|
||||
|
||||
Type unions (`|`) can be used to denote that a relation can have subjects of
|
||||
multiple types, e.g., `viewers: (User | SubjectSet<Group, "members">)[]`,
|
||||
meaning that the subject of the "viewer" relation can be either a "User", or a
|
||||
subject set "Group#members".
|
||||
|
||||
```ebnf
|
||||
RelationDecls = "related" "=" "{" { RelationName ":" ArrayType } "}" .
|
||||
RelationName = identifier .
|
||||
ArrayType = RelationType | ( "(" RelationType { "|" RelationType } ")" ) "[]" .
|
||||
RelationType = SubjectType | SubjectSetType .
|
||||
SubjectType = TypeName .
|
||||
SubjectSetType = "SubjectSet" "<" TypeName, string_lit ">" .
|
||||
TypeName = identifier .
|
||||
```
|
||||
|
||||
Note that all relations are defined as array types `T[]` because there are
|
||||
naturally only many-to-many relations in Keto.
|
||||
|
||||
The following declares a type _Document_ with three relations: _owners_ and
|
||||
_viewers_, both of which have _users_ as subjects. Additionally, the relation
|
||||
_parent_ has type _Document_.
|
||||
|
||||
```ts
|
||||
class User {}
|
||||
|
||||
class Document {
|
||||
related = {
|
||||
parents: Document[]
|
||||
owners: User[]
|
||||
viewers: User[]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Permission definition
|
||||
|
||||
Permissions are defined as functions within class declarations that take a
|
||||
parameter `ctx` of type `Context` and evaluate to a boolean `true` or `false`.
|
||||
|
||||
The type annotations for `ctx` and the return value are optional.
|
||||
|
||||
```ebnf
|
||||
PermissionDefns = "permits" "=" "{" Permission [ "," Permission ] "}" .
|
||||
Permission = PermissionSign "=>" PermissionBody .
|
||||
PermissionSign = PermissionName ":" "(" "ctx" [ ":" "Context" ] ")" [ ":" "boolean" ] .
|
||||
PermissionName = identifier .
|
||||
```
|
||||
|
||||
The `ctx` object is a fixed parameter that contains the `subject` for which the
|
||||
permission check should be conducted:
|
||||
|
||||
```ts
|
||||
ctx = { subject: "some_user_id" }
|
||||
```
|
||||
|
||||
The context will contain more fields in the future, e.g., the IP range or
|
||||
geolocation, the time of day, or the security level of the device making the
|
||||
request.
|
||||
|
||||
```ebnf
|
||||
PermissionBody = ( "(" PermissionBody ")" ) | ( "!" PermissionBody ) | ( PermissionCheck | { Operator PermissionBody } ) .
|
||||
Operator = "||" | "&&" .
|
||||
PermissionCheck = TransitiveCheck | IncludesCheck .
|
||||
```
|
||||
|
||||
The body of a permission check is either one of:
|
||||
|
||||
- a `IncludesCheck`, a check that something is in a set, e.g.,
|
||||
`this.related.viewers.includes(ctx.subject)`:
|
||||
|
||||
```ebnf
|
||||
IncludesCheck = Var "." "related" "." RelationName "." "includes" "(" "ctx" "." "subject" ")" .
|
||||
Var = identifier .
|
||||
```
|
||||
|
||||
- a `TranstitiveCheck`, a call to a permission on a relation, e.g.,
|
||||
`this.related.parents.transitive(p => p.permits.view(ctx))`:
|
||||
|
||||
```ebnf
|
||||
TransitiveCheck = "this" "." "related" "." RelationName "." "transitive" "(" Var "=>" ( PermissionCall | IncludesCheck ) ")" .
|
||||
PermissionCall = Var "." "permits" "." PermissionName "(" "ctx" ")" .
|
||||
```
|
||||
|
||||
## Implementation notes
|
||||
|
||||
`IncludeCheck` and `TransitiveCheck` translate to Zanzibar concepts as follows:
|
||||
|
||||
| Keto Config | Zanzibar AST |
|
||||
| --------------------------------------------------------- | ------------------------------------------------------------------------------------ |
|
||||
| `this.related.R.includes(ctx.subject)` | `computed_userset { relation: "R" } }` |
|
||||
| `this.related.R.transitive(x = x.permits.P(ctx.subject))` | `tuple_to_userset { tupleset { relation: "R" } computed_userset { relation: "P" } }` |
|
||||
|
||||
## Type checking
|
||||
|
||||
The following type checks are performed once the config is fully parsed:
|
||||
|
||||
- Given a `TypeName` as `X` (e.g., in `RelationDecls`), we check that there
|
||||
exists a class declaration for `X`.
|
||||
- Given a `SubjectSetType` as `SubjectSet<T, R>`, we check that `R` is a
|
||||
relation defined for `T`.
|
||||
- Given an `IncludesCheck` as `this.related.R.includes(ctx.subject)`, we check
|
||||
that
|
||||
- `R` is a relation defined for the current namespace.
|
||||
- Given a `TransitiveCheck` as
|
||||
`this.related.R.transitive(x = x.permits.P(ctx.subject))`, we check that
|
||||
- `R` is a relation defined for the current namespace and that
|
||||
- `P` is a permission defined for all types referenced by `R`.
|
||||
- Given a `TransitiveCheck` as
|
||||
`this.related.R.transitive(x = x.related.S.includes(ctx.subject))`, we check
|
||||
that
|
||||
- `R` is a relation defined for the current namespace and that
|
||||
- `S` is a relation defined for all types referenced by `R`.
|
||||
|
||||
## Examples
|
||||
|
||||
The config can be type-checked in `strict` mode by TypeScript with the
|
||||
[noLib](https://www.typescriptlang.org/tsconfig#noLib) option (preventing the
|
||||
standard globals), and the
|
||||
[strictPropertyInitialization](https://www.typescriptlang.org/tsconfig#strictPropertyInitialization)
|
||||
option (allowing uninitialized properties).
|
||||
|
||||
```ts
|
||||
class User implements Namespace {
|
||||
related: {
|
||||
manager: User[]
|
||||
}
|
||||
}
|
||||
|
||||
class Group implements Namespace {
|
||||
related: {
|
||||
members: (User | Group)[]
|
||||
}
|
||||
}
|
||||
|
||||
class Folder implements Namespace {
|
||||
related: {
|
||||
parents: File[]
|
||||
viewers: (User | SubjectSet<Group, "members">)[]
|
||||
}
|
||||
|
||||
permits = {
|
||||
view: (ctx: Context): boolean => this.related.viewers.includes(ctx.subject),
|
||||
}
|
||||
}
|
||||
|
||||
class File implements Namespace {
|
||||
related: {
|
||||
parents: (File | Folder)[]
|
||||
viewers: (User | SubjectSet<Group, "members">)[]
|
||||
owners: (User | SubjectSet<Group, "members">)[]
|
||||
siblings: File[]
|
||||
}
|
||||
|
||||
permits = {
|
||||
view: (ctx: Context): boolean =>
|
||||
this.related.parents.traverse((p) =>
|
||||
p.related.viewers.includes(ctx.subject),
|
||||
) ||
|
||||
this.related.parents.traverse((p) => p.permits.view(ctx)) ||
|
||||
this.related.viewers.includes(ctx.subject) ||
|
||||
this.related.owners.includes(ctx.subject),
|
||||
|
||||
edit: (ctx: Context) => this.related.owners.includes(ctx.subject),
|
||||
|
||||
rename: (ctx: Context) =>
|
||||
this.related.siblings.traverse((s) => s.permits.edit(ctx)),
|
||||
}
|
||||
}
|
||||
```
|
||||
1
docs/sidebar.json
Normal file
1
docs/sidebar.json
Normal file
@@ -0,0 +1 @@
|
||||
[]
|
||||
Reference in New Issue
Block a user