Skip to content

feat(auth): migrate FxA token auth from Hawk to prefixed Bearer tokens - #125

Merged
vbudhram merged 1 commit into
mainfrom
update-bearer
Jul 1, 2026
Merged

vbudhram merged 1 commit into
mainfrom
update-bearer

Conversation

@vbudhram

Copy link
Copy Markdown
Contributor

Replace Hawk request-signing with the prefixed-Bearer scheme adopted by the auth-server (ADR-0022/0050): Authorization: Bearer _, where is the existing HKDF-derived token id and identifies the token kind (fxs/fxk/fxar/fxpf/fxpc).

  • Rename HawkTokenAuth to FxATokenBearerAuth; keep HawkTokenAuth as a deprecated alias that emits a DeprecationWarning.
  • Warn when a token would be sent over non-loopback plaintext HTTP, since the Bearer header is now a replayable credential.
  • Remove the unused hawkauthlib dependency and orphaned Hawk-only code.

@vbudhram vbudhram self-assigned this Jun 25, 2026
@vbudhram
vbudhram force-pushed the update-bearer branch 2 times, most recently from 2366762 to c543d36 Compare June 25, 2026 18:12
@vbudhram
vbudhram requested a review from dschom June 29, 2026 15:58
Comment thread fxa/_utils.py
are exempt so local development against an http auth-server still works.
"""
parsed = urlparse(url)
if parsed.scheme == "http" and parsed.hostname not in _LOOPBACK_HOSTS:

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.

Should this error? Seems like a no go to not send these of TLS.

Comment thread fxa/_utils.py Outdated

class HawkTokenAuth(requests.auth.AuthBase):
"""A requests auth hook implementing token-based hawk auth.
_LOOPBACK_HOSTS = frozenset(("localhost", "127.0.0.1", "::1"))

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.

What about 0.0.0.0?

Comment thread fxa/tests/test_utils.py
def test_emits_prefixed_bearer_header_for_session_token(self):
auth = FxATokenBearerAuth(SESSION_TOKEN, "sessionToken")
req = auth(Request())
self.assertEqual(

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.

👍

Comment thread fxa/_utils.py Outdated
if self.apiclient is not None:
params["ts"] = str(int(self.apiclient.server_curtime()))
hawkauthlib.sign_request(req, self.id, self.auth_key, params=params)
_warn_if_token_sent_insecurely(req.url)

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.

I think this should be an error not a warning. Someone might upgrade, and this should fail fast, imo.

@dschom dschom left a comment

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.

Thanks! Looking pretty good. Two small things before approval:

  1. Fail fast if we aren't TLS (ie https).
  2. Delete the clock skew stuff. That was hawk specific, so its basically dead code with extra overhead at this point. See APIClient class.

Replace Hawk request-signing with the prefixed-Bearer scheme adopted by
the auth-server (ADR-0022/0050): Authorization: Bearer <prefix>_<id>,
where <id> is the existing HKDF-derived token id and <prefix> identifies
the token kind (fxs/fxk/fxar/fxpf/fxpc).

- Rename HawkTokenAuth to FxATokenBearerAuth; keep HawkTokenAuth as a
  deprecated alias that emits a DeprecationWarning.
- Add TOKEN_PREFIXES kept in sync with the auth-server/auth-client tables.
- Warn when a token would be sent over non-loopback plaintext HTTP, since
  the Bearer header is now a replayable credential.
- Remove the unused hawkauthlib dependency and orphaned Hawk-only code.
- Add unit tests pinning the per-kind wire format and mocked coverage of
  the migrated core/oauth call sites.
@vbudhram
vbudhram merged commit c394c6c into main Jul 1, 2026
6 checks passed
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