Skip to content

fix(oauth): send the OAuth token request to the region's auth host - #189

Closed
JingHao-Leon wants to merge 2 commits into
Teslemetry:mainfrom
JingHao-Leon:fix/cn-oauth-token-endpoint
Closed

JingHao-Leon wants to merge 2 commits into
Teslemetry:mainfrom
JingHao-Leon:fix/cn-oauth-token-endpoint

Conversation

@JingHao-Leon

@JingHao-Leon JingHao-Leon commented Oct 20, 2026 •

Copy link
Copy Markdown

What was broken

The OAuth token endpoint was hardcoded to the global auth host, so a client configured for the cn region exchanged its authorization code and refreshed its access token against fleet-auth.prd.vn.cloud.tesla.com instead of auth.tesla.cn.

The authorize endpoint already switched host for China (tesla_fleet_api/tesla/oauth.py:52), so a China client was sent to auth.tesla.cn to log in and then had the resulting code redeemed by a different region's auth host - the two halves of one OAuth flow ended up on different hosts. The partner-token request had the same split.

Root cause

The token endpoint was written as a string literal at each call site instead of being derived from the region (line numbers on main):

  • tesla_fleet_api/tesla/oauth.py:71 - TeslaFleetOAuth.get_refresh_token posts the authorization code to the global host
  • tesla_fleet_api/tesla/oauth.py:109 - TeslaFleetOAuth.refresh_access_token posts the refresh token to the global host
  • tesla_fleet_api/tesla/fleet.py:270 - TeslaFleetApi.partner_login posts the partner credentials to the global host

The region-aware authorize host already existed at tesla_fleet_api/tesla/oauth.py:52; no equivalent switch was applied to the token endpoint.

This change adds const.auth_server(region) as the single source of truth for the token endpoint and uses it at all three call sites. cn resolves to https://auth.tesla.cn/oauth2/v3/token; every other region - and an unset region - keeps https://fleet-auth.prd.vn.cloud.tesla.com/oauth2/v3/token.

How this was verified

Reproduced first, then fixed - the same test file shows both states.

Before the fix, against unmodified main (1.18.0) with the new tests added:

$ uv run pytest tests/test_fleet_auth_refresh.py -q
3 failed, 10 passed in 0.57s

FAILED tests/test_fleet_auth_refresh.py::OAuthTokenEndpointTests::test_cn_exchanges_the_authorization_code_on_the_cn_host
FAILED tests/test_fleet_auth_refresh.py::OAuthTokenEndpointTests::test_cn_partner_login_uses_the_cn_host
FAILED tests/test_fleet_auth_refresh.py::OAuthTokenEndpointTests::test_cn_refreshes_the_access_token_on_the_cn_host

Every failure is the same assertion - the request went to https://fleet-auth.prd.vn.cloud.tesla.com/oauth2/v3/token instead of https://auth.tesla.cn/oauth2/v3/token:

AssertionError: 'https://fleet-auth.prd.vn.cloud.tesla.com/oauth2/v3/token' != 'https://auth.tesla.cn/oauth2/v3/token'

The whole suite, same unfixed source, with the new tests added:

$ uv run pytest tests -q
3 failed, 949 passed, 1 warning, 127 subtests passed in 29.23s

After the fix:

$ uv run pytest tests/test_fleet_auth_refresh.py -q
13 passed in 0.43s

$ uv run pytest tests -q
952 passed, 1 warning, 127 subtests passed in 36.27s

Baseline for comparison - unmodified main, without the new tests:

$ uv run pytest tests -q
945 passed, 1 warning, 127 subtests passed in 31.00s

The 7 added tests are the whole difference between 945 and 952. The na cases and the cn authorize-URL characterization pass in both states, so only the China token host changes.

The end-to-end behaviour, same script run against main and against this branch:

# main
authorize URL: https://auth.tesla.cn/oauth2/v3/authorize
token POST URL: https://fleet-auth.prd.vn.cloud.tesla.com/oauth2/v3/token

# this branch
authorize URL: https://auth.tesla.cn/oauth2/v3/authorize
token POST URL: https://auth.tesla.cn/oauth2/v3/token

Lint and types:

$ uv run ruff check tesla_fleet_api tests
All checks passed!

$ uv run pyright tesla_fleet_api
0 errors, 0 warnings, 0 informations

One note on a pre-existing flake, unrelated to this change: tests/test_tesla_private_key.py::GetRsaPrivateKeyOptionalValidationTests::test_existing_key_read_does_not_block_event_loop is timing-sensitive (it expects >10 event-loop ticks across a mocked 0.15s key read) and fails intermittently on a loaded machine. It also failed on unmodified main in 2 of 3 full-suite runs (1 failed, 944 passed). This change does not touch the code path it exercises (tesla_fleet_api/tesla/tesla.py).

CI status

The repository's own CI workflow (lint / test / build) is held behind GitHub's "Approve and run workflows" gate on this branch: the run finished with conclusion action_required and reports 0 jobs, so the suite has not executed on the upstream runner - it needs a maintainer's approval to run. That is a gate rather than a failure: no job reported an error, and the run's head SHA matches this PR's head.

gh pr checks currently lists only the third-party CodeRabbit review check, still pending. The results above were produced locally with uv sync --locked (Python 3.13.9, uv 0.11.19) using the same commands CI runs.

Fixes #187

This change was prepared with the assistance of an AI coding agent.

