Skip to main content

max / makenotwork

1.3 KB · 25 lines History Blame Raw
1 -- Separate credential for the server-to-server SDK key endpoints.
2 --
3 -- `sync_apps.api_key` reaches every client: the apps compile it in with
4 -- `include_str!`, so it ships inside each binary and `strings` recovers it.
5 -- That is fine for what it is -- a public client identifier -- but
6 -- `/api/sync/keys/{claim,release,list}` authenticated on that value alone.
7 -- Anyone with a shipped binary could therefore consume the app's key cap
8 -- under `per_key` billing and pollute claim attribution.
9 --
10 -- The keys endpoints get their own secret instead: generated in the
11 -- dashboard, shown once, held only by a developer backend, never compiled
12 -- into a client. Stored SHA-256 hashed like the api_key, with a prefix kept
13 -- for display.
14 --
15 -- Nullable, and no backfill: an app without a secret cannot call the keys
16 -- endpoints at all. Deriving one from the api_key would carry the same
17 -- weakness forward, and no first-party client calls these routes today.
18 ALTER TABLE sync_apps ADD COLUMN IF NOT EXISTS keys_secret_hash TEXT;
19 ALTER TABLE sync_apps ADD COLUMN IF NOT EXISTS keys_secret_prefix TEXT;
20
21 -- Lookup path for the keys endpoints. Partial: most apps never set one.
22 CREATE UNIQUE INDEX IF NOT EXISTS sync_apps_keys_secret_hash_idx
23 ON sync_apps (keys_secret_hash)
24 WHERE keys_secret_hash IS NOT NULL;
25