TryMellon
Navigation

Tenants vs accounts

How TryMellon models accounts, tenants, and applications — and who can do what.

Tenants vs accounts

TryMellon’s data model has three nested concepts: account → tenants → applications. Understanding this shape is critical for reading the dashboard, interpreting 404 errors on admin endpoints, and wiring S2S integrations correctly.


Core concepts

Account (your billing entity)
├── Tenant A          ← isolates users, credentials, audit logs
│   └── Application A1
├── Tenant B
│   ├── Application B1
│   └── Application B2
└── Tenant C
    └── Application C1
  • Account — the top-level entity that owns billing, plan limits, and member users. One account per customer.
  • Tenant — an isolation boundary for runtime data (users, credentials, sessions, audit logs). Customer A’s users cannot authenticate against Customer B’s tenant by construction.
  • Application — a client/app inside a tenant. Holds the OAuth2 credentials, webhook configuration, WebAuthn RP ID, etc.

When does a new tenant get created?

Every call to POST /v1/applications from a dashboard user session creates a new tenant + the application + an owner membership for the creator in that new tenant.

Why: this keeps users, audit logs, and credentials isolated per application even inside the same account. A breach of one application’s credentials cannot pivot into another application’s users.

Consequence: your dashboard account will often have many tenants (one per app), and the “Applications” list you see spans them. A tenant name like "Tenant: 7f3a-…-auto" is an auto-generated label for an application’s isolation boundary — not an error.

Authorization model

TryMellon distinguishes two callers:

CallerCredentialScopeCan list apps cross-tenant?
Service principalOAuth2 client credentials (client_id + client_secret)One tenant (the tenant the credentials are issued for)No — tenant-scoped only
User principalSession cookie / JWT obtained via passkey loginThe account the user belongs to, plus every tenant they are a member ofYes — with ?scope=account

Matrix: who can do what

ActionService principal (same tenant)User creatorUser tenant ownerUser tenant adminUser tenant viewer
GET /v1/applications/:id❌ (404)❌ (404)
PATCH /v1/applications/:id❌ (404)❌ (404)
POST /v1/applications/:id/rotate-secret❌ (404)❌ (404)
DELETE /v1/applications/:id (future)❌ (404)❌ (404)❌ (404)
GET /v1/applications?scope=account❌ (403)

admin and developer roles do not grant edit/rotate/delete on applications today — only the owner role does. This is a conservative default; if your team needs a finer role × action matrix, reach out.

Denials return 404, not 403

For per-resource endpoints (:id), TryMellon returns 404 application_not_found on every denial — regardless of whether the app exists. This is a deliberate info-leak mitigation: an attacker probing your tenant cannot distinguish “app does not exist” from “app exists but I’m not authorized”. Audit logs internal to TryMellon capture the reason (authorization.denied) with the principal identity and the resource’s tenant so operators can reconcile.

See Admin REST API → Error responses for the full shape.

Dashboard segmentation

The TryMellon dashboard reflects this model in two sections:

  • Account — Overview, Billing, Team, Applications (cross-tenant list with a Tenant column).
  • Tenant — Users, Credentials, Audit logs, Settings — scoped to the selected tenant via a tenant switcher.

This keeps the “one app = one tenant” reality visible without requiring you to know the tenant ID of each app.