Skip to content

feat(auth): accept Bearer + Hawk on all FxA token routes#20547

Open
vbudhram wants to merge 1 commit into
mainfrom
fxa-9392
Open

feat(auth): accept Bearer + Hawk on all FxA token routes#20547
vbudhram wants to merge 1 commit into
mainfrom
fxa-9392

Conversation

@vbudhram
Copy link
Copy Markdown
Contributor

@vbudhram vbudhram commented May 8, 2026

Because

  • ADR-0022 sanctioned dropping Hawk for in-monorepo callers; the 2024 attempt was reverted because plain Bearer <hex> collided with the OAuth refresh-token strategy on the same routes.
  • Hawk's host/uri/payload MAC adds no real value when auth-client and auth-server live in the same monorepo, but every authenticated browser call still pays the cost.

This pull request

  • Adds a server-side bearer-fxa-token Hapi scheme accepting Authorization: Bearer <prefix>_<hex> (fxs_, fxk_, fxar_, fxpf_, fxpc_). The GitHub/Stripe-style prefix keeps the wire format disjoint from refresh tokens and Hawk so all three coexist on the same route.
  • Flips ~65 auth configs across 17 route files to multi-strategy chains (Bearer first, Hawk fallback), including the deprecated /account/sessions. Extracts makePostLookupGuard so verifiedSessionToken enforces the same email/token/AAL2 checks on both paths.
  • Fixes the Hawk scheme's missing-header branch to honor throwOnFailure: false for clean fall-through, and adds an auth.strategy.used{scheme,kind} StatsD counter for migration observability.
  • Migrates fxa-auth-client to bearerHeader/authedRequest, deletes the Hawk signing code in lib/hawk.ts, and adds test/no-hawk-signing.ts as a regression guard.
  • Hardens lib/sentry.js filterExtras with an explicit header allowlist and an unanchored value-pattern redactor (/\bfx[a-z]+_[0-9a-f]{64}\b/) so a bearer token id cannot leak into Sentry, even embedded in a stack frame.
  • Updates ADR-0022 to "Partially Implemented"; server-side Hawk stays for external clients (Firefox Desktop, iOS, Android, Sync).

Issue that this pull request solves

Closes: https://mozilla-hub.atlassian.net/browse/FXA-9392

Checklist

Put an x in the boxes that apply

  • My commit is GPG signed.
  • If applicable, I have modified or added tests which pass locally.
  • I have added necessary documentation (if appropriate).
  • I have verified that my changes render correctly in RTL (if appropriate).
  • I have manually reviewed all AI generated code.

Other information

How to test:

  1. nx test-unit fxa-auth-server and nx test-unit fxa-auth-client. Remote suite covers the Bearer path via bearer_scheme_registered.in.spec.ts and the Bearer arm of totp.in.spec.ts; test/client/api.js continues to exercise Hawk fallback.
  2. Manual: sign in via fxa-settings, exercise /account/keys, /recovery_email/status, /account/sessions, TOTP verify. DevTools should show Bearer fxs_<hex> / Bearer fxk_<hex> headers. Hawk callers (Firefox Desktop / Sync) are unaffected.

Note: Token replay scope widens under Bearer (no host/uri/nonce binding); rotation cadence and the customs ratelimiter remain the primary mitigations, as documented in ADR-0022.

Copilot AI review requested due to automatic review settings May 8, 2026 16:27
@vbudhram vbudhram requested a review from a team as a code owner May 8, 2026 16:27
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates FxA’s authenticated “token routes” to accept a new prefixed Bearer token wire format alongside the existing Hawk scheme, enabling a gradual migration away from client-side Hawk signing while keeping server-side Hawk support for external clients.

Changes:

  • Introduces a new bearer-fxa-token Hapi auth scheme and registers Bearer strategies for FxA token kinds (session/keyFetch/accountReset/passwordForgot/passwordChange), plus a Bearer variant of verifiedSessionToken.
  • Switches many auth-server routes to multi-strategy auth chains (Bearer first, Hawk fallback), and adds StatsD instrumentation for observing strategy usage during migration.
  • Migrates fxa-auth-client to emit prefixed Bearer headers, removes Hawk signing code, and adds regression tests/guards to prevent Hawk signing from returning.

Reviewed changes

