Skip to content

Commit 1857889

Browse files
committed
style(best-practises): Fix linting issues
1 parent f1dca2d commit 1857889

File tree

1 file changed

+40
-37
lines changed

1 file changed

+40
-37
lines changed

pages/best-practices/best-practices.mdx

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,68 @@
11
# Best Practices
22

3-
### Rule Categories
3+
## Rule Categories
44

5-
#### Priority A: Essential
5+
### Priority A: Essential
66

77
The essential rules are the most important ones.
88
Use them to ensure that your SpiceDB cluster is performant, your schema is sane, and your authorization logic is sound.
99
Exceptions to these rules should be rare and well justified.
1010

11-
#### Priority B: Strongly Recommended
11+
### Priority B: Strongly Recommended
1212

1313
The strong recommendation rules will improve the schema design, developer experience, and performance of your SpiceDB cluster.
1414
In most cases, these rules should be followed.
1515

16-
#### Priority C: Recommended
16+
### Priority C: Recommended
1717

1818
The recommended rules reflect how we would run our own systems, but may not apply to every use case and may not make sense in every situation.
1919
Follow them if you can and ignore them if you can’t.
2020

21-
### Priority A Rules: Essential
21+
## Priority A Rules: Essential
2222

23-
#### Make sure your schema fails closed
23+
### Make sure your schema fails closed
2424

2525
Tags: **schema**
2626

2727
This is related to the idea of using negation sparingly, and of phrasing your schema additively.
28-
Give thought to what happens if your application fails to write a relation: should the user have access in that case? The answer is almost always `no`.
28+
Give thought to what happens if your application fails to write a relation: should the user have access in that case?
29+
The answer is almost always `no`.
2930

30-
#### Tune Connections to Datastores
31+
### Tune Connections to Datastores
3132

3233
Tags: **operations**
3334

3435
To size your SpiceDB connection pools, start by determining the maximum number of allowed connections based on the documentation for your selected datastore, divide that number by the number of SpiceDB pods you’ve deployed, then split it between read and write pools.
3536

3637
Use these values to set the `--datastore-conn-pool-read-max-open` and `--datastore-conn-pool-write-max-open` flags, and set the corresponding min values to half of each, adjusting as needed based on whether your workload leans more heavily on reads or writes.
3738

38-
#### Test Your Schema
39+
### Test Your Schema
3940

4041
Tags: **schema**
4142

