Skip to content

(janitor/dedupe): consolidate Kilo v3 token signing onto signKiloToken - #5633

Merged
pandemicsyn merged 2 commits into
mainfrom
janitor/dedupe-kilo-token-signing
Aug 28, 2026
Merged

(janitor/dedupe): consolidate Kilo v3 token signing onto signKiloToken#5633
pandemicsyn merged 2 commits into
mainfrom
janitor/dedupe-kilo-token-signing

Conversation

@kilo-code-bot

@kilo-code-bot kilo-code-bot Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Summary

webhook-agent-ingest, security-auto-analysis, and gastown each hand-rolled
their own HS256 "Kilo user token v3" JWT signer instead of using the canonical
signKiloToken() already exported from @kilocode/worker-utils:

  • services/webhook-agent-ingest/src/util/jwt.ts — a hand-rolled base64url +
    Web Crypto HMAC-SHA256 signer, used only by token-minting-service.ts.
  • services/security-auto-analysis/src/token.ts — a near byte-identical
    hand-rolled implementation of the same base64url/HMAC signer.
  • services/gastown/src/util/kilo-token.util.ts — a third variant calling
    jose's SignJWT directly.

All three produce the same "Kilo user token v3" shape (kiloUserId,
apiTokenPepper, version: 3, plus optional extras like botId /
internalApiUse / createdOnPlatform) that signKiloToken() in
packages/worker-utils/src/kilo-token.ts already owns, and all three services
already depend on @kilocode/worker-utils and run in the same Cloudflare
Workers runtime as the canonical implementation — no cross-runtime coupling.

Today a bug fix, claim change, or hardening applied to the canonical
implementation would silently not propagate to these three independent
copies of the same security-sensitive signing logic.

Changes

  • webhook-agent-ingest: delete util/jwt.ts entirely;
    token-minting-service.ts now calls signKiloToken.
  • security-auto-analysis: delete the local signJwt /
    parseExpiresIn / hmacSha256 / base64url helpers from token.ts;
    generateApiToken and generateInternalServiceToken now delegate to
    signKiloToken.
  • gastown: kilo-token.util.ts's generateKiloApiToken now delegates to
    signKiloToken instead of calling jose's SignJWT directly.
  • worker-utils: made signKiloToken's pepper param optional. Omitting
    it produces a token with no apiTokenPepper claim at all, matching the
    "internal service token" contract already documented and relied on by
    verifyKiloBearerAgainstCurrentPepper (an explicit null pepper is
    compared against the account's current pepper; an absent claim skips
    that check). This preserves generateInternalServiceToken's original
    behavior — it never included the claim — and is a purely additive,
    backward-compatible change (every other caller still passes a pepper
    explicitly). Added a regression test covering this in
    kilo-token.test.ts.

No behavior change for any other call site: they already always included
apiTokenPepper (string or null).

Verification

  • pnpm --filter @kilocode/worker-utils typecheck / test — 28 files, 356
    tests passed (including a new test asserting the omitted-pepper claim
    behavior).
  • pnpm --filter cloudflare-webhook-agent-ingest typecheck / test — 10
    files, 89 tests passed.
  • pnpm --filter cloudflare-security-auto-analysis typecheck / test — 16
    files, 180 tests passed.
  • pnpm --filter cloudflare-gastown typecheck / test — 22 files, 316 tests
    passed.
  • oxlint / oxfmt on all changed files — clean.

Shared PostgreSQL/Redis were not started for this change; none of the touched
tests require them (pure unit-level JWT signing/verification).

webhook-agent-ingest, security-auto-analysis, and gastown each
hand-rolled their own HS256 "Kilo user token v3" JWT signer (two of
them near byte-identical Web Crypto implementations, one a direct
jose SignJWT call), duplicating the same domain concept already
owned by signKiloToken() in @kilocode/worker-utils. All three
services already depend on @kilocode/worker-utils and run in the
same Cloudflare Workers runtime as the canonical implementation, so
this is a drop-in replacement:

- webhook-agent-ingest: delete util/jwt.ts (hand-rolled base64url +
  HMAC-SHA256 signer); token-minting-service now calls signKiloToken.
- security-auto-analysis: delete the local signJwt/parseExpiresIn/
  hmacSha256 helpers from token.ts; generateApiToken and
  generateInternalServiceToken now delegate to signKiloToken.
- gastown: kilo-token.util.ts's generateKiloApiToken now delegates to
  signKiloToken instead of calling jose's SignJWT directly.

signKiloToken's `pepper` param is now optional: omitting it produces
a token with no apiTokenPepper claim at all, matching the existing
"internal service token" contract already documented and relied on
by verifyKiloBearerAgainstCurrentPepper (an explicit `null` pepper is
compared against the account's pepper; an absent claim skips that
check). This preserves generateInternalServiceToken's original
behavior, which never included the claim.

No behavior change for the other call sites, which already always
included apiTokenPepper (as a string or null).
@kilo-code-bot kilo-code-bot Bot added the janitor Automated dead-code/duplication cleanup label Aug 28, 2026
@kilo-code-bot

kilo-code-bot Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor Author

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (2 files)
  • packages/worker-utils/src/kilo-token.ts
  • packages/worker-utils/src/kilo-token.test.ts
Previous Review Summary (commit dc28df9)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit dc28df9)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (6 files)
  • packages/worker-utils/src/kilo-token.ts
  • packages/worker-utils/src/kilo-token.test.ts
  • services/gastown/src/util/kilo-token.util.ts
  • services/security-auto-analysis/src/token.ts
  • services/webhook-agent-ingest/src/services/token-minting-service.ts
  • services/webhook-agent-ingest/src/util/jwt.ts

Reviewed by grok-4.6 · Input: 37.9K · Output: 5.8K · Cached: 189.2K

Review guidance: REVIEW.md from base branch main

Per review: the deleted webhook-agent-ingest hand-rolled signer always
included typ: 'JWT' in its header, so signKiloToken should keep doing
the same to preserve byte-level header compatibility with that migrated
issuer and to make all signKiloToken outputs consistently self-identify
as JWTs. verifyKiloToken does not (and did not) constrain typ, so this
is purely additive and doesn't change verification behavior for any
consumer. Added a test asserting the protected header shape.
@pandemicsyn
pandemicsyn merged commit 82c944c into main Aug 28, 2026
44 checks passed
@pandemicsyn
pandemicsyn deleted the janitor/dedupe-kilo-token-signing branch August 28, 2026 20:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

janitor Automated dead-code/duplication cleanup

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants