> For the complete documentation index, see [llms.txt](https://sdk.metamarket.tech/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sdk.metamarket.tech/architecture-and-trust/security-and-tenant-isolation.md).

# Security and Tenant Isolation

Every game on MetaMarket is a tenant, and the platform's first job is to keep one tenant's data and reach confined to that tenant. This page is the isolation and access model a technical reviewer needs; the mechanics behind each point are in [Authentication](/evaluate-and-integrate/authentication.md) and [Roles and permissions](/architecture-and-trust/users-and-actors.md).

## How tenants are isolated

Every tenant-scoped record carries the app id that owns it, and reads and writes are filtered by it.

An external client sends an `X-App-Id` header. Four server-side controls make it trustworthy:

* **The gateway serves a fixed list of app ids**, held in its own configuration, and rejects any `/api/*` call outside that list. Auth calls are the exception, since identity is app-agnostic.
* **A gateway placed in front of a single partner is registered for that partner alone.** That is what makes the binding single-tenant, and it is confirmed at onboarding rather than assumed.
* **The app secret never comes from the client.** The gateway selects it only from its own configuration.
* **On event calls the engine takes the acting app id from the header** the gateway already validated against that secret, and overwrites anything the request body claims.

Where the gateway's configured set is that one app, a request it accepts is necessarily that tenant. There is no second app id a client behind it could name, and no secret it could substitute, so the external client-and-gateway path acts only as its own app. This binding is enforced by the server-side gateway provisioning, not by the client: the SDK stamping the app id on each call is a convenience, and the same guarantee holds for a raw HTTP client, which the gateway constrains the same way. Access to several tenants from one process, including the platform's own, is a separate first-party path (`Platform.Sdk`, direct to the engine) that is internal-only and not part of this external surface.

One boundary is independent of all of the above: shared platform state, the platform currency and loyalty standing, is not readable or writable by any external app. That is enforced by the platform's own trust gating rather than by the tenant header, so an external client reaches it only through a platform-owned workflow that reacts to a reported milestone, described in [Local and Shared Economies](/core-concepts/shared-economy.md). The hosting and gateway controls are reviewed with the team during onboarding, where the server-side enforcement of this single-app binding is confirmed rather than left to the client.

## How players and apps authenticate

Players authenticate with a device key. Each device generates a private key it never shares and registers only the public key, and a session is issued once the device proves possession of that key.

There is one deliberate exception. The first connection from an unknown device bootstraps a new guest player without a proof, because there is nothing yet to prove against. Every session issued or refreshed after that requires the key.

Two credentials are in play, and they behave differently:

* **The access token** is a short-lived bearer credential, RS256 and 15 minutes. Treat it like any bearer token.
* **The refresh token** is key-bound, so a stolen one is useless without the device's private key, which never leaves the device.

The current credential is a device-bootstrapped guest identity; passkey and social sign-in are planned. Applications authenticate separately, server to server, with their own credential that never reaches a game client.

Requests travel over HTTPS. Which entry path a client uses, and what it is allowed to reach, follows from the app's trust level rather than from what the client asserts, which is what keeps a client to its own access. The full flow and its exceptions are in [Authentication](/evaluate-and-integrate/authentication.md).

## What a reviewer gets, and when

The model above is public because it is structural. Deployment specifics, hosting, monitoring, data handling, retention, and recovery, are reviewed with the team as part of partner onboarding, covered in [Trust and due diligence](/architecture-and-trust/trust-and-due-diligence.md). To report a suspected vulnerability, follow [SECURITY.md](/architecture-and-trust/security.md).
