Skip to navigation

Data dictionary

The complete inventory of what Writ keeps about you and your agents. If an object isn’t listed here, Writ doesn’t store it.

A standing rule: raw secrets are never stored. API keys, sponsor tokens, and magic-link tokens are kept as SHA-256 hashes only. The raw value is shown exactly once, at creation, and then it’s gone.

Tenant

Your account. One tenant per email address. Everything below belongs to a tenant.

FieldMeaning
idten_… — the tenant’s unique id
nameHuman-readable name (defaults to your email domain)
emailThe address the tenant was created from
planfree, or flipped by the Stripe webhook after payment
policyThe tenant’s policy (see Policy)
stripe_customer_idSet once a Stripe customer exists for this tenant
pending_welcomeTrue until the first API key + sponsor token are issued
created_atUnix timestamp

API key

Authenticates calls to the gate. Looks like writ_…. A tenant can have many.

FieldMeaning
key_hashSHA-256 of the key. The raw key is never stored
prefixShort non-secret display prefix (e.g. writ_AbC1) so you can tell keys apart in the portal
labelOptional label you set at creation
emailAddress it was issued for
tenant_idOwning tenant
planMirrors the tenant plan at issue time
checks_used / receipts_countUsage counters for the current period
period / usage_sinceThe billing period the counters belong to
created_atUnix timestamp
revoked_atSet when revoked. Revoked keys stop authenticating immediately; the record is kept

Lost your key? While signed in to the portal you can mint a new one (API keys → + New key) and revoke the lost one. No need to delete anything.

The human half of the credential pair. Looks like writ_sp_…. One per tenant, minted when the tenant is created, shown once, never recoverable, never re-issued through the portal today.

It authorizes the human-side operations: creating grants, revoking and reinstating principals. The API key says which tenant is asking; the sponsor token says a human approved this.

Principal

An agent acting on someone’s behalf: a sponsor (the human or system that approves) plus an agent (the software doing the work), within a tenant. Principals come into existence implicitly — the first time a grant names them — and can be revoked pre-emptively.

FieldMeaning
sponsor_idWho approved this agent’s actions
agent_idThe agent itself
tenant_idOwning tenant

Policy

One per tenant. A table mapping each verb to a mode. There is no per-agent or per-environment policy today.

ModeMeaning
allowThe check passes without further approval
denyThe check fails; the write must not run
require_grantThe check passes only with a live grant
step_upA human sponsor must approve via a grant first

The verb set is fixed in the gate (money movement, identity, data changes, communications, infrastructure, and others). Custom verbs are not supported today.

Grant

A short-lived permission slip minted by a human (sponsor token or dashboard) after a STEP_UP, or directly via POST /v1/grants.

FieldMeaning
idgrnt_…
sponsor_id / agent_id / verb / target / purposeExactly what is allowed. All five must match the check
ttl_secondsLifetime. Defaults to 90 seconds, max 3600 (1 hour)
expires_atUnix timestamp when it dies
spentSingle-use semantics: it can’t be reused for a different write
tenant_idOwning tenant
created_atUnix timestamp

Receipt

Written for every decision the gate makes — ALLOW, DENY, STEP_UP, REVOKE, and others. Denials write receipts too: the refusal itself is auditable. Receipts are the audit log, and the audit log is the meter.

FieldMeaning
receiptIdrcpt_…
tenantIdOwning tenant
decisionThe gate’s answer
sponsorId / agentId / verb / target / purposeWhat was decided on
grantIdThe grant that authorized it, if any
reasonHuman-readable reason for the decision
policyVersionThe policy version the decision ran against
prevHash / chainHashTamper-evident chain: each receipt stores the previous receipt’s chainHash (or GENESIS), and chainHash = HMAC(canonical fields + prevHash) with a tenant-specific key
createdAtUnix timestamp

Verify any receipt chain with GET /v1/receipts/verify or ./writ verify-chain.

Revocation

The kill switch. Revoking a principal denies every subsequent check for that sponsor/agent pair, immediately.

FieldMeaning
sponsor_id / agent_idThe principal being cut off
reasonWhy, in your words
revoked_atUnix timestamp
tenant_idOwning tenant

Reinstate undoes it; the principal can check again.

Single-use sign-in token, emailed to you. Stored as a SHA-256 hash with a 15-minute expiry; the raw token travels in the URL fragment so it never lands in server logs. The account-creation variant works the same way and creates the tenant only when clicked.

Rate limits

Unauthenticated endpoints are bounded before any account lookup, so the limits themselves can’t be used to probe for accounts: 30 magic-link requests per hour per IP, a per-email cooldown on magic links, and per-tenant caps on key creation.