Skip to content

Add OAuth 2.0 documentation#2968

Open
erwindouna wants to merge 27 commits intohome-assistant:masterfrom
erwindouna:oauth-docs
Open

Add OAuth 2.0 documentation#2968
erwindouna wants to merge 27 commits intohome-assistant:masterfrom
erwindouna:oauth-docs

Conversation

@erwindouna
Copy link
Copy Markdown
Member

@erwindouna erwindouna commented Feb 19, 2026

Proposed change

Adding OAuth 2.0 documentation. Starting point to expand the developer docs, as discussed with @MartinHjelmare.

Type of change

  • Document existing features within Home Assistant
  • Document new or changing features for which there is an existing pull request elsewhere
  • Spelling or grammatical corrections, or rewording for improved clarity
  • Changes to the backend of this documentation
  • Remove stale or deprecated documentation

Checklist

  • I have read and followed the documentation guidelines.
  • I have verified that my changes render correctly in the documentation.

Additional information

  • This PR fixes or closes issue: fixes #
  • Link to relevant existing code or pull request:

Summary by CodeRabbit

  • Documentation
    • Added a comprehensive OAuth 2.0 integration guide covering auth flows, token handling, reauthentication, error semantics, usage examples, and best practices for building integrations.
  • Documentation
    • Updated site navigation to surface the new OAuth 2.0 guide under Core → Building Integrations.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 19, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Added a new OAuth 2.0 documentation page for Home Assistant integrations and registered it in the sidebar navigation.

Changes

Cohort / File(s) Summary
Documentation
docs/oauth2.md
New documentation page describing OAuth 2.0 support: helpers (Authorization Code flow, token refresh, OAuth2Session), supported flows (Authorization Code, PKCE), integration config flow examples, reauthentication flows, authenticated request patterns, semantic token exception hierarchy, coordinated vs non-coordinated usage examples, and best practices.
Navigation
sidebars.js
Added "oauth2" entry to the Core → Building Integrations items array to surface the new documentation page in the sidebar.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is largely incomplete: the 'Proposed change' section is minimal, both documentation checklist items are unchecked, and critical details like linked issues or code references are missing. Complete the checklist by confirming documentation guidelines were followed and changes render correctly, and provide the GitHub PR link for the underlying feature changes if available.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add OAuth 2.0 documentation' clearly and concisely describes the main change: adding new documentation for OAuth 2.0 implementation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/core/platform/oauth2.md`:
- Line 63: The sentence describing the `extra_authorize_data` property uses
"provider specific" without a hyphen; update that text so the compound modifier
reads "provider-specific" to be grammatically correct (locate the
`extra_authorize_data` description in oauth2.md and replace "provider specific"
with "provider-specific").
- Around line 263-266: Remove the two unresolved author notes and fix the typos:
replace "{MIGHT NEED TO EXPAND THIS WITH DUC METHODS}" and "{WE STILL NEED TO
BUILD THIS IN, THOUGH. CHECK THE PR UNDER REVIEW BY ALLENPORTER.}" with final
text (or delete the second bullet about token_request_headers until the feature
is implemented or explicitly mark it as "upcoming/experimental"); correct
"ConfgEntryError" to "ConfigEntryError" and "Enfore" to "Enforce"; keep the
guidance about raising ConfigEntryNotReady, implementing async_step_reauth, and
using extra_authorize_data intact while ensuring the token_request_headers
recommendation is only present if the API exists or is clearly labeled as
experimental.
- Line 33: Fix the two text errors in the Note line: change "prodiver" to
"provider" and replace the non-standard word "overpreferred" with either
"preferred" or "strongly preferred" (e.g., "preferred" to keep tone consistent)
in the sentence that begins "_Note:_ If a service ...".
- Around line 26-31: Update the OAuth2 flow names in the table so the rows for
LocalOAuth2Implementation and LocalOAuth2ImplementationWithPkce read
"Authorization Code" and "Authorization Code with PKCE" respectively (they are
currently mislabeled as Client Credentials), fix typos "prodiver"→"provider" and
"overpreferred"→"preferred", rename the documented error type "ConfgEntryError"
to "ConfigEntryError", and change "Enfore"→"Enforce" while removing the draft
placeholder text "{WE STILL NEED TO BUILD THIS IN, THOUGH. CHECK THE PR UNDER
REVIEW BY ALLENPORTER.}" from the AbstractOAuth2Implementation section.
- Around line 148-156: Update the exception tuples used when mapping token
request failures to ConfigEntryNotReady so they match the blog recommendation:
replace any occurrences of except (OAuth2TokenRequestTransientError,
OAuth2TokenRequestError) (seen around the raise ConfigEntryNotReady blocks) with
except (OAuth2TokenRequestError, ClientError) to ensure low-level
aiohttp.ClientError (ClientError) network failures are caught; do this
consistently for the three occurrences that wrap the raise ConfigEntryNotReady
(the same try/except that currently references OAuth2TokenRequestTransientError)
and import or reference ClientError where necessary.

Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md
Comment thread docs/core/platform/oauth2.md
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
@home-assistant home-assistant bot marked this pull request as draft February 19, 2026 20:05
@home-assistant
Copy link
Copy Markdown

Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍

