You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
plugin-auth: JWT plugin's EdDSA keygen breaks login on hosts without Ed25519 (WebContainer/StackBlitz) #3585
On any host whose WebCrypto lacks Ed25519, every authenticated request 500s as soon as the OIDC provider is enabled — which is the default whenever the MCP server is on. Reproduced on StackBlitz/WebContainer (Node 22.22.3) with @objectstack/* 16.1.0.
Symptom
Sign-in succeeds, then the first /api/v1/auth/get-session returns 500:
[Better Auth]: OperationError DOMException [OperationError]: The operation failed for an operation-specific reason
at Object.cfrgGenerateKey (builtins.js:74:3727)
at async SubtleCrypto.generateKey (builtins.js:90:10600) {
[cause]: TypeError: o.run is not a function
at Module.generateKeyPair (jose/dist/webapi/key/generate_key_pair.js:111:26)
at generateExportedKeyPair (better-auth/dist/plugins/jwt/utils.mjs:42:48)
at Module.createJwk (better-auth/dist/plugins/jwt/utils.mjs:61:58)
at resolveSigningKey (better-auth/dist/plugins/jwt/sign.mjs:76:26)
}
[AuthManager] better-auth returned error: 500
GET /api/v1/auth/jwks reproduces it with no credentials at all — that route generates the key pair on first use.
Root cause
plugin-auth registers better-auth's JWT plugin as jwt({ schema: buildJwtPluginSchema() }) — no jwks.keyPairConfig, so better-auth's default EdDSA (Ed25519) applies.
WebContainer's WebCrypto has no Ed25519, so cfrgGenerateKey throws.
The plugin's after hook on /get-session signs a set-auth-jwt header for every session, so the failure hits normal cookie login — not just OAuth clients.
It is on by default in a plain dev server: resolveOidcProviderEnabled(pluginConfig) falls back to isMcpServerEnabled(), which defaults to true.
So an app that never asked for OIDC still gets an unusable login on such a host, and the error message points at better-auth rather than at the algorithm choice.
Workaround
OS_OIDC_PROVIDER_ENABLED=false drops the plugin and login works (verified end to end: sign-in/email 200, get-session 200, jwks 404). Apps can't do better than this today because the algorithm isn't configurable through AuthPluginConfig.
Suggested fix
Any of, roughly in order of preference:
Pass an algorithm the host supports — e.g. probe crypto.subtle.generateKey({name:'Ed25519'}, …) once at startup and fall back to ES256 when it throws.
Expose jwks.keyPairConfig through AuthPluginConfig so an app can pin ES256/RS256.
At minimum, catch the keygen failure and degrade the OIDC provider (there is already getDegradedAuthFeatures) instead of 500ing the whole session path — plus an error that names Ed25519.
Activity
claude commentedon Aug 4, 2026
认领:PM 循环第 1 轮(identity 车道)
会话:
session_015W6nhsDrz6zWQc8je12a1t分支:
claude/issue-3585-jwt-eddsa-fallbackWorktree:
objectstack-issue-3585域:
domain:identity文件面:
packages/plugins/plugin-auth/**(预计auth-manager.ts、auth-schema-config.ts一带 + 测试 + changeset)。⛔packages/spec/**零改动 —— 若方案 2(把 keyPairConfig 暴露进AuthPluginConfig)要求改 spec 契约面,即触发 needs_decision 停下,不自行定契约形状Generated by Claude Code
claude commentedon Aug 4, 2026
PM 验收(第 1 轮,identity 车道):ACCEPT — PR #5044,CI 绿后转 ready 入队
复核逐条(对 GitHub 实况):
utils.mjs默认仍是{alg:'EdDSA',crv:'Ed25519'},jwt({schema})注册点仍在auth-manager.ts:2175—— 不是照 issue 快照施工。{name:'Ed25519'}描述符而非宿主嗅探;packages/spec/**零改动 ✓;文件面全部落plugin-auth✓(6 文件含 changeset)。resolveSigningKey会回退到getLatestKey()(不看算法),所以仅配keyPairConfig只救新部署 —— 存量sys_jwks里的 EdDSA 键仍会被选中并死在importJWK。dev 的解法:仅在无 Ed25519 的宿主上安装 better-auth 文档化的adapter.getJwks密钥环 seam,隐藏(不删除)导入不了的键,铸新 ES256 键收敛;正常宿主完全走原生读路径。行为变更边界清晰,行有回迁测试(宿主恢复 Ed25519 后 EdDSA 行复原)。auth-manager.jwt-eddsa-fallback.test.ts—— patch 的是 WebCrypto 本身而不是自家探针(探针 stub 会漏掉「选中了导不进的键」这条真实 500 路径),真管线跑通升级收敛全程。开发中试出的两个真 bug(裸undefined只把 500 上移一帧,因runAfterHooks无守卫读result.headers)已各自 pin 住。4 条上游 tripwire 钉住 better-auth 的默认算法/hook 形状/seam —— 升 rc.3+ 时会响。content/docs/全文零处宣称 EdDSA/Ed25519(反查 OIDC 正常命中),无文档因此过时。CI 目前 21 检 0 红、11 在跑;绿后转 ready 入合并队列,本单随 PR 关闭。
Generated by Claude Code
test(plugin-auth): pin the #3585 memory engine's delete to ObjectQL's…
fix(plugin-auth): choose a JWT signing algorithm the host supports (o…