Querying Data
This page walks through the main ways to query data in SpiceDB. The options are listed from most preferred to least preferred in terms of performance, but the right choice always depends on your use case.
In most of the APIs below, if you want to be able to read your write, you can
pass a consistency parameter to the queries. Use either fully_consistent
or at_least_as_fresh(revision) depending on how strict you need to be. See
Consistency for more details.
When invoking any of our APIs, you can send a header X-Request-ID=somevalue
and it will be echoed back in the response, which makes correlating logs or
tracing requests easy.
Check Permission
CheckPermission is the go-to for most access checks. It’s designed for high-traffic workloads.
You can debug a check locally with zed permission check resource:someresource somepermission user:someuser --explain to understand how the decision was made.
When your schema uses caveats and you don’t provide all the required context in the request parameters, the API will tell you that in the response that the result is “conditional” instead of simply denying or allowing, and it’s up to you to inspect that result.
The subject of the query can be a single user (e.g. user:someuser) or a set of users (e.g. group:engineering#member).
CheckBulkPermissions
If your app needs to do multiple checks (for example, for various subjects), use the CheckBulkPermissions API. It’s great for UI workloads where you need to check multiple permissions at once: think tables, lists, and dashboards.
It’s always preferable to perform one call to CheckBulkPermissions with N checks than N calls to CheckPermission, unless you don’t want to wait for the N checks to finish.
LookupResources
LookupResources is a good choice when you need to find all resources of a given type that a specific subject can access. It supports cursoring and works well for moderate result sizes.
If you’re expecting more than ~10,000 results, this isn’t ideal. At that point you’ll get better performance and cost efficiency from our Materialize offering.
LookupSubjects
LookupSubjects returns all subjects that have access to a specific resource. It does not support cursoring, and the response includes a list of objects that have been explicitly excluded.
For example, if the schema is
definition user {}
definition document {
relation blocked: user
relation view: user:*
permission viewer = view - blocked
}and the relationships are
document:finance#view@user:*
document:finance#blocked@user:anne
document:finance#blocked@user:bobThen LookupSubjects for document:finance will return a response of the form {user:* - [user:anne,user:bob]}.
If you are looking to find all the subjects that are on a specific relation, use ReadRelationships instead of LookupSubjects.
ReadRelationships
ReadRelationships should be your last resort. It’s slower, it doesn’t populate or use the permissions cache, and it won’t evaluate caveats. Use it only when you truly need raw relationship data and none of the higher-level APIs fit the job.
Watch
The Watch API is not meant to answer permission questions but to serve other use-cases, like auditing. See this for more details.
ExpandPermissionTree
This ExpandPermissionTree API is useful in scenarios where your UI needs to show which users and groups have access to something.