SOFTWARE / SYSTEMS / AIEngineering news. Technical depth.
Authorization / 3 MIN READ

Garbage-collect relationship tuples without resurrecting access

Use immutable IDs, tombstones, ordered cleanup, and restore rules so deleted principals and resources cannot regain stale permissions.

Relationship tuples must be deleted as part of the resource lifecycle, while identifiers must never be reused for a different security principal. Use immutable random IDs, tombstone deletions, remove inbound and outbound relationships asynchronously with tracked progress, and define backup restore so old tuples cannot reappear as valid access.

Make identity reuse impossible

A tuple such as user:42 viewer document:9 is meaningful only if both identifiers forever name the same security objects. Reassigning user:42 to a new employee or recreating tenant slug acme can grant permissions intended for the deleted principal. Keep display names and mutable slugs outside authorization identifiers. Generate immutable IDs and retain tombstones long enough to reject delayed writes and restores.

Ory’s documentation explains relationships in Ory Permissions as namespace, object, relation, and subject components. Ory Keto is a fine-grained relationship-based permission system with permission inheritance. That model makes lifecycle discipline important: deleting an application row does not by itself prove every relationship referencing its identifier disappeared. Ory Network and self-hosted deployments should each be evaluated according to their current operational interfaces and retention setup.

Delete in a safe order

First mark the application object deleting and reject new relationship writes for it. Next revoke high-risk access synchronously when feasible. Queue cleanup of tuples where the object is either subject or resource, including group and parent relationships that grant indirect access. Verify counts and retry idempotently. Only then finalize application deletion according to retention policy.

OpenFGA’s guide to updating relationship tuples documents tuple deletion and combining writes and deletes atomically in supported requests. The broader lesson is to make tuple mutation explicit and observable. A garbage collector should use the authorization system’s supported write path, not direct database deletion that bypasses consistency and audit behavior.

Keep a deletion ledger with immutable object ID, deletion epoch, cleanup cursor, tuple counts, failures, and completion. Metrics should expose age of the oldest incomplete deletion and writes rejected against tombstones. A retry after partial failure must continue from the ledger rather than resurrect the object to make cleanup easier.

Treat backups as another writer

A backup can restore tuples whose application objects remain deleted, or restore an old object alongside relationships created later. Define a coordinated recovery point or a reconciliation phase. After restore, compare tuple subjects and objects with authoritative lifecycle records, reject tombstoned IDs, and quarantine unresolved references before serving authorization decisions.

Document restoration needs a new object ID by default. If the product promises restoration of the same logical document, restore under the same immutable ID only when the tombstone and all authorization history are restored consistently. Never attach an old tuple set to a newly created object that happens to share a slug.

Tenant deletion is the strongest test. Enumerate users, groups, resources, invitations, service accounts, and cross-tenant relationships. Block recreation of the same internal tenant ID, even if the customer later reuses its display name. Confirm that a delayed event from before deletion cannot write a tuple after cleanup.

Exercise resurrection scenarios

Create a tenant, group, user, and inherited document grant. Delete them with the cleanup worker paused, then resume it. Retry old tuple events, restore a backup, and recreate matching display names. At every stage, assert that the new objects have no old access. Start by adding immutable lifecycle IDs and a deletion ledger to the resource type with the broadest relationship graph.

Coordinate event consumers

Deletion competes with delayed membership and sharing events. Include an object generation or deletion epoch in events, and reject a write older than the tombstone. Consumers should acknowledge permanent rejection rather than retry forever. Test queue replay after restore and out-of-order create, grant, delete, and revoke messages across each relationship boundary. Confirm cleanup catches relationships in which the deleted object appears as a subject set as well as a resource.

Reviewed September 2026.

SOURCES & REVIEW

Sources are linked throughout this guide. Product capabilities can change; consult the linked documentation for your deployment.

Read our editorial approach ↗