Learn more about our pull request process.

@erwindouna erwindouna marked this pull request as ready for review February 19, 2026 20:37
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/core/platform/oauth2.md`:
- Line 66: Fix the grammatical error in the sentence referring to token refresh
by replacing the double modal "can will handle" with a single modal (e.g., "will
handle" or "can handle") in the paragraph that mentions
async_ensure_token_valid; keep the rest of the sentence intact and ensure
async_step_reauth is still mentioned as the required reauthentication entry
point.
- Line 239: Fix the typo in the OAuth2 docs: replace "ConfgEntryAuthFailed" with
the correct class name "ConfigEntryAuthFailed" in the sentence that contrasts
raising ConfigEntryNotReady for transient errors versus ConfigEntryAuthFailed
for non-recoverable errors so the documented symbol matches the actual exception
name.
- Around line 104-110: Add the missing comparison bullet for
async_get_access_token and fix the typo in the async_ensure_token_valid bullet:
update the text to say "This needs to be done" and add a new bullet describing
async_get_access_token that explains it will refresh the token if needed and
return the token (so callers can get the token in one call), and keep the note
that both methods raise the same exceptions (referencing async_get_access_token
and async_ensure_token_valid to locate the section).

---

Duplicate comments:
In `@docs/core/platform/oauth2.md`:
- Line 62: The sentence describing the extra_authorize_data property uses the
unhyphenated phrase "provider specific"; update the text for the
extra_authorize_data property so it reads "provider-specific" (i.e., change
"provider specific parameters" to "provider-specific parameters") to use the
correct compound modifier.
- Line 32: Fix the typos and flow-name errors in the sentence starting with
"_Note:_ If a service prodiver offers..." by changing "prodiver" to "provider",
replacing "overpreferred" with "preferred", and swapping both instances of
"Client Credentials flow" to "Authorization Code flow" so the note matches the
corrected table above; update the sentence that mentions Device Authorization
and QR code only if wording depends on these flow names to keep consistency.
- Around line 150-154: Update the exception handlers that currently read "except
(OAuth2TokenRequestTransientError, OAuth2TokenRequestError) as err:" so they
instead catch the base OAuth2TokenRequestError plus aiohttp.ClientError (i.e.
use (OAuth2TokenRequestError, ClientError)), and remove the redundant
OAuth2TokenRequestTransientError entry; ensure the handlers that raise
ConfigEntryNotReady (using DOMAIN and translation_key="auth_server_error") are
changed accordingly in both places where this tuple appears so low-level network
aiohttp failures are covered.

Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
@MartinHjelmare MartinHjelmare marked this pull request as draft February 23, 2026 10:49
erwindouna and others added 7 commits February 24, 2026 21:42
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
@erwindouna erwindouna marked this pull request as ready for review February 24, 2026 20:59
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (4)
docs/core/platform/oauth2.md (4)

60-60: "provider specific" → "provider-specific" (compound modifier missing hyphen).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/core/platform/oauth2.md` at line 60, In the docs line describing
extra_authorize_data, change the phrase "provider specific" to the hyphenated
compound modifier "provider-specific" so the sentence reads: "The
`extra_authorize_data` property is where you define the OAuth scopes and any
other provider-specific parameters required during the authorization request."
Reference: `extra_authorize_data`.

97-97: "needs to done" → "needs to be done" (missing "be").

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/core/platform/oauth2.md` at line 97, Typo in the docs: change "needs to
done" to "needs to be done" in the sentence describing
async_ensure_token_valid(); update the line mentioning
async_ensure_token_valid() and the OAuth2Session property so it reads "needs to
be done before every request" to correct the grammar.

228-228: Typo: "ConfgEntryAuthFailed" → "ConfigEntryAuthFailed".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/core/platform/oauth2.md` at line 228, Fix the typo
"ConfgEntryAuthFailed" to "ConfigEntryAuthFailed" in the sentence that contrasts
raising ConfigEntryNotReady for transient errors vs ConfigEntryAuthFailed for
non-recoverable errors; update the mention of ConfigEntryAuthFailed (spelled
correctly) so both occurrences in that sentence/doc entry are accurate.

