Skip to content

fix(wallet): tolerate client clock skew in credential expiry checks#377

Open
noevidence1017 wants to merge 1 commit into
Miracle656:mainfrom
noevidence1017:fix/auth-clock-skew-tolerance-365
Open

fix(wallet): tolerate client clock skew in credential expiry checks#377
noevidence1017 wants to merge 1 commit into
Miracle656:mainfrom
noevidence1017:fix/auth-clock-skew-tolerance-365

Conversation

@noevidence1017

Copy link
Copy Markdown
Contributor

Summary

Audits and hardens clock-skew handling for time-bound credentials in __check_auth.

Session-key (SessionKeyAcl::expiry) and allowance (Allowance::expiry) expiry were compared against the consensus ledger timestamp with a strict now > expiry. Clients choose that expiry from their local wall clock and, for ledger-bound lifetimes, an assumed ledger rate (~5 s/ledger). Local clock drift and ledger-rate rounding can therefore place the stored expiry a few seconds earlier than the user expects, producing spurious SessionKeyExpired / AllowanceExpired rejections right at the boundary.

Behaviour (documented)

  • The on-chain comparison uses env.ledger().timestamp(), which is part of consensus and identical for every validator in a given ledger. There is no validator-side skew, so a strict comparison is correct on the contract side.
  • The skew to defend against is entirely client-side (clock drift + ledger-rate estimation when picking the expiry value).
  • Fix: a small, fixed grace window, CLOCK_SKEW_TOLERANCE_SECS = 60, applied to every expiry comparison. The grace window only ever extends validity, by a bounded constant, so it cannot cause an unexpired credential to be rejected and cannot weaken any check other than expiry.

Changes

  • New module contracts/invisible_wallet/src/auth/expiration.rs centralising expiry logic:
    • is_expired(now, expiry) — tolerance-aware, with saturating add for overflow safety.
    • is_expired_strict(now, expiry) — exact boundary, for tests/docs.
    • ensure_not_expired(now, expiry, err)Result helper letting each caller surface its own error variant.
  • session_key::enforce and the allowance check in __check_auth now route through this module instead of inline now > expiry.
  • Module-level documentation explaining the ledger-timestamp semantics and the rationale for the grace window.

Tests

  • Unit tests for boundary timestamps: before expiry, exactly at expiry, one second past expiry (within grace), edge of grace window, one second past grace, far past, plus u64::MAX overflow safety and zero-expiry cases.
  • End-to-end boundary tests through session_key::enforce (at expiry, within grace, past grace).
  • Full suite passes: cargo test -p invisible-wallet → 62 passed; 0 failed.

Closes #365

Session-key and allowance expiry were compared against the consensus
ledger timestamp with a strict `now > expiry`. Clients pick that expiry
from their local wall clock (and, for ledger-bound lifetimes, an assumed
~5s/ledger rate), so client clock drift and ledger-rate rounding could
place the stored expiry a few seconds early and cause spurious
SessionKeyExpired / AllowanceExpired rejections at the boundary.

Add a dedicated `auth::expiration` module that centralises the
comparison and applies a small, fixed clock-skew grace window
(CLOCK_SKEW_TOLERANCE_SECS = 60). The on-chain ledger timestamp is part
of consensus and identical across validators, so a strict comparison is
correct on the contract side; the grace window only ever extends
validity, by a bounded constant, to absorb client-side estimation error.

Session-key enforcement and the allowance check now route through this
module. Adds unit tests for the boundary (at expiry, within grace, one
second past grace, overflow safety) and end-to-end boundary tests
through `session_key::enforce`.

Closes Miracle656#365
@vercel

vercel Bot commented Jun 28, 2026

Copy link
Copy Markdown

@noevidence1017 is attempting to deploy a commit to the miracle656's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Jun 28, 2026

Copy link
Copy Markdown

@noevidence1017 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

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.

Audit clock-skew handling in __check_auth

1 participant