Copilot reviewed 41 out of 41 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/fxa-settings/src/lib/auth-key-stretch-upgrade.ts Uses the new token-credential derivation alias (scheme-neutral naming).
packages/fxa-auth-server/test/remote/totp.in.spec.ts Adds an integration test covering Bearer auth for /totp/verify; formatting tweaks.
packages/fxa-auth-server/test/remote/bearer_scheme_registered.in.spec.ts Adds a remote smoke test around Bearer behavior (currently described as “registration-only”).
packages/fxa-auth-server/lib/server.js Registers Bearer token auth schemes/strategies and Bearer verified-session strategy; adds strategy-used metrics wiring.
packages/fxa-auth-server/lib/sentry.spec.ts Adds tests ensuring cookie headers and prefixed token values are redacted.
packages/fxa-auth-server/lib/sentry.js Hardens Sentry extras filtering with header allowlist + token-value pattern redaction.
packages/fxa-auth-server/lib/routes/totp.js Switches relevant TOTP routes to Bearer+Hawk multi-strategy auth.
packages/fxa-auth-server/lib/routes/session.js Switches session routes to Bearer+Hawk multi-strategy auth.
packages/fxa-auth-server/lib/routes/security-events.js Switches to Bearer+Hawk multi-strategy verified session auth.
packages/fxa-auth-server/lib/routes/recovery-phone.ts Switches routes to Bearer+Hawk multi-strategy auth; updates strategy checks.
packages/fxa-auth-server/lib/routes/recovery-phone.spec.ts Updates route auth expectations to Bearer-first multi-strategy.
packages/fxa-auth-server/lib/routes/recovery-key.js Switches recovery key routes to Bearer+Hawk multi-strategy auth.
packages/fxa-auth-server/lib/routes/recovery-codes.js Switches recovery codes routes to Bearer+Hawk multi-strategy auth.
packages/fxa-auth-server/lib/routes/password.ts Switches password routes to Bearer+Hawk multi-strategy auth.
packages/fxa-auth-server/lib/routes/passkeys.ts Switches passkeys route auth to Bearer+Hawk multi-strategy.
packages/fxa-auth-server/lib/routes/oauth/token.js Allows sessionToken Bearer on optional session auth for /oauth/token.
packages/fxa-auth-server/lib/routes/oauth/key_data.js Switches key-data route auth to Bearer+Hawk multi-strategy.
packages/fxa-auth-server/lib/routes/oauth/authorization.js Switches authorization route auth to Bearer+Hawk multi-strategy.
packages/fxa-auth-server/lib/routes/newsletters.js Adds sessionToken Bearer to strategy list and updates session-token detection.
packages/fxa-auth-server/lib/routes/mfa.ts Switches MFA routes to Bearer+Hawk verified-session auth.
packages/fxa-auth-server/lib/routes/linked-accounts.ts Switches linked-accounts route auth to Bearer+Hawk multi-strategy.
packages/fxa-auth-server/lib/routes/geo-location.ts Switches geo route auth to Bearer+Hawk multi-strategy; formatting tweaks.
packages/fxa-auth-server/lib/routes/emails.js Switches email routes to Bearer+Hawk multi-strategy auth.
packages/fxa-auth-server/lib/routes/devices-and-sessions.js Adds sessionToken Bearer into sessionToken/refreshToken strategy lists.
packages/fxa-auth-server/lib/routes/auth-schemes/verified-session-token.js Extracts shared post-lookup guard for both Hawk and Bearer verified-session strategies.
packages/fxa-auth-server/lib/routes/auth-schemes/hawk-fxa-token.spec.ts Adds tests for throwOnFailure fallthrough semantics and strategy-used metric.
packages/fxa-auth-server/lib/routes/auth-schemes/hawk-fxa-token.js Adds throwOnFailure-respecting fallthrough behavior + StatsD strategy-used metric.
packages/fxa-auth-server/lib/routes/auth-schemes/bearer-fxa-token.spec.ts Adds comprehensive tests for Bearer scheme parsing, fallthrough, hooks, and metrics.
packages/fxa-auth-server/lib/routes/auth-schemes/bearer-fxa-token.js Implements new prefixed Bearer auth scheme for FxA token kinds, with fallthrough semantics.
packages/fxa-auth-server/lib/routes/attached-clients.spec.ts Updates route auth expectation to Bearer-first multi-strategy.
packages/fxa-auth-server/lib/routes/attached-clients.js Switches attached-clients routes to Bearer+Hawk multi-strategy auth.
packages/fxa-auth-server/lib/routes/account.ts Switches account routes to Bearer+Hawk multi-strategy auth; updates strategy-based branching.
packages/fxa-auth-client/test/no-hawk-signing.ts Adds regression guard ensuring Hawk signing calls aren’t reintroduced.
packages/fxa-auth-client/test/hawk.ts Updates Hawk tests to cover only HKDF credential derivation + alias behavior.
packages/fxa-auth-client/test/bearer.ts Adds Bearer header format/prefix test vectors.
packages/fxa-auth-client/server.ts Re-exports new Bearer helper module.
packages/fxa-auth-client/package.json Adds export map entry for ./lib/bearer.
packages/fxa-auth-client/lib/hawk.ts Removes Hawk signing implementation; keeps HKDF derivation and adds deriveTokenCredentials alias.
packages/fxa-auth-client/lib/client.ts Migrates request auth to prefixed Bearer headers and removes Hawk timestamp handling.
packages/fxa-auth-client/lib/bearer.ts Adds bearerHeader helper and prefix table for token kinds.
docs/adr/0022-deprecate-hawk.md Updates ADR status and documents the Bearer migration approach.
Comments suppressed due to low confidence (1)

