Skip to content

Downgrade jwt_reparse from alert to debug log#11759

Merged
iain-macdonald merged 2 commits into
masterfrom
iain/downgrade-jwt-reparse-alert
Apr 2, 2026
Merged

Downgrade jwt_reparse from alert to debug log#11759
iain-macdonald merged 2 commits into
masterfrom
iain/downgrade-jwt-reparse-alert

Conversation

@iain-macdonald

@iain-macdonald iain-macdonald commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

The jwt_reparse alert.UnexpectedEvent added in #11754 fires on the normal cloud executor authentication path — it's not an actual unexpected reparse, it's the initial (and only) parse of the JWT for every task execution.

The call flow:

  1. priority_task_scheduler.go:585 — sets only the raw ES256-signed JWT string in the context
  2. executor.go:200 — calls interceptors.AddAuthToContext
  3. interceptors.go:96 — calls AuthenticatedGRPCContext
  4. oidc.go:558 — calls authenticateGRPCRequest(ctx, true)
  5. oidc.go:501-543 — peer certs, SSL headers, API keys, basic auth, authority all miss (local context, no gRPC metadata)
  6. oidc.go:547 — falls through to claims.ClaimsFromContext(ctx)
  7. claims.go:490 — no cached claims (nobody parsed the JWT yet)
  8. claims.go:497 — no auth error (first auth attempt)
  9. claims.go:498 — finds the JWT string
  10. claims.go:503 — fires jwt_reparse alert (misleading — this is the first parse)
  11. claims.go:504 — calls parseClaims with DefaultKeyProvider (no LRU cache)
  12. claims.go:590-591 — tries HS256 key first, fails
  13. claims.go:594-595 — tries ES256 key, expensive elliptic curve verification succeeds
  14. oidc.go:560AuthContextWithJWT re-assembles a new HS256 JWT from the claims and caches both in context

This downgrades the alert back to the rate-limited debug log it was
before #11754.

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings April 1, 2026 03:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adjusts JWT parsing instrumentation in ClaimsFromContext to avoid emitting a monitoring alert on the normal cloud executor authentication path, while still retaining a low-noise diagnostic signal.

Changes:

  • Replace alert.CtxUnexpectedEvent(ctx, "jwt_reparse", ...) with a rate-limited debug log.
  • Introduce a named, rate-limited sub-logger (reparseLog) to cap log volume (once per minute).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread server/util/claims/claims.go Outdated
@iain-macdonald iain-macdonald force-pushed the iain/downgrade-jwt-reparse-alert branch from 228b83a to be6cfad Compare April 1, 2026 03:43
iain-macdonald and others added 2 commits April 2, 2026 08:44
The jwt_reparse alert fires on the normal executor authentication path,
not on an actual unexpected reparse. This is the initial (and only) parse
of the JWT for every task execution on cloud executors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@iain-macdonald iain-macdonald force-pushed the iain/downgrade-jwt-reparse-alert branch from be6cfad to f84a090 Compare April 2, 2026 15:49
@iain-macdonald iain-macdonald merged commit e443a17 into master Apr 2, 2026
9 of 12 checks passed
@iain-macdonald iain-macdonald deleted the iain/downgrade-jwt-reparse-alert branch April 2, 2026 15:56
iain-macdonald added a commit that referenced this pull request Apr 2, 2026
The `jwt_reparse` `alert.UnexpectedEvent` added in #11754 fires on the
normal cloud executor authentication path — it's not an actual
unexpected reparse, it's the initial (and only) parse of the JWT for
every task execution.

The call flow:

1. `priority_task_scheduler.go:585` — sets only the raw ES256-signed JWT
string in the context
2. `executor.go:200` — calls `interceptors.AddAuthToContext`
3. `interceptors.go:96` — calls `AuthenticatedGRPCContext`
4. `oidc.go:558` — calls `authenticateGRPCRequest(ctx, true)`
5. `oidc.go:501-543` — peer certs, SSL headers, API keys, basic auth,
authority all miss (local context, no gRPC metadata)
6. `oidc.go:547` — falls through to `claims.ClaimsFromContext(ctx)`
7. `claims.go:490` — no cached claims (nobody parsed the JWT yet)
8. `claims.go:497` — no auth error (first auth attempt)
9. `claims.go:498` — finds the JWT string
10. `claims.go:503` — fires `jwt_reparse` alert (misleading — this is
the first parse)
11. `claims.go:504` — calls `parseClaims` with `DefaultKeyProvider` (no
LRU cache)
12. `claims.go:590-591` — tries HS256 key first, fails
13. `claims.go:594-595` — tries ES256 key, expensive elliptic curve
verification succeeds
14. `oidc.go:560` — `AuthContextWithJWT` re-assembles a new HS256 JWT
from the claims and caches both in context

This downgrades the alert back to the rate-limited debug log it was
before #11754.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
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.

3 participants