client.canRead(crdtId)
Returns true if the token allows reading crdtId.
client.canWrite(crdtId, opMask?)
Returns true if the token allows writing crdtId. Pass an optional opMask to check op-level access (V2 tokens only).
Standalone helpers
canRead and canWrite are also exported as standalone functions — useful when you have the claims but not a client instance (e.g. in server-side rendering or middleware):
OpMasks reference
Op masks are combined with | to allow multiple operations.
| Constant | Value | Applies to |
|---|---|---|
OpMasks.ALL | 0 | Any CRDT — allows all ops (no restriction) |
OpMasks.GC_INCREMENT | 0x01 | GCounter |
OpMasks.PN_INCREMENT | 0x01 | PNCounter |
OpMasks.PN_DECREMENT | 0x02 | PNCounter |
OpMasks.OR_ADD | 0x01 | ORSet |
OpMasks.OR_REMOVE | 0x02 | ORSet |
OpMasks.LWW_SET | 0x01 | LwwRegister |
OpMasks.PRESENCE_UPDATE | 0x01 | Presence |
OpMasks.RGA_INSERT | 0x01 | RGA |
OpMasks.RGA_DELETE | 0x02 | RGA |
OpMasks.TREE_ADD | 0x01 | Tree |
OpMasks.TREE_MOVE | 0x02 | Tree |
OpMasks.TREE_UPDATE | 0x04 | Tree |
OpMasks.TREE_DELETE | 0x08 | Tree |
OpMasks.MAP_WRITE | 0x01 | CRDTMap |
How it works
The logic mirrors the server’sPermEntry::matches exactly:
- V1 tokens — glob-matched against the
read/writelists. Op masks are ignored (no op granularity in V1). - V2 tokens — rules are evaluated first-match-wins. Each rule may have a glob pattern (
p), an op mask (o), and a per-rule expiry (e). The{clientId}placeholder is expanded to the token’sclient_idbefore matching.
Multi-agent pattern
When using{clientId} in V2 permission patterns, each agent’s token is automatically scoped to its own keys:
{clientId} patterns.