packages/fxa-auth-client/lib/client.ts:463

  • authedRequest now types kind as BearerTokenKind, but call sites pass tokenType.* (a string enum). In TypeScript, string enums are not assignable to a union of string literals, so this is likely to fail tsc --build for fxa-auth-client. Consider removing tokenType in favor of BearerTokenKind (or making tokenType a literal-union/const object) so the types line up.
  private async authedRequest(
    method: string,
    path: string,
    token: hexstring,
    kind: BearerTokenKind,
    payload: object | null,
    extraHeaders: Headers | undefined
  ) {
    if (extraHeaders === undefined) {
      if (this.requireHeaders) {
        await this.errorHandler(new Error('extraHeaders missing!'));
        return;
      } else {
        extraHeaders = new Headers();
      }
    }

    const headers = await bearerHeader(token, kind);
    for (const [name, value] of extraHeaders) {
      headers.set(name, value);
    }
    return this.request(method, path, payload, headers);
  }

  private async sessionGet(
    path: string,
    sessionToken: hexstring,
    headers?: Headers
  ) {
    return this.authedRequest(
      'GET',
      path,
      sessionToken,
      tokenType.sessionToken,
      null,
      headers
    );

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +10 to +33
// M1 smoke test: the Bearer scheme is registered at server boot but no route
// is wired to it yet. Sending a valid-looking Bearer header at a Hawk-only
// route must still 401 — this proves registration has no side effects on
// existing routes, and that a bare Bearer header is not accidentally
// accepted anywhere in the monorepo prior to M2.
let server: TestServerInstance;
let serverPort: number;

beforeAll(async () => {
server = await getSharedTestServer();
const url = new URL(server.publicUrl);
serverPort = parseInt(url.port, 10);
}, 120000);

afterAll(async () => {
await server.stop();
});

describe('#integration - Bearer scheme registration', () => {
it('rejects a Bearer-on-Hawk-route request with 401 (no route accepts Bearer yet)', async () => {
const hex64 = 'a'.repeat(64);
const res = await fetch(
`http://localhost:${serverPort}/v1/session/destroy`,
{
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.

Before I even saw this copilot comment, I was confused by the test name.

Comment thread docs/adr/0022-deprecate-hawk.md Outdated
- Deciders: Danny Coates, Ryan Kelly, Les Orchard, Ben Bangert
- Date: 2020-05-27
- Status: Partially Implemented (2026-04-23) — client-side Bearer migration complete
(FXA-9392, see `ai/docs/exec-plans/active/fxa-9392-hawk-to-bearer-migration.md`);
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.

@vbudhram did you mean to check that in?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Woops, I did not, cleaned this up.

Comment thread docs/adr/0022-deprecate-hawk.md Outdated

### 2026-04-23 update — client-side migration complete (FXA-9392)

The interim scheme chosen was **prefixed Bearer tokens** on the Authorization header (`Authorization: Bearer <prefix>_<hex>`, where `<prefix>` identifies the token kind: `fxs_`, `fxk_`, `fxkv_`, `fxar_`, `fxpf_`, `fxpc_`). The prefix avoids collisions with the refresh-token Bearer strategy on routes that accept both. Routes use Hapi multi-strategy chains, trying Bearer first and falling back to Hawk.
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.

This true, the code changes don't contain fxkv_

@vbudhram vbudhram force-pushed the fxa-9392 branch 2 times, most recently from 310fac1 to 0a323ca Compare May 11, 2026 20:50
@vbudhram vbudhram self-assigned this May 11, 2026
expect(res.authAt).toBeTruthy();
});

it('should reset password after verifying totp via Bearer header (M2 FXA-9392)', async () => {
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.

Remove issue number from test name.

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 is 'M2'?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Surprised this didn't get flagged by my review skill, and its in my CLAUDE.md 🤔

Comment thread packages/fxa-auth-server/lib/sentry.js Outdated
// always be redacted before reaching Sentry. This is the primary mechanism;
// the substring fallback below catches anything new that follows the old
// naming heuristics until it gets added here explicitly.
const SENSITIVE_KEY_ALLOWLIST = new Set([
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 don't understand why we can't have a single list. Also semantics of ALLOWLIST here is misleading since these terms are not being allowed, and they are actually being redacted.

@@ -703,7 +703,7 @@ module.exports = ({ log, oauthDB, db, mailer, devices, statsd, glean }) => {
// XXX TODO: To be able to fully replace the /token route from oauth-server,
// this route must also be able to accept 'client_secret' as Basic Auth in header.
mode: 'optional',
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.

Just noticed this, and I know it is not part of your changeset, but why mode optional?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This endpoint supports 4 different oauth grant types but only 1 of the grant types (fxa-credentials) passes sessionToken.

Comment on lines +113 to +116
if (!match) {
// Wrong scheme, wrong prefix for this kind, malformed body,
// or any formatting drift (whitespace, mixed case). Let the
// next strategy in the chain try.
Copy link
Copy Markdown
Contributor

@dschom dschom May 13, 2026

Choose a reason for hiding this comment

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

Does the next strategy really try, or does returning this error end the request?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I didn't write an explicit test for this but we used the pattern in other routes so didn't see a reason why it would not fallback. Can write a test for this though if you think its worthwhile.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I did end up adding tests for these

try {
token = await getCredentialsFunc(tokenId);
} catch (_) {
// getCredentialsFunc swallows invalid-hex / expired internally
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.

If it may surface a DB error, but we want to keep going, should we Sentry.captureException?

return h.authenticated({ credentials: token });
},
payload: async function (req, h) {
// Bearer has nothing to verify about the payload. Preserve the
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 thought the reason this was important was due to hawk payload signing? I'm not sure what purpose this serves here, since this strategy does nothing to validate the payload.

await promise;
throw new Error('Should have thrown');
} catch (err: any) {
expect(err).toBeInstanceOf(AppError);
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.

Can we use the idimoatic .rejects jest syntax instead?

throw new Error('Should have thrown');
} catch (err: any) {
expect(err).toBeInstanceOf(AppError);
expect(err.output.payload.code).toBe(401);
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 feel like we can just check these in the tests, or have a function that takes an error object, instead of this awkward try catch.

@vbudhram vbudhram force-pushed the fxa-9392 branch 2 times, most recently from 2eeab4d to d0e0c67 Compare May 13, 2026 18:08
// `statsd` and `kind` are optional; when both are set, emit
// `auth.strategy.used{scheme=hawk, kind=<kind>}` on successful auth so
// the Hawk -> Bearer migration (FXA-9392) has a visible split metric.
const statsd = authStrategyOptions.statsd || null;
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 feel like these shouldn't be optional. Is there a situation where having them as opitional makes sense?

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.

The updates made didn't really address this. They are still essentially optional /shrug

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Pushed a fix to make this more explict.

// Multi-strategy mode: return Boom so Hapi can try the next
// strategy (Bearer / refresh-token / etc.) instead of
// short-circuiting the chain on the missing-header branch.
return Boom.unauthorized(null, 'hawkFxaToken');
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.

In the event there isn't another strategy, does this response have same format as tokenNotFound? Or is it missing an errno? And if so, could this cause issues on the front the end?

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 feel like validating / knowing that this was considered is important for the PR to land.

function strategy(
getCredentialsFunc,
authStrategyOptions = { throwOnFailure: true }
authStrategyOptions = { throwOnFailure: true, statsd: null, kind: null }
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 having the options be required and explicitly stated would be better.

return error;
};

const postLookupGuard = makePostLookupGuard(db, config, statsd);
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 don't understand why this refactor is needed. Nothing wrong with it as far as I can tell, but curious if there was a specific reason this was necessary.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This was just to reuse the email/token/AAL checks instead of duplicating them

auth: {
mode: 'optional',
strategy: 'sessionToken',
strategies: ['sessionTokenBearer', 'sessionToken'],
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'm noticing that over in packages/fxa-auth-server/lib/server.in.spec.ts, this counterpart is set to strategy: 'sessionToken' still.

// fxpc_ passwordChangeToken
const KIND_PREFIXES = {
sessionToken: 'fxs',
keyFetchToken: 'fxk',
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.

The adr implies this should be fxkv

});

it('requires session authorization', () => {
it('requires session authorization (Bearer first, Hawk fallback)', () => {
Copy link
Copy Markdown
Contributor

@dschom dschom May 13, 2026

Choose a reason for hiding this comment

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

String in parens is missleading... Maybe just say it supports strategy fallback? This is an issue for a few other tests in this file.

Copy link
Copy Markdown
Contributor

@dschom dschom left a comment

Choose a reason for hiding this comment

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

@vbudhram. A few comments / clean up. Then I'll do a quick local test and r+.

Because:

ADR-0022 (2020) sanctioned dropping Hawk for in-monorepo callers. FXA-9392
attempted this in 2024 but was reverted because plain "Bearer <hex>"
collided with the refresh-token strategy. This change uses prefixed Bearer
tokens (GitHub/Stripe pattern) so the wire format is disjoint from the
refresh-token scheme.

This commit:

* Adds a server-side bearer-fxa-token Hapi auth scheme. Wire format:
  "Authorization: Bearer <prefix>_<hex>" where the prefix encodes the
  token kind (fxs_, fxk_, fxar_, fxpf_, fxpc_). keyFetchToken and
  keyFetchTokenWithVerificationStatus deliberately share the fxk_ prefix
  on the wire (the client only ever derives one keyFetch credential; the
  with-verification variant differs only in the server-side DB lookup).
  Strategies registered for all six token kinds plus non-throwing
  multi-strategy variants and a verifiedSessionTokenBearer that shares
  the post-lookup guard with the existing Hawk-backed verifiedSessionToken
  (extracted to makePostLookupGuard).
* Flips every protected route (including the deprecated /account/sessions
  endpoint, kept compatible for any client that adopts the Bearer auth-
  client) to a multi-strategy chain with Bearer first and Hawk as
  fallback, around 65 auth configs across 17 files:
  single-strategy session/keyFetch/accountReset/passwordForgot/
  passwordChange/verifiedSession routes, the four-way
  multiStrategySessionToken chains, and the [sessionToken, refreshToken]
  and [sessionToken, oauthToken] chains. Handler-side auth.strategy
  checks broadened to accept the new Bearer variants.
* Fixes the Hawk scheme's missing-header branch to respect
  throwOnFailure: false so multi-strategy chains can fall through
  cleanly. Adds auth.strategy.used{scheme,kind} StatsD counter to both
  schemes for observability of the migration.
* Strategy options are runtime-required: bearer and hawk strategy()
  factories now validate that throwOnFailure, statsd, and (hawk) kind
  are passed explicitly. server.js call sites updated to pass
  throwOnFailure on every registration. Eliminates the prior class of
  bug where a registration silently disappeared from the
  auth.strategy.used dashboard because statsd/kind were omitted.
* All fallthrough error paths in both strategies return an AppError
  with errno=110, "Token not found", isBoom=true instead of
  Boom.unauthorized(null, scheme). A final 401 from a multi-strategy
  chain is wire-compatible with the typed single-strategy "Token not
  found" response. Regression tests assert errno=110 in the
  throwOnFailure=false branches.
* Migrates fxa-auth-client: new lib/bearer.ts::bearerHeader, renames
  hawkRequest to authedRequest, deletes Hawk signing code from
  lib/hawk.ts, switches the three deriveHawkCredentials call sites to
  deriveTokenCredentials. Adds test/no-hawk-signing.ts regression
  guard. Updates fxa-settings/src/lib/auth-key-stretch-upgrade.ts to
  the new alias.
* Hardens fxa-auth-server/lib/sentry.js filterExtras with a single
  key-fragment redact list (auth, cookie, pw, kb, key) plus an
  unanchored value-pattern redactor for prefixed Bearer tokens so
  the raw id cannot leak into Sentry extras even when embedded in a
  larger string (stack frame, URL, error message).
* Updates ADR-0022 status to "Partially Implemented" with notes on
  what is intentionally out of scope (server-side Hawk stays for
  external clients: Firefox Desktop, iOS, Android, Sync).
* Adds ADR-0050 documenting the prefixed-Bearer token naming
  convention, the rejected alternatives (plain Bearer, custom
  Authorization scheme, JWT), and the rules for allocating new
  prefixes.

Tests: auth-server Jest 3414/3414, auth-client Mocha 26/26,
fxa-settings auth-adjacent tests 274/274; tsc clean on auth-server,
auth-client, fxa-settings, fxa-admin-server. Remote test exercising
the Bearer path end-to-end added for /totp/verify; existing remote
suite continues to exercise Hawk fallback because test/client/api.js
sends Hawk headers.

Fixes FXA-9392
@vbudhram
Copy link
Copy Markdown
Contributor Author

@vbudhram. A few comments / clean up. Then I'll do a quick local test and r+.

I think I've address your issues. Give it a try locally, I leaned more into functional tests exercising the flows to give more confidence that its working as intended.

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.

3 participants