Skip to content

Add OAuth 2.0 documentation#2968

Draft
erwindouna wants to merge 25 commits intohome-assistant:masterfrom
erwindouna:oauth-docs
Draft

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

Conversation

@erwindouna
Copy link
Contributor

@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 comprehensive OAuth 2.0 integration guide covering authentication flows, implementation patterns, reauthentication handling, error management, and best practices for building integrations.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 19, 2026

📝 Walkthrough

Walkthrough

A comprehensive OAuth 2.0 documentation page has been added to Home Assistant integration guides, covering implementation helpers, supported flows, configuration, reauthentication, API requests, and error handling. The documentation has been registered in the sidebar navigation.

Changes

Cohort / File(s) Summary
Documentation
docs/oauth2.md
New comprehensive guide detailing OAuth 2.0 support, including built-in helpers, supported flows, implementation patterns, reauthentication, authenticated requests, error handling, usage examples, and best practices.
Navigation
sidebars.js
Added "oauth2" entry to the Core → Building Integrations documentation items.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add OAuth 2.0 documentation' is concise and clearly summarizes the main change—adding comprehensive OAuth 2.0 documentation.
Description check ✅ Passed The description follows the template structure with a clear proposed change, correct type of change selection, and includes relevant context about discussion with maintainers.
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 docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
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.

@home-assistant home-assistant bot marked this pull request as draft February 19, 2026 20:05
@home-assistant
Copy link

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
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.

@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
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

Copy link
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
Contributor Author

Choose a reason for hiding this comment

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

Replaced.

@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
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


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
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.

- 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
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.

| ---------------------------- | ----------------------------------- | ------------------------------- |
| 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
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.

"""Confirm reauthentication."""
if user_input is None:
return self.async_show_form(step_id="reauth_confirm")
return await self.async_step_user()
Copy link
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

@MartinHjelmare MartinHjelmare marked this pull request as draft March 10, 2026 12:49
erwindouna and others added 9 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>
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