Skip to content

fix(agent-core): make auth token module browser-import-safe#18

Merged
AtelyPham merged 1 commit into
mainfrom
tin/agent-core-browser-safe-auth
Jul 1, 2026
Merged

fix(agent-core): make auth token module browser-import-safe#18
AtelyPham merged 1 commit into
mainfrom
tin/agent-core-browser-safe-auth

Conversation

@AtelyPham

Copy link
Copy Markdown
Contributor

Problem

@tangle-network/agent-core's root (src/index.ts) re-exports the auth token runtime from ./auth/index.js. That module referenced Buffer at module-eval time:

const JWT_HEADER       = base64UrlEncode(JSON.stringify({alg:"HS256",typ:"JWT"}))  // top-level, Buffer.from
const JWT_HEADER_EDDSA = base64UrlEncode(JSON.stringify({alg:"EdDSA",typ:"JWT"}))  // top-level, Buffer.from

and statically imported node:crypto. So any browser bundle that transitively imports agent-core — e.g. platform-web → … → @tangle-network/sdk-telemetry → @tangle-network/agent-core (root) — boot-crashed with ReferenceError: Buffer is not defined (React never mounts, blank SPA). This is the agent-core sibling of the @tangle-network/sandbox fix (tangle-network/agent-dev-container#2991).

Fix (server signing stays synchronous; only importing is now browser-safe)

  1. Isomorphic base64urlbtoa/atob + TextEncoder/TextDecoder instead of Buffer (works in Node and browsers).
  2. Lazy JWT headers — HS256 + EdDSA headers computed on first use and memoized, not at module load.
  3. Lazy node:crypto — HMAC, Ed25519 sign/verify, generateKeyPairSync, randomBytes, timingSafeEqual resolve via process.getBuiltinModule("node:crypto") (Node ≥ 22.3; server-only). In a browser globalThis.process is undefined, so a stray call fails loud with a clear server-only error instead of crashing at import.

Token wire format is byte-identical — already-issued tokens still verify. ./auth/browser and tokens-browser.ts are unchanged.

Validation

  • pnpm --filter @tangle-network/agent-core test418 pass (17 files), incl. a new tests/auth/browser-safety.test.ts exercising HMAC read-tokens, Ed25519 sidecar tokens, and API-key hashing with globalThis.Buffer deleted.
  • check-types clean · tsdown build clean · built dist/auth/index.js has 0 top-level Buffer, 0 eager node:crypto imports.
  • End-to-end: packed this build, forced it into platform-web (agent-dev-container), removed the Buffer polyfill, rebuilt, and headless-loaded the SPA (dev-browser) → React mounts, sign-in page renders, 0 console errors, no "Buffer is not defined". (Before this fix, the same headless test still crashed on agent-core.)

Downstream

Unblocks reverting the platform-web Buffer polyfill (agent-dev-container #2987 / #2991): once this releases as @tangle-network/agent-core@0.4.1, the adc override bumps 0.4.0 → 0.4.1 alongside the tcloud@0.4.14 bump, and the polyfill can be removed.

`@tangle-network/agent-core`'s root re-exports the auth token module, so it
lands in browser bundles transitively (e.g. via `@tangle-network/sdk-telemetry`).
It referenced `Buffer` at module-eval time (top-level `JWT_HEADER` /
`JWT_HEADER_EDDSA`) and statically imported `node:crypto`, so any consuming SPA
boot-crashed with `ReferenceError: Buffer is not defined`.

- base64url encode/decode is now isomorphic (`btoa`/`atob` + `TextEncoder`/
  `TextDecoder`), never `Buffer`
- the HS256 and EdDSA JWT headers are computed lazily on first use
- HMAC/Ed25519 signing, verification, and key generation resolve `node:crypto`
  on demand via `process.getBuiltinModule` (server-only)

Token wire format is unchanged; 418 tests pass incl. a new browser-import-safety
suite. Server-only signing/verification stay synchronous.
@AtelyPham AtelyPham self-assigned this Jul 1, 2026
@AtelyPham AtelyPham merged commit 077b3d4 into main Jul 1, 2026
1 check passed
@AtelyPham AtelyPham deleted the tin/agent-core-browser-safe-auth branch July 2, 2026 05:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant