Native HMAC apiSigner and signed infoRollup appKeys - #6183
Conversation
c8f9826 to
44a9d19
Compare
Apply strict-boolean, nullish, and return-type fixes in files leaving the relaxed-rules list.
Single-flight the initial load and serialize every write through a promise chain so overlapping patches cannot clobber each other or blank on-disk fields. Adds keysCache fields for remote key fetch.
Replace the flat env.json/ENV singleton with config.json + keys.json and runtime CONFIG, KEYS, globalKeys, and pluginMaps accessors. Partner secrets live nested under globalKeys.
Boot from baked-in KEYS, then overlay a signed infoRollup appKeys payload and device cache. Mutate KEYS and globalKeys in place and rebuild pluginMaps.
Print only LAYER-* overlay markers from the local info_keys seed, plus whether the native signer loaded, so device e2e can confirm remote key fetch without dumping secrets.
Plugins whose API keys are absent or malformed do not register with the core, which leaves them out of `currencyConfig` and `swapConfig`. Diff the plugin list we handed to `makeEdgeContext` against what the account came back with, and show the missing plugin IDs in an error drop-down so a misconfigured key surfaces instead of silently removing assets and exchanges from the app. Plugin loading happens once per core context, so this reports once per session rather than on every login. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
44a9d19 to
568056f
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Token-only API key ignored
- buildContextOptions now forwards a usable EDGE_API_KEY to MakeEdgeContext even when EDGE_API_SECRET is missing, so core can use legacy Token auth.
Or push these changes by commenting:
@cursor push 61a8982da7
Preview (61a8982da7)
diff --git a/src/components/services/EdgeCoreManager.tsx b/src/components/services/EdgeCoreManager.tsx
--- a/src/components/services/EdgeCoreManager.tsx
+++ b/src/components/services/EdgeCoreManager.tsx
@@ -123,10 +123,12 @@
const { EDGE_API_KEY: apiKey, EDGE_API_SECRET: apiSecret } = KEYS
const nativeKey = hasNativeApiSigner() ? await warmNativeApiKey() : ''
const nativeApiSigner = nativeKey !== '' ? makeNativeApiSigner() : undefined
- const jsPair =
- isUsableApiKey(apiKey) && apiSecret != null && apiSecret.byteLength > 0
+ // Token-only keys are valid: core uses `Authorization: Token {apiKey}`.
+ const jsPair = isUsableApiKey(apiKey)
+ ? apiSecret != null && apiSecret.byteLength > 0
? { apiKey, apiSecret }
- : undefined
+ : { apiKey }
+ : undefined
console.log(
`[apiSigner] native=${nativeApiSigner != null} keysFallback=${
jsPair != nullYou can send follow-ups to the cloud agent here.
Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 568056f. Configure here.
| return { | ||
| ...(nativeApiSigner != null | ||
| ? { apiSigner: nativeApiSigner } | ||
| : jsPair ?? {}), |
There was a problem hiding this comment.
Token-only API key ignored
Medium Severity
buildContextOptions only forwards JS credentials when both KEYS.EDGE_API_KEY and KEYS.EDGE_API_SECRET are present. An apiKey without a secret is dropped, so core never receives the legacy Token {apiKey} pair that HMAC_SIGNING.md still describes. The README also tells developers to set only EDGE_API_KEY in keys.json, which the native stub path then ignores.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 568056f. Configure here.



CHANGELOG
Does this branch warrant an entry to the CHANGELOG?
Dependencies
Requirements
If you have made any visual changes to the GUI. Make sure you have:
Description
Splits runtime
env.jsoninto non-secretconfig.jsonand secretkeys.json, with four plugin maps (corePlugins,swapPlugins,guiApiKeys,rampPlugins) plusglobalKeys. WalletConnect isglobalKeys.WALLETCONNECT_PROJECT_ID. Plugin maps are opaque objects (no field-by-field*_INIT/*_API_KEYflattening).Fetches remote secrets from signed
GET /v1/infoRollup/:appIdas siblingappKeys(partner idconfig.appId ?? 'edge'), with DeviceSettingsgetKeysCacheand baked-inkeys.jsonas fallbacks.pluginApiKeys.posthogis never served.Adds a native Edge API HMAC signer (
edgeKey.json+ XOR-split C shards) so login-server requests can be signed outside the JS bundle viaapiSigner, with JSKEYS.EDGE_API_*remaining as a fallback.Rebased onto current
develop(keeps Swapter and marketing-push tracking).Note
High Risk
Changes authentication (native HMAC + infoRollup signing), boot-time secret resolution, and how every plugin receives credentials—misconfiguration or timing bugs could break login, partner APIs, or silently pin stale keys.
Overview
Replaces the monolithic
env.json/ENVsetup withconfig.json(non-secret),keys.json(secrets), and build-onlyedgeKey.json, exposed at runtime asCONFIG,KEYS/globalKeys, and resolvedpluginMaps. Plugin configuration moves to four ID-keyed maps (corePlugins,swapPlugins,guiApiKeys,rampPlugins) instead of flat*_INITfields; deploy and local tooling now patchconfigJson/keysJsonper branch (legacyenvJsonis ignored here).Adds native Edge API HMAC signing on iOS and Android: build scripts XOR-shard the secret from
edgeKey.jsoninto generated C sources, exposeEdgeApiSignerto React Native, and wireapiSignerinto edge-core for login-server auth while keeping secrets out of the Metro bundle (JSKEYS.EDGE_API_*remains a fallback when the native module is absent).Adds signed remote plugin secrets via
GET /v1/infoRollup/:appIdappKeys, merged over baked-inkeys.jsonwith aDeviceSettingskeysCachetier and cold-start timeouts;EdgeCoreManagerwaits on key resolution before building plugins, and consumers that need rotatable secrets must read them lazily after overlay apply.Ships migration scripts (
split-env-json,split-baked-and-server-keys), expanded docs (CONFIG_KEYS_ARCHITECTURE.md,HMAC_SIGNING.md), and tests for merge semantics, HMAC vectors,keysServer, and serialized settings writes.Reviewed by Cursor Bugbot for commit 568056f. Bugbot is set up for automated code reviews on this repo. Configure here.