122-122: async_get_access_token() is mentioned as a call site but MartinHjelmare noted it is not HA's public API — it belongs to the library layer.

The sentence "wherever you call async_get_access_token() or async_ensure_token_valid()" propagates the confusion between the library-internal method and the HA session API. This is consistent with the past reviewer feedback: integrations should only call async_ensure_token_valid().

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/core/platform/oauth2.md` at line 122, Update the sentence to stop
instructing integrations to call async_get_access_token(); instead mention only
async_ensure_token_valid() as the public HA API to use and clarify that
async_get_access_token() is a library-internal method (not part of the public
integration API). Keep the existing context about integrations without a
coordinator, and reference the coordinator and the async_ensure_token_valid()
symbol so readers know where to handle exceptions; remove or replace any direct
mention of async_get_access_token().
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/core/platform/oauth2.md`:
- Around line 173-177: The call to async_get_access_token() inside
_async_update_data contradicts guidance — replace it with the standard
OAuth2Session flow: call OAuth2Session.async_ensure_token_valid() on
self.session before using the token, then read the token from self.session.token
(e.g., access_token = self.session.token["access_token"]) instead of calling
async_get_access_token(); also remove or update the comment about coordinator
auto-mapping unless you confirm the coordinator will translate OAuth exceptions,
and ensure any token-refresh exceptions are handled by the coordinator or
surfaced appropriately.
- Around line 36-58: The snippet is missing imports for used names; add "import
logging" and "from typing import Any, Mapping" (or appropriate typing aliases)
at the top of the module so the OAuth2FlowHandler.logger property and
extra_authorize_data return type (dict[str, Any]) resolve, and ensure the
async_step_reauth snippet uses Mapping without error by importing Mapping;
update imports near the top of the file rather than inside class/methods so
OAuth2FlowHandler, logger, extra_authorize_data, and async_step_reauth all have
the required symbols available.

---

Duplicate comments:
In `@docs/core/platform/oauth2.md`:
- Line 60: In the docs line describing extra_authorize_data, change the phrase
"provider specific" to the hyphenated compound modifier "provider-specific" so
the sentence reads: "The `extra_authorize_data` property is where you define the
OAuth scopes and any other provider-specific parameters required during the
authorization request." Reference: `extra_authorize_data`.
- Line 97: Typo in the docs: change "needs to done" to "needs to be done" in the
sentence describing async_ensure_token_valid(); update the line mentioning
async_ensure_token_valid() and the OAuth2Session property so it reads "needs to
be done before every request" to correct the grammar.
- Line 228: Fix the typo "ConfgEntryAuthFailed" to "ConfigEntryAuthFailed" in
the sentence that contrasts raising ConfigEntryNotReady for transient errors vs
ConfigEntryAuthFailed for non-recoverable errors; update the mention of
ConfigEntryAuthFailed (spelled correctly) so both occurrences in that
sentence/doc entry are accurate.
- Line 122: Update the sentence to stop instructing integrations to call
async_get_access_token(); instead mention only async_ensure_token_valid() as the
public HA API to use and clarify that async_get_access_token() is a
library-internal method (not part of the public integration API). Keep the
existing context about integrations without a coordinator, and reference the
coordinator and the async_ensure_token_valid() symbol so readers know where to
handle exceptions; remove or replace any direct mention of
async_get_access_token().

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 7080ac9 and 86a9636.

📒 Files selected for processing (1)
  • docs/core/platform/oauth2.md

Comment thread docs/core/platform/oauth2.md
Comment thread docs/core/platform/oauth2.md Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oauth2 isn't a platform in the Home Assistant sense. So we should not put the new page under that directory. Application Credentials is a platform.

Maybe put the new file directly under docs but have it show in the sidebar under "Building integrations"?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Replaced.

Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
Comment thread docs/core/platform/oauth2.md Outdated
@MartinHjelmare MartinHjelmare marked this pull request as draft February 24, 2026 23:03
erwindouna and others added 4 commits February 25, 2026 08:44
@erwindouna erwindouna marked this pull request as ready for review February 25, 2026 08:18
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Nitpick comments (1)
docs/oauth2.md (1)

111-111: Use "backward" (not "backwards") per the Microsoft Style Guide.

