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

Commit 1cf7a80

Browse files
committed
feat: add soft expiry logic and tests
1 parent 8ea69b7 commit 1cf7a80

3 files changed

Lines changed: 30 additions & 4 deletions

File tree

google/auth/_regional_access_boundary_utils.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
# The default lifetime for a cached Regional Access Boundary.
1414
DEFAULT_REGIONAL_ACCESS_BOUNDARY_TTL = datetime.timedelta(hours=6)
1515

16+
# The period of time prior to the boundary's expiration when a background refresh
17+
# is proactively triggered.
18+
REGIONAL_ACCESS_BOUNDARY_REFRESH_THRESHOLD = datetime.timedelta(hours=1)
19+
1620
# The initial cooldown period for a failed Regional Access Boundary lookup.
1721
DEFAULT_REGIONAL_ACCESS_BOUNDARY_COOLDOWN = datetime.timedelta(minutes=15)
1822

google/auth/credentials.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,11 +390,15 @@ def _maybe_start_regional_access_boundary_refresh(self, request, url):
390390
if not self._is_regional_access_boundary_lookup_required():
391391
return
392392

393-
# Don't start a new refresh if the Regional Access Boundary info is still valid.
393+
# Don't start a new refresh if the Regional Access Boundary info is still fresh.
394+
refresh_threshold = (
395+
_regional_access_boundary_utils.REGIONAL_ACCESS_BOUNDARY_REFRESH_THRESHOLD
396+
)
394397
if (
395398
self._regional_access_boundary
396399
and self._regional_access_boundary_expiry
397-
and _helpers.utcnow() < self._regional_access_boundary_expiry
400+
and _helpers.utcnow()
401+
< (self._regional_access_boundary_expiry - refresh_threshold)
398402
):
399403
return
400404

tests/test_credentials.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,9 +397,9 @@ def test_maybe_start_refresh_is_skipped_if_env_var_not_set(
397397
)
398398
def test_maybe_start_refresh_is_skipped_if_not_expired(self, mock_start_refresh):
399399
creds = CredentialsImpl()
400-
creds._regional_access_boundary = {"encodedLocations": "test"}
400+
creds._regional_access_boundary = {"encodedLocations": "0xABC"}
401401
creds._regional_access_boundary_expiry = _helpers.utcnow() + datetime.timedelta(
402-
minutes=5
402+
hours=2
403403
)
404404
with mock.patch.dict(
405405
os.environ,
@@ -410,6 +410,24 @@ def test_maybe_start_refresh_is_skipped_if_not_expired(self, mock_start_refresh)
410410
)
411411
mock_start_refresh.assert_not_called()
412412

413+
@mock.patch(
414+
"google.auth._regional_access_boundary_utils._RegionalAccessBoundaryRefreshManager.start_refresh"
415+
)
416+
def test_maybe_start_refresh_triggered_if_soft_expired(self, mock_start_refresh):
417+
creds = CredentialsImpl()
418+
creds._regional_access_boundary = {"encodedLocations": "0xABC"}
419+
420+
creds._regional_access_boundary_expiry = _helpers.utcnow() + datetime.timedelta(
421+
minutes=30
422+
)
423+
request = mock.Mock()
424+
with mock.patch.dict(
425+
os.environ,
426+
{environment_vars.GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED: "true"},
427+
):
428+
creds._maybe_start_regional_access_boundary_refresh(request, "http://example.com")
429+
mock_start_refresh.assert_called_once_with(creds, request)
430+
413431
@mock.patch(
414432
"google.auth._regional_access_boundary_utils._RegionalAccessBoundaryRefreshManager.start_refresh"
415433
)

0 commit comments

Comments
 (0)