Skip to content

auth: add ClockSkew option to RequireBearerTokenOptions#969

Open
BorisTyshkevich wants to merge 1 commit into
modelcontextprotocol:mainfrom
Altinity:auth-clock-skew-option
Open

auth: add ClockSkew option to RequireBearerTokenOptions#969
BorisTyshkevich wants to merge 1 commit into
modelcontextprotocol:mainfrom
Altinity:auth-clock-skew-option

Conversation

@BorisTyshkevich
Copy link
Copy Markdown

Summary

  • Add a `ClockSkew time.Duration` field to `RequireBearerTokenOptions` that bounds the tolerance applied to a token's `Expiration` when checking elapsed validity.
  • Default zero preserves the existing strict comparison; positive values let resource servers tolerate the drift typical of distributed deployments and cloud-managed IdPs.

Motivation

Real-world resource servers running behind a CDN, in distributed deployments, or talking to an authorization server whose clock drifts a few seconds (common with cloud-managed IdPs) need a small positive tolerance when checking token expiration. Strict-equality comparison rejects tokens that are valid by the issuer's clock but momentarily appear expired by the verifier's. The reverse case — an issuer's clock running slightly fast at /token issuance — also reaches the verifier as a token whose `exp` lies microseconds in the past.

Test plan

  • `go test ./auth/...` passes.
  • New `TestRequireBearerToken_ClockSkew` exercises four cases: fresh accept, strict-expired reject, within-skew accept, beyond-skew reject.
  • Existing `TestRequireBearerToken` continues to pass with `ClockSkew` defaulting to zero.

Resource servers running behind a CDN, in distributed deployments, or
communicating with an authorization server whose clock drifts a few
seconds need a small positive tolerance when checking token expiration.
The default zero value preserves the existing strict comparison.

Adds a ClockSkew time.Duration field to RequireBearerTokenOptions plus
a TestRequireBearerToken_ClockSkew test covering the four meaningful
combinations (fresh accept, strict-expired reject, within-skew accept,
beyond-skew reject).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread auth/auth.go
Comment on lines +149 to +153
skew := time.Duration(0)
if opts != nil {
skew = opts.ClockSkew
}
if tokenInfo.Expiration.Add(skew).Before(time.Now()) {
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.

Suggested change
skew := time.Duration(0)
if opts != nil {
skew = opts.ClockSkew
}
if tokenInfo.Expiration.Add(skew).Before(time.Now()) {
if opts == nil {
opts = &RequireBearerTokenOptions{}
}
if tokenInfo.Expiration.Add(opts.ClockSkew).Before(time.Now()) {

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.

2 participants