✏️ Proposed fix
-All three exceptions inherit from `aiohttp.ClientResponseError` for backwards compatibility, but integrations should migrate to catching the new exceptions directly.
+All three exceptions inherit from `aiohttp.ClientResponseError` for backward compatibility, but integrations should migrate to catching the new exceptions directly.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/oauth2.md` at line 111, Replace the phrase "for backwards compatibility"
with "for backward compatibility" in docs/oauth2.md where the sentence "All
three exceptions inherit from `aiohttp.ClientResponseError` for backwards
compatibility, but integrations should migrate to catching the new exceptions
directly." appears; update the text to read "All three exceptions inherit from
`aiohttp.ClientResponseError` for backward compatibility, but integrations
should migrate to catching the new exceptions directly."
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/oauth2.md`:
- Line 97: Fix the typo in the sentence describing async_ensure_token_valid by
inserting the missing word "be" so it reads "needs to be done before every
request"; update the line referencing async_ensure_token_valid and
OAuth2Session.token accordingly to maintain clarity in docs/oauth2.md.
- Line 118: The bullet point missing the verb should be updated to read
"OAuth2TokenRequestTransientError is treated as UpdateFailed, triggering the
coordinator's retry mechanism" — edit the line containing the string
"OAuth2TokenRequestTransientError" to insert the verb "is" between the error
name and "treated" so the sentence is grammatically correct.
- Around line 177-183: The example shows a NameError because _async_setup uses
undefined session; change the call to ExampleApiClient(session=self.session)
inside _async_setup and reconcile the __init__ assignment that sets self.client
= client — either remove the client parameter from __init__ (and its self.client
= client line) if the coordinator should create the client in _async_setup, or
keep the client parameter and avoid overwriting it in _async_setup (use the
passed-in client or only create the client when none exists); update __init__ or
_async_setup accordingly to make intent consistent (refer to __init__ and
_async_setup and the self.client and self.session symbols).
- Line 22: Replace the tentative sentence with a direct imperative: state "Use
the built-in config_entry_oauth2_flow for standard Authorization Code flows" and
instruct to "Use the existing template flows that inherit from
AbstractOAuth2FlowHandler; only implement custom child flows if absolutely
necessary." Ensure references to config_entry_oauth2_flow and
AbstractOAuth2FlowHandler remain unchanged.
- Line 235: Fix the typo by replacing the misspelled symbol
"ConfgEntryAuthFailed" with the correct "ConfigEntryAuthFailed" in the oauth2
docs text (the sentence that explains raising ConfigEntryNotReady vs
ConfigEntryAuthFailed for transient vs non-recoverable errors), ensuring the
exact symbol name is corrected wherever it appears.
- Line 60: Update the documentation sentence to hyphenate the compound adjective
by changing "provider specific parameters" to "provider-specific parameters" in
the sentence that describes the extra_authorize_data property (the line
mentioning the `extra_authorize_data` property and OAuth scopes).
- Line 150: Replace the awkward sentence "Look at the [library
guide](/docs/api_lib_auth) on authentication for more information on building
guidelines. The following examples act merely as an example how to interlink a
library with OAuth2.0 in the Data Update Coordinator." with a clearer phrasing:
use "See the [library guide](/docs/api_lib_auth) on authentication for more
information on building guidelines" and change "OAuth2.0" to "OAuth 2.0", then
reword the second clause to something like "The following examples show how to
integrate a library with OAuth 2.0 in the Data Update Coordinator" so the
paragraph reads smoothly and uses correct spacing and terminology.

---

Nitpick comments:
In `@docs/oauth2.md`:
- Line 111: Replace the phrase "for backwards compatibility" with "for backward
compatibility" in docs/oauth2.md where the sentence "All three exceptions
inherit from `aiohttp.ClientResponseError` for backwards compatibility, but
integrations should migrate to catching the new exceptions directly." appears;
update the text to read "All three exceptions inherit from
`aiohttp.ClientResponseError` for backward compatibility, but integrations
should migrate to catching the new exceptions directly."

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 86a9636 and 4037d43.

📒 Files selected for processing (2)
  • docs/oauth2.md
  • sidebars.js

Comment thread docs/oauth2.md Outdated
Comment thread docs/oauth2.md
Comment thread docs/oauth2.md Outdated
Comment thread docs/oauth2.md
Comment thread docs/oauth2.md Outdated
Comment thread docs/oauth2.md Outdated
Comment thread docs/oauth2.md
Comment thread docs/oauth2.md Outdated

Integrations that connect to cloud services often need to authenticate users via OAuth 2.0. Home Assistant provides a set of helpers in `homeassistant.helpers.config_entry_oauth2_flow` that handle the OAuth 2.0 flow, token storage, and token refresh lifecycle — so integrations don't have to implement this themselves.

