Identity & app keys
There are two kinds of “identity” in Muhkoo, and they answer different questions.
User identity (zero-knowledge)
Section titled “User identity (zero-knowledge)”A user’s identity is derived on their device from (username, password):
seed = PBKDF2(password, "muhkoo-zk-v1:" + username)secret = HKDF(seed, "zk-secret")salt = HKDF(seed, "zk-salt")…plus deterministic ECDSA + ECDH keypairscommitment = Poseidon(secret, salt, Poseidon(ecdsaPub))The accelerator only ever stores the commitment — a one-way Poseidon hash.
At login the client proves, in zero knowledge (a Groth16 proof over the
preimagePoK circuit), that it knows a (secret, salt, …) matching the stored
commitment, without revealing any of it.
Consequences:
- No passwords or secrets on the server. Ever.
- Federated login. The same
(username, password)reproduces the same identity (and commitment) on any device — no key material to sync or escrow. - The commitment is the user’s stable id — it’s what
user.commitmentreturns and how per-user data is addressed.
App keys
Section titled “App keys”Your app authenticates to the accelerator with an app key. Keys look like:
mk_<env>_<type>_<32 hex> │ │ │ └ sk = secret key (server-side) pk = publishable key (browser-safe) └ live | testpk(publishable) — safe to ship in client bundles. Use this innew Client({ apiKey })for browser apps.sk(secret) — server-side only. Never put it in a browser bundle or any client-exposed env var.testvslive— separate environments. Test keys exercise the full stack without touching live billing/usage.
Keys are issued per app from the developer portal
(or POST /api/apps). They’re per-deployment — a key minted against one
accelerator (e.g. staging) won’t resolve on another (e.g. production).
What the app key gates
Section titled “What the app key gates”- Billing + metering — usage is attributed to the app behind the key.
- Messaging — shared-space (space/DM) websockets are authorized with a short-lived ticket derived from the app key.
How they combine
Section titled “How they combine”A request carries the app key (which app) and, once a user signs in, the session token (which user). Authorization is the intersection: this app, acting for this user. CORS is wildcard because the API is public and multi-tenant — security rides on the keys, not the origin.