Skip to Content
Peretyn
SDK

Tuples

Write and delete the facts that checks are decided from.

Write tuples

write stores tuples. You can only write relations. Permissions are computed from them.

import { peretyn } from '@peretyn/sdk';
import type { schema } from './schema';

const authz = peretyn<typeof schema>({ token: process.env.PERETYN_TOKEN! });

const { written } = await authz.write({
  writes: [
    {
      subject: { type: 'user', id: 'alice' },
      relation: 'owner',
      object: { type: 'document', id: 'roadmap' },
    },
    {
      subject: { type: 'user', id: 'bob' },
      relation: 'viewer',
      object: { type: 'document', id: 'roadmap' },
    },
  ],
});

console.log(`wrote ${written} tuples`);

The script prints wrote 2 tuples.

Delete tuples

Pass deletes to remove tuples. One call can take both writes and deletes, and the runtime applies them in one transaction.

import { peretyn } from '@peretyn/sdk';
import type { schema } from './schema';

const authz = peretyn<typeof schema>({ token: process.env.PERETYN_TOKEN! });

await authz.write({
  deletes: [
    {
      subject: { type: 'user', id: 'bob' },
      relation: 'viewer',
      object: { type: 'document', id: 'roadmap' },
    },
  ],
});

const { allowed } = await authz.check({
  subject: { type: 'user', id: 'bob' },
  relation: 'can_view',
  object: { type: 'document', id: 'roadmap' },
});

console.log(allowed ? 'allowed' : 'denied');

The script prints denied. Bob's only path to the roadmap was the tuple that the script deleted.

Idempotent writes

By default, writing a tuple that already exists and deleting one that doesn't exist both succeed without changing anything. You can make either case an error:

OptionEffect
onDuplicate'ignore' (default) or 'error' when a written tuple exists.
onMissing'ignore' (default) or 'error' when a deleted tuple is missing.
strictSets both options to 'error'.

The SDK retries a write only when both options are 'ignore'. A strict write runs once.

written and deleted count the tuples that you sent, not the tuples that changed.

Read changes

readChanges pages through every write and delete in the environment, oldest first. Pass type to see changes to one object type only. Pass the continuationToken from one page to get the next.

On this page