This page covers how to implement OAuth 2.0 in an integration, how to handle errors and best practices.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Here we could mention the library guide:

https://developers.home-assistant.io/docs/api_lib_auth#oauth2

Ie that this page covers implementing OAuth2 in an integration while the library guide page covers implementing Oauth2 in a 3rd party library that will be used for an integration.

Comment thread docs/oauth2.md Outdated
- A session helper (`OAuth2Session`) for making authenticated API requests.
- Error handling via a set of semantic exceptions

The helper supports two credential approaches, both of which require `application_credentials` support.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we should mention what two credential approaches we mean here.

Comment thread docs/oauth2.md Outdated
Comment thread docs/oauth2.md Outdated
| ---------------------------- | ----------------------------------- | ------------------------------- |
| Authorization code | `LocalOAuth2Implementation` | Standard browser-based flow |
| Authorization code with PKCE | `LocalOAuth2ImplementationWithPkce` | When the provider requires PKCE |
| Custom | `AbstractOAuth2Implementation` | Any non-standard flow |
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm still not sure if we should talk about custom flows, since we don't know that we can support them in a good way.

Comment thread docs/oauth2.md Outdated
"""Confirm reauthentication."""
if user_input is None:
return self.async_show_form(step_id="reauth_confirm")
return await self.async_step_user()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we should use the same example as here (or link to that example):

https://developers.home-assistant.io/docs/config_entries_config_flow_handler#reauthentication

Comment thread docs/oauth2.md Outdated
Comment thread docs/oauth2.md Outdated
Comment thread docs/oauth2.md
Comment thread docs/oauth2.md Outdated
Comment thread docs/oauth2.md Outdated
@MartinHjelmare MartinHjelmare marked this pull request as draft March 10, 2026 12:49
erwindouna and others added 11 commits March 11, 2026 08:49
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
@erwindouna erwindouna marked this pull request as ready for review April 9, 2026 19:09
@home-assistant home-assistant bot requested a review from MartinHjelmare April 9, 2026 19:09
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (6)
docs/oauth2.md (6)

120-120: ⚠️ Potential issue | 🟡 Minor

Missing verb "be" in sentence.

The sentence reads "needs to done" instead of "needs to be done".

This issue was already flagged in previous reviews.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/oauth2.md` at line 120, The sentence describing
`async_ensure_token_valid` has a missing verb: change "needs to done before
every request" to "needs to be done before every request" in the docs; ensure
the line referencing `async_ensure_token_valid` and `OAuth2Session.token` is
updated accordingly.

253-261: ⚠️ Potential issue | 🟡 Minor

Typo in exception name on line 259.

"ConfgEntryAuthFailed" is missing the "i" - should be "ConfigEntryAuthFailed".

This issue was already flagged in previous reviews.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/oauth2.md` around lines 253 - 261, The docs contain a typo in the
exception name: replace the misspelled "ConfgEntryAuthFailed" with the correct
symbol "ConfigEntryAuthFailed" in the Best practices section so the documented
exception matches the actual Home Assistant exception class; update any other
occurrences of the misspelling in the same file to ensure consistency
(references: ConfigEntryAuthFailed, OAuth2TokenRequestReauthError).

182-182: ⚠️ Potential issue | 🟡 Minor

Fix style issues: "Look at" → "See", "OAuth2.0" → "OAuth 2.0", and hyphenate "3rd-party".

This issue was already flagged in previous reviews.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/oauth2.md` at line 182, Update the sentence text to fix style: replace
the lead phrase "Look at" with "See", change "OAuth2.0" to "OAuth 2.0", and
hyphenate "3rd-party" in the phrase that currently reads "building a 3rd party
library with OAuth2.0 for an integration" (the sentence referencing the library
guide and Data Update Coordinator). Ensure the updated sentence reads smoothly
with these three style changes.

59-59: ⚠️ Potential issue | 🟡 Minor

Hyphenate the compound adjective "provider-specific".

This issue was already flagged in previous reviews.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/oauth2.md` at line 59, The sentence uses "provider specific" as a
compound adjective; update the documentation text for the extra_authorize_data
property to hyphenate it as "provider-specific" so it reads "provider-specific
parameters" (refer to the extra_authorize_data description).

136-142: ⚠️ Potential issue | 🟡 Minor

Missing verb in bullet point.

Line 141 is missing the verb "is" - should read "OAuth2TokenRequestTransientError is treated as UpdateFailed".

