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 tenant | Notes |
|---|---|
| API keys | One per assistant integration is the recommended shape. Rotatable and revocable independently. |
| Connector configuration | Which systems are connected, and the encrypted credentials for each. |
| Seats and roles | The people in your organisation and what each of them may invoke. |
| Audit log | Every tool call, denial and permission change, scoped to your tenant only. |
| Usage and quota | Daily 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.
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.
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.
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.
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.1 | Static API key | |
|---|---|---|
| Identity in the log | The person who signed in | The key, and whoever holds it |
| Setup | Auto-discovered, nothing to paste | Generate, copy, paste into the client |
| Permissions | Person's role, resolved live | Role bound to the key at creation |
| Revocation | Revoke the connection or the seat | Revoke the key |
| Use when | Default. Claude, ChatGPT, Copilot dynamic discovery. | Client cannot do interactive OAuth, or DLP policy blocks it. |
Rotating a key
- Generate the replacement first. Settings → API Keys → New key, same assistant, same role. Copy it.
- Update the client. Paste the new key into the assistant's connector configuration and confirm one tool call succeeds.
- Revoke the old key. Only now. Revoking first means an outage between step one and step two.
- 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.