mirror of
https://github.com/codewhale-hq/Codewhale.git
synced 2026-11-08 08:04:25 -10:00
fix(auth): tolerate device clock skew in ChatGPT verification
Allow the existing 60-second network time tolerance on ChatGPT identity-token expiry and not-before checks while keeping signature, issuer, audience, subject, nonce and required-claim checks exact. A token with a 15-second future nbf now verifies; the existing one-hour-invalid case still fails. Verification: cargo test -p codewhale-runtime --lib siwc_signed_identity_requires_signature_issuer_audience_expiry_nonce_and_account passed (1 passed, 0 failed). Refs #7203.
This commit is contained in:
1 parent
b0b2b9a335
commit
4ca5880be8
2 files changed
+9
-1
No files matched your search
@@ -193,6 +193,7 @@ until the matching tag, packages, checksums, and release assets exist.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **ChatGPT sign-in tolerates a small device clock skew:** identity-token expiry and not-before checks allow the same 60-second tolerance already used for ordinary network time drift, while signature, issuer, audience, subject and nonce checks remain exact. The diagnostic text still names the exact failed check when a token is genuinely invalid.
|
||||
- **Remaining long-blocking work moved off async callers (#6553):** route
|
||||
credential and certificate preflight, worktree creation, Runtime Chat relay
|
||||
and remote-control journal transactions, and the remaining session, branch,
|
||||
|
||||
@@ -2436,6 +2436,7 @@ pub const CHATGPT_OAUTH_CLIENT_ID: &str = "dynamic_agent_client";
|
||||
pub const CHATGPT_OAUTH_RESOURCE: &str = "https://api.openai.com/v1";
|
||||
pub const CHATGPT_OAUTH_SCOPE: &str =
|
||||
"openid profile email offline_access resource.invoke chatgpt.tokens.use.direct";
|
||||
const CHATGPT_CLOCK_SKEW_LEEWAY_SECS: u64 = 60;
|
||||
|
||||
/// Verified registration identity. The client ID also binds the selected workspace.
|
||||
/// One active registration is supported; use CODEWHALE_CHATGPT_NEW_ACCOUNT=1
|
||||
@@ -2579,7 +2580,7 @@ fn verify_chatgpt_jwt<T: serde::de::DeserializeOwned + Clone>(
|
||||
validation.set_audience(&[audience]);
|
||||
validation.set_required_spec_claims(&["exp", "iss", "aud", "sub"]);
|
||||
validation.validate_nbf = true;
|
||||
validation.leeway = 0;
|
||||
validation.leeway = CHATGPT_CLOCK_SKEW_LEEWAY_SECS;
|
||||
let claims = decode::<Value>(token, &key, &validation)
|
||||
.map_err(|error| match error.kind() {
|
||||
ErrorKind::InvalidSignature => {
|
||||
@@ -8384,6 +8385,12 @@ consent_version = 1
|
||||
let error = verify(&signer.token(changed)).unwrap_err().to_string();
|
||||
assert!(error.contains(expected), "invalid {field}: {error}");
|
||||
}
|
||||
let mut skewed = claims.clone();
|
||||
skewed["nbf"] = Value::from(now_unix_secs().unwrap() + 15);
|
||||
assert!(
|
||||
verify(&signer.token(skewed)).is_ok(),
|
||||
"a small clock skew must not reject a valid identity token"
|
||||
);
|
||||
for required in ["iss", "aud", "exp", "sub", "nonce"] {
|
||||
let mut changed = claims.clone();
|
||||
changed.as_object_mut().unwrap().remove(required);
|
||||
|
||||
Reference in new issue
Block a user