Skip to Content
FeaturesTenants & Users

Tenants & Users

Tenants

A tenant is a workspace. The owner creates it via POST /v1/tenants after signing up. One owner may have several workspaces; they all share the owner’s Stripe customer.

On creation the platform writes the tenant row (tier=starter, status=active), provisions a per-tenant KMS CMK, reuses or creates the owner’s Stripe customer, creates a metered subscription, writes a free-credit row (10,000 tokens), and writes the owner membership row.

Selected tenant fields:

FieldNotes
tenant_idSystem-generated UUID
nameDisplay name; the proxy slug is derived from it via slugify()
slugStored for quick reference; renaming updates gsi1_pk
owner_subCognito sub of the creator
stripe_subscription_idOne subscription per workspace
tierstarter / pro / enterprise
statusactive / suspended / deleted
has_payment_methodtrue after Stripe Checkout setup completes
default_regioneu-central-1 / eu-central-2 / us-east-1
kms_cmk_arnPer-tenant KMS CMK

Deletion

  • Soft delete (DELETE /v1/tenants/{id}, owner): sets status=deleted, deleted_at=now, cancels the Stripe subscription immediately.
  • Hard delete / purge: automatic 14 days after soft delete via the daily cleanup cron, or on demand via DELETE /v1/tenants/{id}/purge (platform admin only). Removes GSI1 rows, membership rows, key rows, the Stripe customer (if it was the owner’s last workspace), and Cognito users.

Users & RBAC

RoleCapabilities
ownerFull access: billing, users, grants, keys, settings. One per tenant.
developerInvoke the proxy, view own usage, create own keys within their grant.
service_accountNon-human; holds an ar_live_... key; proxy invoke only. Not a Cognito user.

Roles are injected into the Cognito JWT (custom:tenant_role) by the pre-token-generation Lambda from the DynamoDB user row.

Invite flow

  1. The owner calls POST /v1/users/invite { "email": "dev@example.com" }.
  2. The control plane calls Cognito AdminCreateUser, sending an invite email.
  3. The developer registers; the post-confirmation trigger fires.
  4. Because an invited USER#<sub> row already exists, the trigger sets it active rather than creating a new tenant.
  5. The owner creates a grant for the developer via PUT /v1/grants/{dev_sub}.

Removing a user (DELETE /v1/users/{user_id}) sets status=removed on the DynamoDB row and automatically revokes their grant. The Cognito user is not deleted — they may belong to another tenant.

Last updated on