This issue was already flagged in previous reviews.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/oauth2.md` around lines 136 - 142, Fix the missing verb in the
documentation sentence describing how exceptions are mapped by the Data Update
Coordinator: update the bullet that mentions OAuth2TokenRequestTransientError so
it reads "OAuth2TokenRequestTransientError is treated as UpdateFailed" (ensure
you edit the exact text mentioning OAuth2TokenRequestTransientError and
UpdateFailed to add the word "is").

22-22: ⚠️ Potential issue | 🟡 Minor

Use direct, imperative tone for implementation guidance.

The current phrasing is tentative. Documentation should use direct imperatives.

This issue was already flagged in previous reviews.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/oauth2.md` at line 22, Revise the sentence to use a direct imperative:
instruct readers to "Use the built-in config_entry_oauth2_flow helper for
Authorization Code flows" and state plainly "Only create custom subclasses of
AbstractOAuth2FlowHandler when necessary" (instead of tentative phrasing); keep
references to config_entry_oauth2_flow and AbstractOAuth2FlowHandler exactly as
named and remove hedging words like "should" or "if it's needed."
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/oauth2.md`:
- Line 20: Rewrite the sentence to clearly name and hyphenate the two
approaches: use "application-provided credentials" to mean the integration ships
its own client ID and client secret, and "user-provided credentials" to mean the
end user supplies their own OAuth 2.0 client credentials via the UI; keep the
reference to `application_credentials` and ensure compound adjectives are
hyphenated (e.g., "application-provided" and "user-provided") and the sentence
remains concise per Microsoft Style Guide.
- Around line 143-154: Remove the contradictory coordinator-specific text and
code from the "Integrations without a Data Update Coordinator" section: delete
the paragraphs that describe coordinator behavior and the example call to
coordinator.async_config_entry_first_refresh(), and instead state clearly that
integrations without a Data Update Coordinator must call
async_ensure_token_valid() and handle OAuth2TokenRequestReauthError and
OAuth2TokenRequestTransientError at each token request site; keep references to
the exception types (OAuth2TokenRequestReauthError,
OAuth2TokenRequestTransientError) and the function name async_ensure_token_valid
to guide readers, and ensure the surrounding text and code fence reflect a
non-coordinator workflow only.
- Around line 88-99: In async_oauth_create_entry, the code calls
self.async_set_unique_id(user_id) but user_id is undefined; extract the id from
the incoming data dict (e.g., obtain user_id = data.get('user_id') or
data['user_id'] depending on guarantees) and pass that to
self.async_set_unique_id, and if using get() add a guard to handle a missing
user_id (raise/abort with a clear error) before continuing; update the reference
in async_oauth_create_entry accordingly.

---

Duplicate comments:
In `@docs/oauth2.md`:
- Line 120: The sentence describing `async_ensure_token_valid` has a missing
verb: change "needs to done before every request" to "needs to be done before
every request" in the docs; ensure the line referencing
`async_ensure_token_valid` and `OAuth2Session.token` is updated accordingly.
- Around line 253-261: The docs contain a typo in the exception name: replace
the misspelled "ConfgEntryAuthFailed" with the correct symbol
"ConfigEntryAuthFailed" in the Best practices section so the documented
exception matches the actual Home Assistant exception class; update any other
occurrences of the misspelling in the same file to ensure consistency
(references: ConfigEntryAuthFailed, OAuth2TokenRequestReauthError).
- Line 182: Update the sentence text to fix style: replace the lead phrase "Look
at" with "See", change "OAuth2.0" to "OAuth 2.0", and hyphenate "3rd-party" in
the phrase that currently reads "building a 3rd party library with OAuth2.0 for
an integration" (the sentence referencing the library guide and Data Update
Coordinator). Ensure the updated sentence reads smoothly with these three style
changes.
- Line 59: The sentence uses "provider specific" as a compound adjective; update
the documentation text for the extra_authorize_data property to hyphenate it as
"provider-specific" so it reads "provider-specific parameters" (refer to the
extra_authorize_data description).
- Around line 136-142: Fix the missing verb in the documentation sentence
describing how exceptions are mapped by the Data Update Coordinator: update the
bullet that mentions OAuth2TokenRequestTransientError so it reads
"OAuth2TokenRequestTransientError is treated as UpdateFailed" (ensure you edit
the exact text mentioning OAuth2TokenRequestTransientError and UpdateFailed to
add the word "is").
- Line 22: Revise the sentence to use a direct imperative: instruct readers to
"Use the built-in config_entry_oauth2_flow helper for Authorization Code flows"
and state plainly "Only create custom subclasses of AbstractOAuth2FlowHandler
when necessary" (instead of tentative phrasing); keep references to
config_entry_oauth2_flow and AbstractOAuth2FlowHandler exactly as named and
remove hedging words like "should" or "if it's needed."
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 88b7b246-3b31-4436-b0b7-4c7332d0973e

📥 Commits

Reviewing files that changed from the base of the PR and between 4037d43 and f296d88.

📒 Files selected for processing (2)
  • docs/oauth2.md
  • sidebars.js
✅ Files skipped from review due to trivial changes (1)
  • sidebars.js

Comment thread docs/oauth2.md
- A session helper (`OAuth2Session`) for making authenticated API requests.
- Error handling via a set of semantic exceptions

The helper supports two credential approaches, both of which require `application_credentials` support: application provided credentials (where the integration ships its own client ID and client secret) and user-provided credentials (where the user supplies their own OAuth 2.0 client credentials via the UI).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Clarify the two credential approaches and fix hyphenation.

The sentence mentions "two credential approaches" but could be clearer about what they are. Additionally, compound adjectives need hyphens.

✏️ Proposed fix
-The helper supports two credential approaches, both of which require `application_credentials` support: application provided credentials (where the integration ships its own client ID and  client secret) and user-provided credentials (where the user supplies their own OAuth 2.0 client credentials via the UI).
+The helper supports two credential approaches, both of which require `application_credentials` support: application-provided credentials (where the integration ships its own client ID and client secret) and user-provided credentials (where the user supplies their own OAuth 2.0 client credentials via the UI).

As per coding guidelines: "Apply the Microsoft Style Guide to ensure documentation maintains clarity and conciseness."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
The helper supports two credential approaches, both of which require `application_credentials` support: application provided credentials (where the integration ships its own client ID and client secret) and user-provided credentials (where the user supplies their own OAuth 2.0 client credentials via the UI).
The helper supports two credential approaches, both of which require `application_credentials` support: application-provided credentials (where the integration ships its own client ID and client secret) and user-provided credentials (where the user supplies their own OAuth 2.0 client credentials via the UI).
🧰 Tools
🪛 LanguageTool

[grammar] ~20-~20: Use a hyphen to join words.
Context: ...cation_credentials` support: application provided credentials (where the integrat...

(QB_NEW_EN_HYPHEN)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/oauth2.md` at line 20, Rewrite the sentence to clearly name and
hyphenate the two approaches: use "application-provided credentials" to mean the
integration ships its own client ID and client secret, and "user-provided
credentials" to mean the end user supplies their own OAuth 2.0 client
credentials via the UI; keep the reference to `application_credentials` and
ensure compound adjectives are hyphenated (e.g., "application-provided" and
"user-provided") and the sentence remains concise per Microsoft Style Guide.

Comment thread docs/oauth2.md
Comment on lines +88 to +99
async def async_oauth_create_entry(self, data: dict) -> dict:
"""Create an oauth config entry or update existing entry for reauth."""
self.async_set_unique_id(user_id)
if self.source == SOURCE_REAUTH:
self._abort_if_unique_id_mismatch()
return self.async_update_reload_and_abort(
self._get_reauth_entry(),
data_updates=data,
)
self._abort_if_unique_id_configured()
return await super().async_oauth_create_entry(data)
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for examples of async_oauth_create_entry in the Home Assistant codebase to find correct pattern

rg -nP -A10 'async_oauth_create_entry' --type=py -g '!test*' -C3

Repository: home-assistant/developers.home-assistant

Length of output: 232


🏁 Script executed:

cat -n docs/oauth2.md | sed -n '80,110p'

Repository: home-assistant/developers.home-assistant

Length of output: 1470


🏁 Script executed:

cat -n docs/oauth2.md | sed -n '60,99p'

Repository: home-assistant/developers.home-assistant

Length of output: 2038


🏁 Script executed:

cat -n docs/oauth2.md | sed -n '99,130p'

Repository: home-assistant/developers.home-assistant

Length of output: 1889


🏁 Script executed:

rg -n 'user_id' docs/oauth2.md -B3 -A3

Repository: home-assistant/developers.home-assistant

Length of output: 437


🏁 Script executed:

# Search for actual working oauth2 implementations or references in the documentation
rg -n 'async_set_unique_id' docs/oauth2.md -B5 -A5

Repository: home-assistant/developers.home-assistant

Length of output: 584


🏁 Script executed:

# Search for examples of how other methods extract data or set unique_id in the file
rg -n 'async_step_user\|data\[' docs/oauth2.md -B2 -A2 | head -50

Repository: home-assistant/developers.home-assistant

Length of output: 66


🏁 Script executed:

# Check the beginning of the file for context and other examples
cat -n docs/oauth2.md | head -60

Repository: home-assistant/developers.home-assistant

Length of output: 3444


🏁 Script executed:

# Look for any comments or docstrings that might explain what data contains or where user_id comes from
cat -n docs/oauth2.md | sed -n '30,100p' | grep -i 'user\|data\|unique'

Repository: home-assistant/developers.home-assistant

Length of output: 1306


Extract user_id from the data parameter on line 90.

The code example references an undefined user_id variable. Since the function receives data: dict, extract the user identifier from it. Change line 90 to: self.async_set_unique_id(data['user_id']) or use data.get('user_id') depending on whether user_id is guaranteed to be present.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/oauth2.md` around lines 88 - 99, In async_oauth_create_entry, the code
calls self.async_set_unique_id(user_id) but user_id is undefined; extract the id
from the incoming data dict (e.g., obtain user_id = data.get('user_id') or
data['user_id'] depending on guarantees) and pass that to
self.async_set_unique_id, and if using get() add a guard to handle a missing
user_id (raise/abort with a clear error) before continuing; update the reference
in async_oauth_create_entry accordingly.

Comment thread docs/oauth2.md
Comment on lines +143 to +154
### Integrations without a Data Update Coordinator

If your integration does **not** use a coordinator, you must handle the exceptions explicitly wherever you do a token request, e.g. call `async_ensure_token_valid()`. The coordinator automatically maps the new exceptions to the correct behavior:

- `OAuth2TokenRequestReauthError` raises ConfigEntryAuthFailed, triggering a reauthentication flow
- `OAuth2TokenRequestTransientError` is treated as UpdateFailed, triggering the coordinator's retry mechanism

Make sure to do a first coordinator refresh during config entry setup, to ensure the access token is refreshed before entities are set up:

```python
await coordinator.async_config_entry_first_refresh()
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Remove contradictory content from non-coordinator section.

This section is titled "Integrations without a Data Update Coordinator" but:

  1. Lines 145-148 discuss coordinator behavior (duplicated from lines 138-141)
  2. Lines 150-154 show coordinator code (coordinator.async_config_entry_first_refresh())

This content doesn't belong in the non-coordinator section and will confuse readers.

♻️ Proposed fix
 ### Integrations without a Data Update Coordinator
 
-If your integration does **not** use a coordinator, you must handle the exceptions explicitly wherever you do a token request, e.g. call `async_ensure_token_valid()`. The coordinator automatically maps the new exceptions to the correct behavior:
-
-- `OAuth2TokenRequestReauthError` raises ConfigEntryAuthFailed, triggering a reauthentication flow
-- `OAuth2TokenRequestTransientError` is treated as UpdateFailed, triggering the coordinator's retry mechanism
-
-Make sure to do a first coordinator refresh during config entry setup, to ensure the access token is refreshed before entities are set up:
-
-```python
-await coordinator.async_config_entry_first_refresh()
-```
+If your integration does **not** use a coordinator, handle the exceptions explicitly wherever you call `async_ensure_token_valid()`:
 
 ```python

As per coding guidelines: "Apply the Microsoft Style Guide to ensure documentation maintains clarity and conciseness."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Integrations without a Data Update Coordinator
If your integration does **not** use a coordinator, you must handle the exceptions explicitly wherever you do a token request, e.g. call `async_ensure_token_valid()`. The coordinator automatically maps the new exceptions to the correct behavior:
- `OAuth2TokenRequestReauthError` raises ConfigEntryAuthFailed, triggering a reauthentication flow
- `OAuth2TokenRequestTransientError` is treated as UpdateFailed, triggering the coordinator's retry mechanism
Make sure to do a first coordinator refresh during config entry setup, to ensure the access token is refreshed before entities are set up:
```python
await coordinator.async_config_entry_first_refresh()
```
### Integrations without a Data Update Coordinator
If your integration does **not** use a coordinator, handle the exceptions explicitly wherever you call `async_ensure_token_valid()`:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/oauth2.md` around lines 143 - 154, Remove the contradictory
coordinator-specific text and code from the "Integrations without a Data Update
Coordinator" section: delete the paragraphs that describe coordinator behavior
and the example call to coordinator.async_config_entry_first_refresh(), and
instead state clearly that integrations without a Data Update Coordinator must
call async_ensure_token_valid() and handle OAuth2TokenRequestReauthError and
OAuth2TokenRequestTransientError at each token request site; keep references to
the exception types (OAuth2TokenRequestReauthError,
OAuth2TokenRequestTransientError) and the function name async_ensure_token_valid
to guide readers, and ensure the surrounding text and code fence reflect a
non-coordinator workflow only.

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