---
title: "Security model"
description: "A web app's or game's code runs on your users' machines, and anyone can read and modify it."
url: "/docs/security/"
lang: en
index: "/llms.txt"
---
# Security model

A web app's or game's code runs on your users' machines, and anyone can read and modify it. KUMODeck is designed around that
fact: **the browser is trusted with nothing it could abuse.**

## Never ship a secret key

| | Publishable `pk_…` | Secret `sk_…` |
|---|---|---|
| Safe in the browser / public repo | **yes** | **never** |
| Sign users (players) in, read/write *their own* data | yes | — |
| Push config, deploy, read any player | no | yes |

The SDK throws if you pass it an `sk_` key. Keep secret keys in your CI secrets or your own server's environment
variables. If one leaks, create a new key in the dashboard, update CI, and revoke the old key — revocation is
immediate. Keys are stored as hashes; a lost key cannot be recovered, only replaced.

## Development and production are isolated

Players, data, rooms are separate per environment, and every key belongs to exactly one
environment. A `pk_dev_` key cannot touch production data, and a leaked dev key
exposes no real users.

## What a modified client can and cannot do

| A cheater can… | …but cannot |
|---|---|
| write their own cloud save | read or write another player's save (so keep anything valuable out of saves) |
| send room messages | exceed 30 msg/s, read another environment's rooms, or keep a connection after a ban |

**Design rule:** put anything valuable behind a server-side decision — your own [Functions](/docs/guides/functions/index.md) —
never behind a client-side `if`. For competitive multiplayer, make the host authoritative, or run the match logic in
your own Functions.
Stats can be checked on the server before they count: value ranges, a
submission rate and a signed webhook to your own server (`integrity.stats`, see the [config reference](/docs/reference/config/index.md#integrity)).

## Players

- Access tokens (JWT, 15 min) are verified without a database round-trip; refresh tokens (90 days) rotate on every use
  and a replayed token revokes the whole chain.
- Passwords are hashed with a memory-hard KDF; login errors do not reveal whether an email exists.
- Other users' data is invisible: requests for resources you don't own return 404.

## Hosting

Apps and games are served from a **separate registrable domain** (`<slug>.kumodeck.app`), one subdomain per project. A
project's JavaScript therefore cannot read the dashboard's session or another project's `localStorage`. Development deployments
are marked `noindex`.

## Functions

Your server code runs isolated from other creators' code and from KUMODeck itself. Each environment gets its own
database, KV, files and queues; your code can reach only the resources bound to it, and KUMODeck's own systems only
through the secret key issued for that environment. Secret values go straight to the runtime and are never stored by
KUMODeck. Raw TCP sockets are blocked, and per-request CPU and subrequest limits apply.

## Your developer account

- Log in with an email and password, or with Google or GitHub. The buttons appear in the dashboard only for the
  providers the server operator has turned on. From a terminal, `kumodeck login --google` (or `--github`)
  opens your browser and waits on a local `127.0.0.1` port with PKCE, like `gh` and `gcloud`; there is no code to
  type on another device.
- KUMODeck never connects a Google or GitHub account to an existing account just because the email address
  matches: a "verified" email at a provider does not prove who owns that address today. If an account with that email
  already exists, log in the usual way first, then add the provider under **Account → Sign-in methods** in the dashboard.
- Adding or removing a sign-in method, setting a password and closing the account first ask you to confirm it is you —
  with your password, or by signing in with a provider you already added. Removing a method or setting / changing the
  password signs out your other devices and connected tools (CLI and MCP).
   The last way to sign in cannot be removed.

## AI agents and other MCP clients

Assistants act with the scopes and projects you choose on the consent screen. Changes to production, bans and deletions
need your confirmation even when the assistant auto-approves tools
. See [Use from an AI agent](/docs/claude-code/index.md#safety).

## Reporting a vulnerability

Please report security issues privately to the maintainers rather than in a public issue.
