summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-common
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-04 03:03:47 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-04 03:03:47 +0200
commitdad2157ada303a45655d2919f62905369525636f (patch)
tree083d08cd15e1258e4fbcca3c3c619debb2857022 /packages/meshbay-common
parent41282b997e016da0773276a935434dd03631e1f3 (diff)
downloadmeshbay-dad2157ada303a45655d2919f62905369525636f.tar.gz
fix: tolerate clock skew when verifying JWTs (leeway 60s)
A client whose clock is a little fast could not connect at all: the MNP handshake verified the hub-issued token with no leeway, so a token whose `iat` was a few seconds ahead of the node's clock failed with "the token is not yet valid (iat)". Seen against a freshly-resumed VM guest. `meshbay_common.handshake.JWT_LEEWAY_SECONDS = 60` is the shared value; applied to the handshake, the node's own hub-token decode, revocation-token verification, and the hub's access-token decode. 60s absorbs NTP-level skew without meaningfully widening the window on a stolen token (they already carry a jti and an exp). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-common')
-rw-r--r--packages/meshbay-common/src/meshbay_common/handshake.py10
1 files changed, 9 insertions, 1 deletions
diff --git a/packages/meshbay-common/src/meshbay_common/handshake.py b/packages/meshbay-common/src/meshbay_common/handshake.py
index 2f3d641..f7d4911 100644
--- a/packages/meshbay-common/src/meshbay_common/handshake.py
+++ b/packages/meshbay-common/src/meshbay_common/handshake.py
@@ -77,6 +77,13 @@ ROLE_NODE = "node"
NONCE_LEN = 32
+# Clock-skew tolerance for JWT `iat`/`exp`/`nbf`. The token is issued by the
+# hub and verified by a node, on two machines whose clocks are only as close
+# as their NTP — and a VM guest that has just resumed can be tens of seconds
+# out. Without this a slightly-fast client cannot connect at all
+# ("token is not yet valid (iat)").
+JWT_LEEWAY_SECONDS = 60
+
class HandshakeError(Exception):
"""
@@ -230,7 +237,8 @@ def authorize_token(
check entirely and fell back to the node's first group (M1).
"""
try:
- decoded = jwt.decode(token, hub_pk_pem, algorithms=["EdDSA"])
+ decoded = jwt.decode(token, hub_pk_pem, algorithms=["EdDSA"],
+ leeway=JWT_LEEWAY_SECONDS)
except Exception as exc:
raise HandshakeError(f"Invalid JWT: {exc}") from exc