Skip to content

Ignore API load balancer stickiness cookies - #1177

Open
matthewgrossman wants to merge 1 commit into
bachya:devfrom
matthewgrossman:fix/refresh-access-token-on-403
Open

Ignore API load balancer stickiness cookies#1177
matthewgrossman wants to merge 1 commit into
bachya:devfrom
matthewgrossman:fix/refresh-access-token-on-403

Conversation

@matthewgrossman

@matthewgrossman matthewgrossman commented Sep 4, 2026

Copy link
Copy Markdown

Describe what the PR does:

This issue was observed in Home Assistant after the SimpliSafe integration had run normally for several days. Subscription polling and control requests then began returning 403 every 30 seconds, leaving entities unavailable until the integration was restarted. Home Assistant supplies a long-lived aiohttp.ClientSession, so cookies set by the SimpliSafe API persist across requests and token refreshes.

SimpliSafe API responses set the AWS load-balancer stickiness cookies AWSALB and AWSALBCORS. Direct probes isolated specific stored cookie values as the cause of the failure: requests using the same fresh access token and headers returned an ALB-branded HTML 403 with those values and 200 without them. The 403 response was:

HTTP/1.1 403 Forbidden
Server: awselb/2.0
Content-Type: text/html
Content-Length: 118

<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
</body>
</html>

This also explains why refreshing the access token alone did not recover the integration, while restarting it appeared to clear the condition.

This change masks both cookies with empty per-request values for api.simplisafe.com. Explicit request cookies override values from the session cookie jar, so the fix does not modify the caller-owned session or affect requests to other hosts. Existing token refresh and HTTP error handling remain unchanged.

Does this fix a specific issue?

No existing issue found.

Checklist:

  • Confirm that one or more new tests are written for the new functionality.
  • Run tests and ensure everything passes (with 100% test coverage).
  • Update README.md with any new documentation. No public API or configuration changed, so no documentation update is needed.

The regression test adds the problematic cookies to the session, verifies that the outgoing API request masks them, and exercises the existing 401 refresh and successful retry flow.

Validation:

  • poetry run pytest --cov simplipy tests — 94 passed, 100% coverage
  • poetry run mypy simplipy tests
  • SKIP=no-commit-to-branch,pytest poetry run pre-commit run --all-files

** Some commentary **

I'm surprised more things in HA don't break with a weeks+ old aiohttp client honestly. This only started happening to me recently, so I'm guessing this is some simplisafe load balancer change they made? If the simplisafe requests were all properly issueing updated set-cookie headers, then I wouldnt' think this would be an issue.

@matthewgrossman

matthewgrossman commented Sep 4, 2026

Copy link
Copy Markdown
Author

hmm looks like the 403s were from ELB, so maybe this isn't the right fix

EDIT: updated to handle the ALB cookie issues

@matthewgrossman
matthewgrossman force-pushed the fix/refresh-access-token-on-403 branch from c1f9193 to 99f844c Compare September 4, 2026 23:45
@matthewgrossman matthewgrossman changed the title Fix access token recovery after HTTP 403 Recover from stale API load balancer cookies Sep 4, 2026
@matthewgrossman
matthewgrossman force-pushed the fix/refresh-access-token-on-403 branch from 99f844c to c9764fe Compare September 5, 2026 03:27
@matthewgrossman matthewgrossman changed the title Recover from stale API load balancer cookies Ignore API load balancer stickiness cookies Sep 5, 2026
@matthewgrossman
matthewgrossman force-pushed the fix/refresh-access-token-on-403 branch from c9764fe to eef8945 Compare September 5, 2026 03:45
@matthewgrossman
matthewgrossman marked this pull request as ready for review September 5, 2026 03:49
Comment thread simplipy/api.py Outdated
Comment thread simplipy/api.py Outdated
kwargs["headers"]["Authorization"] = f"Bearer {self.access_token}"

if url_base == API_URL_BASE:
cookies = dict(kwargs.get("cookies") or {})

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the dict cast necessary here?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. Replaced dict(...) with dictionary unpacking; this still creates a shallow copy so a caller-provided cookie mapping is not mutated.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that was the key idea to not mutate that kwarg, so it was just making a new dict. Honestly mutating the kwarg is probably fine but I was just being defensive with it; happy to remove if you think it's unnecessary

Signed-off-by: Matthew Grossman <matthewryangrossman@gmail.com>
@matthewgrossman
matthewgrossman force-pushed the fix/refresh-access-token-on-403 branch from eef8945 to 7b7c96f Compare September 6, 2026 04:17

@bachya bachya left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@codecov

codecov Bot commented Sep 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (aa1b6e0) to head (7b7c96f).

Additional details and impacted files
@@            Coverage Diff            @@
##               dev     #1177   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           16        16           
  Lines         1024      1027    +3     
=========================================
+ Hits          1024      1027    +3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

2 participants