4243
You should be testing the logic of your schema to ensure that it behaves the way you expect.
44+
4345
- For unit testing and TDD, use test relations + assertions and [zed validate](https://authzed.com/docs/spicedb/modeling/validation-testing-debugging#zed-validate).
4446
- For snapshot testing, use test relations + expected relations and [zed validate](https://authzed.com/docs/spicedb/modeling/validation-testing-debugging#zed-validate).
4547
- For integration testing, use the SpiceDB test server with spicedb [serve-testing](https://authzed.com/docs/spicedb/modeling/validation-testing-debugging#integration-test-server).
4648

47-
#### Prefer Relations to Caveats
49+
### Prefer Relations to Caveats
4850

4951
Tags: **schema**
5052

5153
If an authorization concept can be expressed using relations, it should be.
5254
We provide caveats as an escape hatch; they should only be used for context that’s only available at request time, or else ABAC logic that cannot be expressed in terms of relationships.
5355

5456
Some examples:
57+
5558
- A banlist - this could be expressed as a list in caveat context, but it can also be expressed as a relation with negation.
5659
- A notion of public vs internal - boolean flags seem like an obvious caveat use case, but they can also be expressed using self relations.
5760
- Dynamic roles - these could be expressed as a list in caveats, and it’s not immediately obvious how to build them into a spicedb schema, but our [Google Cloud IAM example](https://authzed.com/blog/google-cloud-iam-modeling) shows how it’s possible.
5861

5962
This is because caveats come with a performance penalty.
6063
A caveated relationship is both harder to cache and also slows down computation of the graph walk required to compute a permission.
6164

62-
#### Make Your Writes Idempotent
65+
### Make Your Writes Idempotent
6366

6467
Tags: **application**
6568

@@ -68,7 +71,7 @@ As much as possible, we recommend that you use the `TOUCH` semantic for your wri
6871

6972
If you’re concerned about sequencing your writes, or your writes have dependencies, we recommend using preconditions.
7073

71-
#### Don’t truncate your tables when running Postgres
74+
### Don’t truncate your tables when running Postgres
7275

7376
Tags: **operations**
7477

@@ -79,9 +82,9 @@ To ensure that every request, whether cached or not, gets a consistent point-in-
7982
Some datastores provide this natively; in others we’ve implemented it on top of the datastore.
8083
In Postgres, the implementation of MVCC depends on the internals of the transaction counter being stored as data in the tables, so if you truncate the relationships table you desync the transaction counter with the stored relationships.
8184

82-
### Priority B Rules: Strongly Recommended
85+
## Priority B Rules: Strongly Recommended
8386

84-
#### Understand your consistency needs
87+
### Understand your consistency needs
8588

8689
Tags: **operations**
8790

@@ -92,23 +95,23 @@ To change this value, set `--datastore-revision-quantization-interval` longer or
9295
When it comes to write consistency, SpiceDB defaults to high safety, especially in distributed database writing scenarios, guaranteeing a visibility order.
9396
Individual datastores may also allow a relaxation of this guarantee, based on your scenario; for example, [setting CockroachDB’s overlap strategy](https://authzed.com/docs/spicedb/concepts/datastores#overlap-strategy), trading some authorization visibility safety across domains for greatly increased write throughput.
9497

95-
#### Use GRPC When Possible
98+
### Use GRPC When Possible
9699

97100
Tags: **application**
98101

99102
SpiceDB can be configured to expose both an [HTTP API](https://authzed.com/docs/spicedb/getting-started/client-libraries#http-clients) and associated Swagger documentation.
100103
While this can be helpful for initial exploration, we strongly recommend using one of our gRPC-based official client libraries if your networking and calling language support it.
101104
gRPC is significantly more performant and lower-latency than HTTP, and client-streaming services like ImportBulk can’t be used with the HTTP API.
102105

103-
#### Keep Permission Logic in SpiceDB
106+
### Keep Permission Logic in SpiceDB
104107

105108
Tags: **schema**
106109

107110
One of the big benefits to using a centralized authorization system like SpiceDB is that there's one place to look for your authorization logic, and authorization logic isn't duplicated across services.
108111
It can be tempting to define the authorization logic for an endpoint as being the `AND` or `OR` of the checks of other permissions, especially when the alternative is writing a new schema.
109112
However, this increases the likelihood of drift across your system, hides the authorization logic for a system in that system's codebase, and increases the load on SpiceDB.
110113

111-
#### Avoid Cycles in your Schema
114+
### Avoid Cycles in your Schema
112115

113116
Tags: **schema**
114117

@@ -142,7 +145,7 @@ definition group {
142145
}
143146
```
144147

145-
#### Phrase Permissions Additively/Positively
148+
### Phrase Permissions Additively/Positively
146149

147150
Tags: **schema**
148151

@@ -153,15 +156,15 @@ This reduces the number of ways that permission logic can interact, and prevents
153156
In concrete terms, that means use wildcards and negations sparingly.
154157
Start with no access and build up; don’t start with full access and pare down.
155158

156-
#### Use Unique Identifiers for Object Identifiers
159+
### Use Unique Identifiers for Object Identifiers
157160

158161
Tags: **application**
159162

160163
Because you typically want to centralize your permissions in SpiceDB, that also means that most of the `IDs` of objects in SpiceDB are references to external entities.
161-
These external entities shouldn't overlap.
164+
These external entities shouldn't overlap.
162165
To that end, we recommend either using `UUIDs` or using another identifier from the upstream that you can be sure will be unique, such as the unique sub field assigned to a user token by your IDP.
163166

164-
#### Avoid ReadRelationships API
167+
### Avoid ReadRelationships API
165168

166169
Tags: **application**
167170

@@ -170,7 +173,7 @@ Using it for permission logic is a code smell.
170173
All checks and listing of IDs should use `Check`, `CheckBulk`, `LookupResources`, and `LookupSubjects`.
171174
If you find yourself reaching for the `ReadRelationships` API for permission logic, there's probably a way to modify your schema to use one of the check APIs instead.
172175

173-
#### Prefer CheckBulk To LookupResources
176+
### Prefer CheckBulk To LookupResources
174177

175178
Tags: **application**
176179

@@ -180,24 +183,24 @@ Where possible, we recommend `CheckBulk`, because its work is bounded to the lis
180183
LookupResources generally requires a lot of work, causes a higher load, and subsequently has some of the highest latencies.
181184
If you need its semantics but its performance is insufficient, we recommend checking out our [Materialize](https://authzed.com/products/authzed-materialize) offering.
182185

183-
### Priority C Rules: Recommended
186+
## Priority C Rules: Recommended
184187

185-
#### Treat Writing Schema like Writing DB Migrations
188+
### Treat Writing Schema like Writing DB Migrations
186189

187190
Tags: **operations**
188191

189192
We recommend treating your SpiceDB schema as though it were a database migration.
190193
Keep it in your codebase, test it before deployment, and write it to your SpiceDB cluster as a part of your continuous integration process.
191194
This ensures that updates to your schema are properly controlled.
192195

193-
#### Load Test
196+
### Load Test
194197

195198
Tags: **operations**
196199

197200
To evaluate the performance and capabilities of your SpiceDB cluster and its underlying datastore, AuthZed provides [Thumper](https://github.com/authzed/thumper) — a load testing tool.
198201
You can use Thumper to simulate workloads and validate schema updates before deploying them to a production environment.
199202

200-
#### Use ZedTokens and “At Least As Fresh” for Best Caching
203+
### Use ZedTokens and “At Least As Fresh” for Best Caching
201204

202205
Tags: **application**
203206

@@ -207,15 +210,15 @@ If possible, we recommend using `at_least_as_fresh` with `ZedTokens` instead.
207210
Capture the `ZedToken` returned by your initial request, then include it in all subsequent calls.
208211
SpiceDB will guarantee you see a state at least as fresh as that token while still leveraging in-memory and datastore caches to deliver low-latency responses
209212

210-
#### Prefer Checking Permissions Instead of Relationships
213+
### Prefer Checking Permissions Instead of Relationships
211214

212215
Tags: **application**
213216

214217
It's possible to make a `Check` call with a relation as the permission.
215218
Even in a simple schema, we recommend instead that you have a permission that points at the relation and to check the relation.
216219
This is because if the logic of the check needs to change, it's easy to change the definition of a permission and difficult to change the definition of a relation (it often requires a data migration).
217220

218-
#### Enable schema watch cache
221+
### Enable schema watch cache
219222

220223
Tags: **operations**
221224

@@ -226,15 +229,15 @@ While we recommend enabling this, it isn't enabled by default because it require
226229
For Postgres, [`track_commit_timestamp`](https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-TRACK-COMMIT-TIMESTAMP) must be set to `on` for the Watch API to be enabled.
227230
For Spanner, there are a maximum of 5 changefeeds available globally for a table, and this consumes one of them.
228231

229-
#### Use the Operator
232+
### Use the Operator
230233

231234
Tags: **operations**
232235

233236
To ensure seamless rollouts, upgrades, and schema migrations, it is recommended to use the SpiceDB Kubernetes Operator if you’re using Kubernetes.
234237
The Operator automates many operational tasks and helps maintain consistency across environments.
235238
You can find the official documentation for the SpiceDB operator [here](https://authzed.com/docs/spicedb/concepts/operator).
236239

237-
#### Ensure that SpiceDB Can Talk To Itself
240+
### Ensure that SpiceDB Can Talk To Itself
238241

239242
Tags: **operations**
240243

@@ -246,43 +249,43 @@ In our experience, running SpiceDB on Kubernetes with our [Operator](https://aut
246249
It’s possible to configure dispatch using DNS as well, but non-Kubernetes based dispatching relies upon DNS updates, which means it can become stale if DNS is changing.
247250
This is not recommended unless DNS updates are rare.
248251

249-
#### Choose the Right Load Balancer
252+
### Choose the Right Load Balancer
250253

251254
Tags: **operations**
252255

253256
In our experience, TCP-level L4 load balancers play more nicely with gRPC clients than HTTP-level L7 load balancers.
254257
For example, we’ve found that even though AWS Application Load Balancers purport to support gRPC, they have a tendency to drop connections and otherwise misbehave; AWS Network Load Balancers seem to work better.
255258

256-
#### Use the Provided Metrics, Traces, and Profiles
259+
### Use the Provided Metrics, Traces, and Profiles
257260

258261
Tags: **operations**
259262

260263
To gain deeper insights into the performance of your SpiceDB cluster, the pods expose both Prometheus metrics and `pprof` profiling endpoints.
261264
You can also configure tracing to export data to compatible OpenTelemetry backends.
262265

263266
- Refer to the [SpiceDB Prometheus documentation](https://authzed.com/docs/spicedb/ops/observability#prometheus) for details on collecting metrics.
264-
- AuthZed Cloud supports exporting metrics to Datadog via the official [AuthZed cloud datadog integration](https://docs.datadoghq.com/integrations/authzed_cloud/).
265-
- To gain a complete picture of your SpiceDB cluster’s performance, it’s important to export metrics from the underlying datastore.
267+
- AuthZed Cloud supports exporting metrics to Datadog via the official [AuthZed cloud datadog integration](https://docs.datadoghq.com/integrations/authzed_cloud/).
268+
- To gain a complete picture of your SpiceDB cluster’s performance, it’s important to export metrics from the underlying datastore.
266269
These metrics help identify potential bottlenecks and performance issues.
267270
AuthZed Cloud provides access to both CockroachDB and PostgreSQL metrics via its cloud telemetry endpoints, enabling deeper visibility into database behavior.
268271
- The [profiling documentation](https://authzed.com/docs/spicedb/ops/observability#profiling) explains how to use the pprof endpoints.
269272
- The [tracing documentation](https://authzed.com/docs/spicedb/ops/observability#opentelemetry-tracing) walks you through sending trace data to a Jaeger endpoint.
270273

271-
#### Use Partials + Composable Schema to Organize your Schema
274+
### Use Partials + Composable Schema to Organize your Schema
272275

273276
Tags: **schema**
274277

275278
As a schema grows in size and complexity, it can become difficult to navigate and grok.
276279
We implemented [Composable Schemas](https://authzed.com/docs/spicedb/modeling/composable-schemas) to solve this problem, allowing you to break down a schema into multiple files and definitions into multiple problems.
277280

278-
#### When In Doubt, Add Another Permission
281+
### When In Doubt, Add Another Permission
279282

280283
Tags: **schema**
281284

282285
When adding a new feature or service, it can be tempting to re-use existing permissions that currently match the semantics you’re looking for, rather than doing the work of modifying the schema to introduce a new permission.
283286
However, if the authorization business logic changes between use cases, you’ll not only have to do the work of modifying the permission, but also modifying the call site, so we recommend frontloading that work.
284287

285-
#### Use Expiration Feature for Expiration Logic
288+
### Use Expiration Feature for Expiration Logic
286289

287290
Tags: **schema**
288291

0 commit comments

Comments
 (0)