## Base Layer EP 03: Spencer Kimball on Governance Is the Real Blocker
[Listen now](/content/base-layer/spencer-kimball/index.html)

> [github.com/authzed/spicedb](https://github.com/authzed/spicedb) ★7015

```zed
// Paste your SpiceDB schema here, or load an example above.
```

## What this validator checks

The parser is the same [official Authzed parser](https://github.com/authzed/spicedb-parser-js) that powers the SpiceDB Playground and VS Code extension, so accepted schemas match what SpiceDB itself parses.

### Syntax errors

Malformed definitions, missing braces, and unexpected tokens, reported with the line and column and a friendly explanation.

### Undefined types

References to types that don’t exist in the schema, with "did you mean…" suggestions powered by edit distance.

### Unknown relations & permissions

Anything referenced inside a permission expression that doesn’t resolve to a real relation or permission in the surrounding definition.

### Undefined caveats & partials

Catches typos in `with my_caveat` clauses and partial references, with suggestions across the schema’s defined names.

### Duplicates & reserved names

Two definitions sharing a name, two relations/permissions sharing a name inside a definition, or any identifier colliding with a reserved keyword.

### Lint hints

Unused relations (including cross-definition arrows), non-snake_case names, and empty definitions, flagged as warnings or hints so they don’t block valid schemas.

Caveat expressions (the body of`caveat ... { ... }`) are parsed but their CEL semantics aren't type-checked here. Apply your schema to a running SpiceDB for that.

## Schema tips & tricks

A few patterns that separate a schema that works from one that scales.

- **Use arrows (`->`) for inherited permissions.** Don't re-declare admin or member checks on every child object, let them flow from a parent:`organization->admin`.
- **Combine with intersection (`&`) and exclusion (`-`) for exceptions.** Model "editor, unless suspended" as`editor - suspended` instead of adding a new relation everywhere it's checked.
- **Name relations for the subject, permissions for the action.** `viewer`/`editor`/`owner` are relations; `view`/`edit`/`delete` are permissions. Mixing the two up is one of the most common schema bugs.
- **Avoid wildcard subjects unless you mean "everyone."** `relation viewer: user:*` grants access to every user in the system; reach for it only on genuinely public resources.
- **Watch your arrow depth.** Each `->` hop is a graph walk at check time; three or four hops deep can slow down `LookupResources` on large datasets.

```
definition organization {
  relation admin: user
  relation member: user
}

definition project {
  relation organization: organization
  relation contributor: user
  relation suspended: user

permission edit = (contributor + organization->admin) - suspended
  permission view = edit + organization->member
}
```

## Frequently asked questions

### Is my schema sent to a server?

### How accurate is this compared to running zed validate?

### What about caveats?

### Where can I learn the SpiceDB schema language?

### Can I use this in CI?

## Ship authorization with confidence.

AuthZed is the team behind SpiceDB. Get production-grade fine-grained permissions for your application.
