Skip to content
This repository was archived by the owner on Mar 6, 2026. It is now read-only.

Commit 7af9f66

Browse files
author
Jon Wayne Parrott
authored
Fix clock skew calculations (#158)
Previously, the clock skew adjusted in the wrong direction. It would cause us to consider credentials whose expiration time had already pass according to the system clock to still be sent to the server. This is the opposite of what we wanted to happen. This fixes it so that we report that credentials are expired slightly before the system clock thinks they've expired.
1 parent 709953d commit 7af9f66

5 files changed

Lines changed: 20 additions & 17 deletions

File tree

google/auth/credentials.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,13 @@ def expired(self):
5656
Note that credentials can be invalid but not expired becaue Credentials
5757
with :attr:`expiry` set to None is considered to never expire.
5858
"""
59-
# Err on the side of reporting expiration early so that we avoid
60-
# the 403-refresh-retry loop.
61-
adjusted_now = _helpers.utcnow() - _helpers.CLOCK_SKEW
62-
return self.expiry is not None and self.expiry <= adjusted_now
59+
if not self.expiry:
60+
return False
61+
62+
# Remove 5 minutes from expiry to err on the side of reporting
63+
# expiration early so that we avoid the 401-refresh-retry loop.
64+
skewed_expiry = self.expiry - _helpers.CLOCK_SKEW
65+
return _helpers.utcnow() >= skewed_expiry
6366

6467
@property
6568
def valid(self):

tests/test_app_engine.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,10 @@ def test_service_account_email_explicit(self, app_identity_mock):
112112

113113
@mock.patch(
114114
'google.auth._helpers.utcnow',
115-
return_value=datetime.datetime.min + _helpers.CLOCK_SKEW)
115+
return_value=datetime.datetime.min)
116116
def test_refresh(self, now_mock, app_identity_mock):
117117
token = 'token'
118-
ttl = 100
118+
ttl = _helpers.CLOCK_SKEW_SECS + 100
119119
app_identity_mock.get_access_token.return_value = token, ttl
120120
credentials = app_engine.Credentials(scopes=['email'])
121121

tests/test_credentials.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,19 @@ def test_expired_and_valid():
3838
assert credentials.valid
3939
assert not credentials.expired
4040

41-
# Set the expiration in the past, but because of clock skew accomodation
42-
# the credentials should still be valid.
41+
# Set the expiration to one second more than now plus the clock skew
42+
# accomodation. These credentials should be valid.
4343
credentials.expiry = (
44-
datetime.datetime.utcnow() -
44+
datetime.datetime.utcnow() +
45+
_helpers.CLOCK_SKEW +
4546
datetime.timedelta(seconds=1))
4647

4748
assert credentials.valid
4849
assert not credentials.expired
4950

50-
# Set the credentials far enough in the past to exceed the clock skew
51-
# accomodation. They should now be expired.
52-
credentials.expiry = (
53-
datetime.datetime.utcnow() -
54-
_helpers.CLOCK_SKEW -
55-
datetime.timedelta(seconds=1))
51+
# Set the credentials expiration to now. Because of the clock skew
52+
# accomodation, these credentials should report as expired.
53+
credentials.expiry = datetime.datetime.utcnow()
5654

5755
assert not credentials.valid
5856
assert credentials.expired

tests/test_iam.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import pytest
2121
from six.moves import http_client
2222

23+
from google.auth import _helpers
2324
from google.auth import exceptions
2425
from google.auth import iam
2526
from google.auth import transport
@@ -42,7 +43,7 @@ def __init__(self):
4243
super(CredentialsImpl, self).__init__()
4344
self.token = 'token'
4445
# Force refresh
45-
self.expiry = datetime.datetime.min
46+
self.expiry = datetime.datetime.min + _helpers.CLOCK_SKEW
4647

4748
def refresh(self, request):
4849
pass

tests/transport/test_grpc.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import mock
1818
import pytest
1919

20+
from google.auth import _helpers
2021
from google.auth import credentials
2122
try:
2223
import google.auth.transport.grpc
@@ -56,7 +57,7 @@ def test_call_no_refresh(self):
5657

5758
def test_call_refresh(self):
5859
credentials = MockCredentials()
59-
credentials.expiry = datetime.datetime.min
60+
credentials.expiry = datetime.datetime.min + _helpers.CLOCK_SKEW
6061
request = mock.Mock()
6162

6263
plugin = google.auth.transport.grpc.AuthMetadataPlugin(

0 commit comments

Comments
 (0)