-
Notifications
You must be signed in to change notification settings - Fork 2
Core Concepts
ggscale has a small set of nouns. Once you see how they fit, the rest of the API reads naturally.
A tenant is the isolation boundary. It usually maps to one studio, customer, or game brand. Every other record belongs to exactly one tenant, including projects, API keys, player accounts, saves, and leaderboards. No tenant can read another tenant's data. Postgres Row-Level Security enforces that in the database, underneath the application code, so a missed filter in a handler still cannot leak across tenants.
The dashboard shows a tenant as "Account Tenant".
A project is a partition inside a tenant. Most studios run one project per game, and often one per environment, for example arcade-prod and arcade-staging. Splitting projects keeps live and test data apart while both roll up to a single tenant for admin and billing.
The dashboard shows a project as "Game Project".
A player is one person who plays your game, identified inside a single project. Players sign up, log in, and store data through the /v1/auth/* endpoints. Your game makes those calls on the player's behalf using the tenant's API key, so players never touch the control panel.
A global player account can link a player's identities across several of your games, which lets one person keep a stable identity between titles.
An API key is how your game authenticates to ggscale. It is always scoped to a tenant, and it can be pinned to a single project. The key is generated once and stored as a hash, so copy it when you create it and treat it as a secret. If it leaks, revoke it and issue a new one.
Send it on every player-facing request:
Authorization: Bearer <api_key>
A key also carries scopes that limit what it can do, which keeps each key restricted to what it needs. A normal client key covers auth, saves, leaderboards, and social calls. Wider actions need a wider scope. Allocating a dedicated game server, for instance, needs a fleet-scoped key together with the dedicated_servers entitlement. Give each client the narrowest key that covers its job.
When a player authenticates, ggscale returns an access_token. This is the session token, a short-lived JWT that identifies the signed-in player. Send it alongside the API key on any call that acts for a player:
X-Session-Token: <access_token>
The auth response also carries a refresh_token. When the access token expires, exchange the refresh token at POST /v1/auth/refresh for a fresh pair instead of making the player log in again.
your game ──► ggscale HTTP API
│
├─ Authorization: Bearer <api_key> → a Tenant (and maybe a Project)
└─ X-Session-Token: <access_token> → a Player in that tenant
│
▼
Postgres (Row-Level Security)
Only rows for that tenant are visible.
The API key answers which game is calling and the session token answers which player, while the database makes sure nothing crosses a tenant line even when a handler forgets to filter.
A control panel user is a human operator, not a player. Operators log in to the control panel to manage tenants, projects, and keys. Each one holds a tenant membership with an owner, admin, or member role. Owners and admins can make changes; members have read-only access. The person who creates a tenant is its owner.