The OAuth token endpoint is hardcoded to the global host, so a China
client redeems its authorization code (and refreshes its access token)
against fleet-auth.prd.vn.cloud.tesla.com instead of auth.tesla.cn,
while the authorize URL already switches host for China.

Covers TeslaFleetOAuth.get_refresh_token/refresh_access_token and
TeslaFleetApi.partner_login for both regions.
China is served by its own auth host (auth.tesla.cn); every other region
shares the global one. The authorize URL already switched host for China,
but the token endpoint stayed hardcoded to the global host, so a China
client redeemed its authorization code and refreshed its access token
against the wrong region.

Add const.auth_server() as the single source of truth and use it for
TeslaFleetOAuth.get_refresh_token, TeslaFleetOAuth.refresh_access_token
and TeslaFleetApi.partner_login.
@coderabbitai

coderabbitai Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: Teslemetry/coderabbit/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2aafd980-58eb-4622-b650-b25051f6998a
📥 Commits

Reviewing files that changed from the base of the PR and between d456585 and 0675c71.

📒 Files selected for processing: 4
  • tesla_fleet_api/const.py
  • tesla_fleet_api/tesla/fleet.py
  • tesla_fleet_api/tesla/oauth.py
  • tests/test_fleet_auth_refresh.py

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📝 Walkthrough

The OAuth token endpoint now depends on the configured region. Code exchange, access-token refresh, and partner login use the China endpoint for the China region and the global endpoint for other regions.

Changes: Regional OAuth token endpoints

Layer / File(s) Summary
Select the token endpoint
tesla_fleet_api/const.py
Added auth_server(region), which returns the China token endpoint for cn and the global endpoint for other or unset regions.
Route token requests and validate regional behavior
tesla_fleet_api/tesla/oauth.py, tesla_fleet_api/tesla/fleet.py, tests/test_fleet_auth_refresh.py
OAuth code exchange, access-token refresh, and partner login now use the regional endpoint. Tests check China and non-China token requests and confirm the China authorization URL host.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: bre77

Merge Risk: ⚪ Minimal · up to 0675c

China token requests use the China endpoint, while other regions retain the global endpoint. No actionable merge-blocking risk remains after normal checks.

Security architecture risk: 🔵 Low · up to 0675c

The routing change is narrow and selects between two fixed HTTPS endpoints. No introduced security regression was established. Remaining uncertainty concerns the regional service’s token contract and failure behavior, which mocked endpoint tests do not verify.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The directly changed exposure is the recipient of authentication material for clients configured with cn across three token flows. The selector does not introduce an arbitrary network destination or add scopes; other regions retain their prior destination.

Trust Boundaries and Controls

  • observed — Caller-supplied codes, refresh tokens, and client credentials remain request-body values rather than destination selectors. The changed routing crosses into the China authorization service only through the fixed cn branch, consistent with the existing China login-host selection.

Resilience and Maintainability Implications

  • observed — Token-state assignment order and error handling are unchanged by the PR. Existing OAuth parsing can leave partial updates on malformed successful responses, and concurrent exchanges remain unsynchronized; those mechanisms predate this change. Partner login still assigns its access token after response parsing. Regional routing adds no retry, rollback, or recovery mechanism.
Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 47.06% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 17 functions across 4 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly identifies the change: OAuth token requests now use the authentication host for the configured region.
Linked Issues check Passed Issue #187 requires China-region authorization-code exchange, refresh-token, and partner-token requests to use the China token endpoint. auth_server(region) returns the China endpoint for cn and t…
Out of Scope Changes check Passed The supplied change summary lists the regional auth helper, its three required call-site updates, and related tests. These changes directly support issue #187. The inspected source confirms the report…
Description check Passed The pull request description directly explains the hardcoded regional OAuth token endpoint issue, the affected authorization-code exchange, refresh, and partner-token requests, the implemented fix, an…
Full details: Linked Issues check

Explanation

Issue #187 requires China-region authorization-code exchange, refresh-token, and partner-token requests to use the China token endpoint. auth_server(region) returns the China endpoint for cn and the global endpoint otherwise. get_refresh_token, refresh_access_token, and partner_login all use this helper. Tests cover China and na for all three request types, and characterize the existing China authorize URL.

Full details: Out of Scope Changes check

Explanation

The supplied change summary lists the regional auth helper, its three required call-site updates, and related tests. These changes directly support issue #187. The inspected source confirms the reported endpoint behavior. No unrelated changes are identified.

Full details: Description check

Explanation

The pull request description directly explains the hardcoded regional OAuth token endpoint issue, the affected authorization-code exchange, refresh, and partner-token requests, the implemented fix, and the verification results. It matches the changeset.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@JingHao-Leon

Copy link
Copy Markdown
Author

Closing this in favour of #188, which covers the same change.

The report in #187 landed, and this PR was the follow-up implementation of it. In the meantime #188 opened with Fixes #187 and covers the same three call sites (get_refresh_token, refresh_access_token, partner_login) with the same region-to-token-URL mapping, so this PR is now redundant and there is no reason to keep two implementations of one fix open on the same issue.

The na/eu URLs are unchanged, and cn resolves to https://auth.tesla.cn/oauth2/v3/token.

No release note needed - #188 covers the same behaviour.

@JingHao-Leon

Copy link
Copy Markdown
Author

Superseded by #188 (same fix, opened from #187) - closing to avoid a duplicate.

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.

CN region: OAuth token endpoint still uses the global auth host instead of auth.tesla.cn

1 participant