Skip to content

Navigation Menu

Sign in
Sign up

feat(jwt): add configurable time-tolerance for clock-skew tolerance - #336

Open
sweengineeringlabs wants to merge 1 commit into
zhaofengli:main from
sweengineeringlabs:feat/jwt-time-tolerance
Open

feat(jwt): add configurable time-tolerance for clock-skew tolerance #336
sweengineeringlabs wants to merge 1 commit into
zhaofengli:main from
sweengineeringlabs:feat/jwt-time-tolerance

Conversation

@sweengineeringlabs

@sweengineeringlabs sweengineeringlabs commented May 5, 2026
edited
Loading

Copy link
Copy Markdown

Problem

from_jwt is called with time_tolerance: None, meaning JWT verification rejects any token whose nbf claim is even one second in the server's future. In practice, the token issuer and atticd rarely share a perfectly synchronised clock:

  • A token minted inside WSL2 carries nbf = WSL2_time; atticd running in a microVM reads the host system clock. WSL2 can drift a few seconds from the Windows host clock.
  • Containers and VMs that sync their clock from a hypervisor source may lag or lead the host by a few seconds depending on when the sync last ran.
  • Any deployment where the CA / token-issuer host and the atticd host are on different NTP strata can see sub-minute skew.

RFC 7519 §4.1.5 explicitly acknowledges this:

"Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew."

Without a configurable leeway there is no standards-compliant way to handle this; operators are forced to either accept spurious 401s or patch the binary.

Change

Adds an optional time-tolerance field to the [jwt] section of server.toml:

[jwt]
time-tolerance = "30s" # accepts "30s", "2m", "1h", ...

Threads through three files:

  1. token/src/lib.rsfrom_jwt gains an Option<std::time::Duration> parameter; mapped to VerificationOptions instead of hardcoded None
  2. server/src/config.rsJWTConfig gains time_tolerance: Option<std::time::Duration> with humantime_serde::option (already a server dependency)
  3. server/src/access/http.rs — call site passes state.config.jwt.time_tolerance

Design decisions

Configurable, not hardcoded. A hardcoded tolerance silently changes the security posture of every deployment. Making it opt-in means the default behaviour is unchanged and operators explicitly accept the trade-off.

humantime_serde was already a dependency of the server crate — no new deps added.

Security note

time-tolerance widens the nbf acceptance window only. It does not bypass exp. A token with validity = 1h and time-tolerance = 30s is accepted for at most 1h 30s. For a private single-tenant cache a value of 30–60 seconds is the right trade-off; for a public cache operators should leave it unset (the default, preserving existing behaviour).

Testing

Verified that cargo build -p attic-server compiles cleanly with these changes.


Happy to add a unit test or adjust the field name / defaults if you prefer a different approach.

Adds an optional time-tolerance field to the [jwt] section of server.toml.
When set, JWT nbf/exp validation accepts tokens whose timestamps fall within
the specified tolerance, accommodating deployments where the token issuer and
the atticd host have unsynchronised clocks.
Common case: microVM and container guests that boot without NTP have clocks
that lag the host by tens of seconds. Tokens minted on the host carry nbf=now
(host time), which is in atticd's future, causing HTTP 401 on every request.
The tolerance is configurable rather than hardcoded so operators of public or
multi-tenant caches are unaffected by default. The field is opt-in: omitting
it preserves the existing behaviour (time_tolerance: None).
Security note: time-tolerance widens the acceptance window symmetrically. It
does not bypass exp. A token with validity=1h and time-tolerance=2m is valid
for at most 62 minutes.
Example server.toml:
 [jwt]
 time-tolerance = "30s"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /