Skip to content

fix(agent-bridge): make the regenerate-cert endpoint actually mint a new cert (#10467) - #10715

Merged
diegosouzapw merged 1 commit into
diegosouzapw:release/v3.8.50from
ntdatt812:fix/10467-regenerate-cert-force
Aug 20, 2026
Merged

diegosouzapw merged 1 commit into
diegosouzapw:release/v3.8.50from
ntdatt812:fix/10467-regenerate-cert-force

Conversation

@ntdatt812

Copy link
Copy Markdown
Contributor

Summary

Fixes #10467 — "Regenerate Cert does not regenerate the cert".

POST /api/tools/agent-bridge/cert/regenerate called generateCert() with no arguments, and generateCert() short-circuits whenever both files already exist:

if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
  console.log("✅ SSL certificate already exists");
  return { key: keyPath, cert: certPath };
}

So on any machine that had already started the bridge the endpoint was a no-op. It still answered { ok: true } with the two paths, which is why the UI reported success while /cert/download kept serving the identical file — matching the reporter's observation that the md5 never changed and the SANs added in #6494 never appeared.

The route's own comment documented this as intentional ("the function is idempotent … If a caller needs a fresh cert they must delete the old one manually"), but that leaves the regenerate button with nothing to do, and there is no other UI path to delete the cert.

Change

generateCert takes an opt-in { force }, and the regenerate route is the one caller that passes it.

The other three callers only need a certificate to exist — src/app/api/settings/mitm/route.ts, src/app/api/tools/agent-bridge/server/route.ts and src/mitm/manager.ts — so they keep the existing short-circuit and are untouched. Nothing regenerates a cert that used to be reused.

Tests

New file tests/unit/agent-bridge-cert-regenerate-force-10467.test.ts, 4 cases, node:test to match the sibling agent-bridge-cert-* tests. Each case runs against its own temp DATA_DIR, so no test touches the real cert store.

Case Asserts
generateCert() with a cert on disk file contents unchanged — the reuse path is preserved
generateCert({ force: true }) with a cert on disk both cert and key contents differ — the actual fix
forced cert is well-formed parses as X509Certificate and carries a SAN for every ANTIGRAVITY_TARGET.hosts entry, so a forced cert can't silently regress #6494
generateCert({ force: true }) with nothing on disk still creates both files

The suite pins the bug rather than describing the fix — against the unpatched generate.ts, exactly the one case that targets it fails:

ℹ tests 4
ℹ pass 3
ℹ fail 1
  AssertionError [ERR_ASSERTION]: certificate should be replaced

With the patch: pass 4, fail 0.

Commands run

node --import tsx/esm --import ./open-sse/utils/setupPolyfill.ts \
     --import ./tests/_setup/isolateDataDir.ts --test --test-force-exit \
     tests/unit/agent-bridge-cert-regenerate-force-10467.test.ts
  → tests 4, pass 4, fail 0

# regression over every cert/mitm unit test, same machine
tests/unit/*cert*.test.ts + tests/unit/*mitm*.test.ts
  before: tests 311, pass 300, fail 10
  after:  tests 315, pass 304, fail 10   (+4 tests, +4 pass, same 10 failures)

npx eslint <the 3 changed files>   → clean
npm run typecheck:core             → clean
npm run check:test-discovery       → OK
npm run check:route-validation:t06 → PASS
npm run check:test-runner-api      → OK

The 10 pre-existing failures in that set are environment-bound, not related to this change — they assert POSIX behaviour (chmod 0644 after cp, umask 0077, /etc/hosts writes, sudo fallback) plus two Windows cert-store lookups. The set is identical before and after; only the 4 new tests moved the counts.

I could not run npm run test:coverage end to end on this machine — the full runner needs far more than a Windows dev box will finish in reasonable time. The changed production lines are covered by the new tests: the force branch and the preserved reuse branch are each asserted directly, and the route's single changed line is the call site.

Changed files

  • src/mitm/cert/generate.ts — { force } option
  • src/app/api/tools/agent-bridge/cert/regenerate/route.ts — pass { force: true }
  • tests/unit/agent-bridge-cert-regenerate-force-10467.test.ts — new

…new cert (diegosouzapw#10467)

POST /api/tools/agent-bridge/cert/regenerate called generateCert() with no
arguments. generateCert() returns the existing paths untouched whenever
server.key and server.crt are both on disk, so on any machine that had
already started the bridge the endpoint was a no-op: the button reported
success, the download route kept serving the old file with the same md5,
and a cert predating diegosouzapw#6494 could never be replaced from the UI.

Give generateCert an opt-in { force } and have the regenerate route pass
it. Every other caller — the MITM settings route, the bridge server route
and the manager — only needs a cert to exist, so they keep the existing
short-circuit and are unchanged.

Fixes diegosouzapw#10467
@diegosouzapw
diegosouzapw merged commit b11b000 into diegosouzapw:release/v3.8.50 Aug 20, 2026
3 checks passed
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…new cert (diegosouzapw#10467) (diegosouzapw#10715)

Merged via merge-train (release/v3.8.50, batch1 2026-08-20) — static gates (typecheck/file-size/complexity/cognitive/changelog) green on the combined tree; test:unit reds observed in the boarded run were verified pre-existing on the pure release tip (unrelated flake), not caused by this PR. Thanks for the contribution!
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.

[BUG] AgentBridge: Regenerate Cert does not regenerate the cert

2 participants