diff --git a/app/spicedb/concepts/schema/page.mdx b/app/spicedb/concepts/schema/page.mdx index 96bc5894..1710015f 100644 --- a/app/spicedb/concepts/schema/page.mdx +++ b/app/spicedb/concepts/schema/page.mdx @@ -437,6 +437,35 @@ Examples: to a _computed_ set of subjects. +### Private/Internal Identifiers + +SpiceDB supports using an underscore (`_`) prefix for identifiers to establish a convention for marking definitions, relations, or permissions as "private" or "internal". This is a naming convention only—they are not treated any different at runtime, and they can still be used in relationships and permission checks like +any other identifier. + +```zed +definition document { + relation viewer: user + relation _internal_viewer: user // private: internal use only + + permission _can_view = viewer + _internal_viewer // private: synthetic + permission view = _can_view // public API +} +``` + +This convention is useful for: + +- **Synthetic permissions**: Permissions that exist only to compose other permissions +- **Internal relations**: Relations not meant to be directly referenced by application code +- **Implementation details**: Parts of your schema that may change without affecting the public API + +#### Identifier Rules + +- Identifiers can begin with a lowercase letter (`a-z`) or underscore (`_`) +- After the first character, identifiers can contain lowercase letters, numbers, and underscores +- Identifiers must be 3-64 characters long and end with an alphanumeric character +- Valid: `_ab`, `_private`, `_internal_relation`, `_helper123` +- Invalid: `_` (too short), `_a` (too short), `_trailing_` (cannot end with underscore) + ## Comments ### Documentation Comments