Tenants & API keys

Your account is a tenant: a hard boundary around your connectors, credentials, people, roles and audit history. Every credential that reaches the gateway belongs to exactly one tenant, and the isolation is enforced in more than one place on purpose.

What a tenant owns

Owned by the tenantNotes
API keysOne per assistant integration is the recommended shape. Rotatable and revocable independently.
Connector configurationWhich systems are connected, and the encrypted credentials for each.
Seats and rolesThe people in your organisation and what each of them may invoke.
Audit logEvery tool call, denial and permission change, scoped to your tenant only.
Usage and quotaDaily call counts measured against your plan.

How isolation is enforced

Tenant isolation is not a single check that could be bypassed. It is applied at three layers, each of which would independently prevent cross-tenant access.

1
At the credential

An API key or OAuth token resolves to one tenant and only one. There is no key that addresses several, and no way to ask for another tenant's data with your own credential.

2
At the connector container

A connector decrypts only the credentials belonging to the tenant on the current request. It never holds another tenant's secrets in memory alongside yours.

3
At the database

Row-level security means a query issued for Tenant A cannot return Tenant B's rows, even if the gateway layer above it were somehow bypassed. This is the backstop that makes the other two safe to rely on.

API keys

Keys are generated in the console under Settings → API Keys. Each key is bound to the assistant it was made for and to a role, which is what turns a key into a scoped identity rather than a password.

Formatmsh_<assistant>_<random>
Claudemsh_cla_…
Copilotmsh_cop_…
Custom clientmsh_cus_…
Sent asAuthorization: Bearer <key>
ShownOnce, at creation. Only the prefix is stored for display.
⚠️

A key is shown exactly once. Copy it when it is generated. Msharti keeps only the prefix so you can recognise the key in a list. If it is lost, revoke it and issue another rather than trying to recover it.

How many keys should we have?

One per assistant integration. A key for the Claude connector, a key for the Copilot connector, a key for the internal script that runs the nightly reconciliation. The reason is operational rather than theoretical: when you need to revoke one, you want to revoke exactly one.

  • A person leaves. Revoke their seat, not the shared key that four other systems depend on.
  • A key leaks. Rotate it without an outage in every other integration.
  • An agent misbehaves. The audit log names the key, so you know exactly which integration to stop.

OAuth or a key?

Prefer OAuth wherever the client supports it. The difference is not convenience, it is what the audit log can tell you afterwards.

OAuth 2.1Static API key
Identity in the logThe person who signed inThe key, and whoever holds it
SetupAuto-discovered, nothing to pasteGenerate, copy, paste into the client
PermissionsPerson's role, resolved liveRole bound to the key at creation
RevocationRevoke the connection or the seatRevoke the key
Use whenDefault. Claude, ChatGPT, Copilot dynamic discovery.Client cannot do interactive OAuth, or DLP policy blocks it.

Rotating a key

  1. Generate the replacement first. Settings → API Keys → New key, same assistant, same role. Copy it.
  2. Update the client. Paste the new key into the assistant's connector configuration and confirm one tool call succeeds.
  3. Revoke the old key. Only now. Revoking first means an outage between step one and step two.
  4. Check the audit log. Calls should now be attributed to the new key prefix. If anything still arrives on the old one, something else was using it.

Related: build an agent covers choosing the role a key carries, and governance and audit covers reading the log afterwards.