SpiceDB Zookies: The Key to Preventing New‑Enemy Attacks in ReBAC
SpiceDB’s Zookies are the safety net that guarantees causal consistency in a distributed ReBAC system. Learn how to use them to prevent New‑Enemy attacks, with a concrete schema example, write‑and‑check workflow, and best‑practice checklist.
17 Sept 2026, 06:09 UTC

Why Zookies Matter for ReBAC
In a graph‑based access control system like SpiceDB, permissions are decided by traversing relationships. When an admin revokes a relationship (for example, removing a user from a group), the change must be visible to all subsequent reads. If a client reads the graph before the revocation is fully propagated, it may still grant access – the classic New‑Enemy attack. SpiceDB solves this with Zookies, a lightweight consistency token that guarantees causal consistency across its distributed store.
What Are Zookies?
A Zookie is a monotonically increasing token issued by SpiceDB after every write operation. It represents a snapshot of the graph at a specific point in time. When a client performs a Check request, it can supply the most recent Zookie it has seen. SpiceDB then ensures that the check is evaluated against a graph state that is at least as recent as that token, preventing stale reads from granting access that should have been revoked.
Without a Zookie, SpiceDB falls back to a less strict consistency mode that may return results from a slightly older snapshot, which is sufficient for many workloads but opens the door to the New‑Enemy problem.
Defining a Recursive Group Schema
Below is a minimal schema that shows nested group membership, a common pattern in real‑world applications. The group type can contain other group objects, enabling hierarchical groups.
type user
attributes
email: string
# A group can contain other groups or users
# This recursive definition is key for nested permissions
type group
relations
member: one @user | @group
# A resource that grants access to members of a group
type file
relations
owner: one @user
shared_with: one @group
Deploying a Local SpiceDB Instance
- Pull the Docker image:
docker pull ghcr.io/authzed/spicedb:latest - Run the server:
docker run -p 50051:50051 ghcr.io/authzed/spicedb:latest - Apply the schema using
spicedb schema apply --schema-file schema.spice(requires the CLI and admin privileges).
Writing Relationships and Capturing Zookies
When you create or delete a relationship, SpiceDB returns a Zookie. Store this value – it represents the latest consistent snapshot you have observed.
# Grant user "[contact removed]" membership in group "engineering"
spicedb write \
-z "admin:role=admin" \
-r "user:[contact removed]#member @group:engineering"
# Response (simplified)
{
"zookie": "z-1234567890"
}
Immediately after revoking the same relationship:
spicedb delete \
-z "admin:role=admin" \
-r "user:[contact removed]#member @group:engineering"
# Response
{
"zookie": "z-1234567901"
}
Notice the Zookie increments. Any subsequent Check must use at least z-1234567901 to see the revocation.
Checking Permissions With and Without a Zookie
Assume a file report.pdf is shared with the engineering group. Alice tries to read it.
# Check without a Zookie (default consistency)
spicedb check \
-z "admin:role=admin" \
-r "user:[contact removed]#can_read @file:report.pdf"
# The result may still be "allow" if the revocation hasn’t propagated.
Now provide the latest Zookie:
spicedb check \
-z "admin:role=admin" \
-r "user:[contact removed]#can_read @file:report.pdf" \
-t "z-1234567901"
# Expected: "deny" because the revocation is guaranteed to be visible.
In practice, you should always store the Zookie from the most recent write and include it in every subsequent check. SpiceDB will return an error if you supply an outdated Zookie, forcing the client to refresh its view of the graph.
Trade‑Offs and Limitations
- Latency vs. Consistency: Using Zookies adds a small overhead because each check must contact a quorum of replicas to validate the snapshot. For read‑heavy workloads where eventual consistency is acceptable, you might skip the token, but be aware of the New‑Enemy risk.
- Complexity: Clients must manage Zookies – store them, refresh them on writes, and handle errors when a stale token is used. This adds a layer of state management to your authorization logic.
- Nested Recursion: Deeply nested group hierarchies can increase traversal time. Model groups with shallow depth or use caching strategies to mitigate latency.
- IdP Independence: SpiceDB is an authorization service, not an identity provider. Ensure your system still authenticates users before making authorization decisions.
Actionable Checklist for Production
- Deploy SpiceDB with a reliable distributed backend (e.g., CockroachDB, Cassandra). Verify that the
zookiefield is present in write responses. - Implement a Zookie cache in your client library: after each write, update the cached token; on a failed check due to an old token, refresh and retry.
- Test the New‑Enemy scenario: write a relationship, revoke it, then perform a check without updating the Zookie. Confirm that the result is “deny” only when the latest token is used.
- Monitor latency of
Checkcalls. If latency spikes, review group nesting depth and consider flattening the hierarchy or adding read‑through caches. - Document the Zookie management flow for developers. A small diagram (see below) can help onboard new team members.
Conclusion
SpiceDB’s Zookies are the linchpin that turns a flexible graph‑based permission model into a robust, causally consistent system. By treating the Zookie as a first‑class citizen in your client code, you can confidently prevent New‑Enemy attacks while still enjoying the expressive power of recursive relationships. The trade‑offs are manageable—mostly around added latency and state management—and the payoff is a secure, modern authorization layer that scales with your distributed architecture.
Diagram: Zookie Flow in SpiceDB
| Step | Description |
|---|---|
| Write Relationship | Server returns new Zookie |
| Store Zookie Locally | Client caches latest token |
| Check Request | Client includes Zookie; server guarantees snapshot >= Zookie |
| Stale Revocation | Without Zookie, check may return outdated result |
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.