Skip to content

perf(oidc): avoid reparsing verified access tokens - #3530

Open
zerox80 wants to merge 1 commit into
opencloud-eu:mainfrom
zerox80:codex/oidc-token-claim-extraction
Open

zerox80 wants to merge 1 commit into
opencloud-eu:mainfrom
zerox80:codex/oidc-token-claim-extraction

Conversation

@zerox80

@zerox80 zerox80 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Description

VerifyAccessToken currently parses the JWT again with ParseUnverified after signature and claim validation, just to collect the arbitrary claims. This change decodes the payload directly at that point, avoiding another parse of the header and signature.

Signature and registered-claim validation still happen first. The added tests cover nested claims, numeric claim types, malformed JSON numbers, a null payload, and rejection of invalid signatures, issuers, expired tokens and tokens used before nbf.

This is the performance change split out of #3466 as requested in review. It is based on main and can be reviewed and merged independently of the audience validation changes.

Related Issue

Motivation and Context

The second parser call repeats work for every verified JWT access token. Decoding only its payload reduces allocations while keeping the existing map-claim behavior and error wrapping.

How Has This Been Tested?

Ubuntu WSL, Go 1.25.9, linux/amd64, vendored dependencies.

  • Ran the new claim-extraction tests against the unchanged implementation on main (a065c9ee19) first. They pass there too.
  • go test -mod=vendor -race -count=1 ./pkg/oidc/... ./services/proxy/... passed for this branch and for feat(proxy): add optional OIDC access token audience validation #3466 with the performance commit removed.
  • The changed-lines golangci-lint check for ./pkg/oidc/... passed with no new findings.
  • Checked that this branch and the updated audience branch merge without conflicts.

Added BenchmarkVerifyAccessTokenClaims, which measures full RS256 access-token verification and map-claim extraction using a local RSA-2048 key and JWKS. It makes no network requests.

Fresh measurements after closing unnecessary applications, using the same benchmark for both versions: six alternating 2-second samples per version, one CPU, Intel Core Ultra 7 155U. The baseline is main at a065c9ee19 plus the new test file.

Metric Before After
Median time 75,183 ns/op 70,230 ns/op
Memory 7,128 B/op 6,040 B/op
Allocations 124 allocs/op 103 allocs/op

That is 1,088 fewer bytes and 21 fewer allocations per verification. The time median is about 6.6% lower, but individual samples varied substantially (before: 70.8–100.0 µs, after: 67.3–110.7 µs). The allocation reduction is consistent; these timings are a local microbenchmark, not an end-to-end proxy throughput result.

To run the benchmark:

go test -mod=vendor -run '^$' -bench '^BenchmarkVerifyAccessTokenClaims$' -benchmem -cpu=1 -benchtime=2s -count=6 ./pkg/oidc

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Technical debt
  • Tests only (no source changes)

Checklist

  • Code changes
  • Unit tests added
  • Acceptance tests added
  • Documentation added

Assisted-By: LLM, GPT 6 Astra

Decode the verified JWT payload directly when extracting map claims. Add regression tests and a standalone RSA-2048 verification benchmark.

Assisted-By: LLM, GPT 6 Astra
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 12 complexity

Metric Results
Complexity 12

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

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