Skip to content

Rewrite openapi.yml contract for Firefox Breach Integration Phase 2 (mntor-5342) - #6817

Merged
GregHilstonMozilla merged 40 commits into
mainfrom
mntor-5342
Sep 9, 2026
Merged

GregHilstonMozilla merged 40 commits into
mainfrom
mntor-5342

Conversation

@GregHilstonMozilla

@GregHilstonMozilla GregHilstonMozilla commented Aug 25, 2026 •

Copy link
Copy Markdown
Collaborator

References:

Jira: MNTOR-5342

Description

Rewrites openapi.yml, the contract between Monitor and the Firefox privacy panel. This is to support the Firefox Breach Integration Phase 2

Must not be merged until #6818 is merged, and deployed

The substantive changes:

  • Thin response. { id, breachedAccounts } only. Firefox already has breach metadata from Remote Settings and joins on the HIBP name.
  • Scoped server-side, no data-class filters.
  • Serves email-only breaches, not just password breaches. (This is what depends on Sync email-only breaches to Remote Settings (mntor-5363) #6818 )
  • Errors have a stable code to branch on, a documented body, and examples.
  • A failed HIBP lookup is a 503. It used to be an empty 200, which would have told the panel to clear a user's breach state during an outage.

Also adds redocly.yaml and a README section on validating the contract.

How to test

npx @redocly/cli@2 lint passes. No code changes, nothing to run.

Render the docs to read it as Firefox will: npx @redocly/cli@2 preview-docs openapi.yml

OR use something like editor.swagger.io

Checklist (Definition of Done)

  • Commits in this PR are minimal and have descriptive commit messages.
  • I've added or updated the relevant sections in readme and/or code comments

@GregHilstonMozilla GregHilstonMozilla self-assigned this Aug 25, 2026
Comment thread openapi.yml
@GregHilstonMozilla
GregHilstonMozilla requested review from Vinnl, codemist, groovecoder, joeherm and mansaj and removed request for groovecoder September 2, 2026 16:19
Comment thread openapi.yml Outdated
Comment thread openapi.yml
Comment thread openapi.yml
Comment thread openapi.yml

@Vinnl Vinnl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Not an expert in API design, but the general approach seems right to me and workable from the frontend.

Comment thread openapi.yml
Comment on lines 203 to +206
- name: domain
in: query
required: false
description: >
Filter breaches by the breached site's primary domain (exact match), e.g. "example.com".
description: Filter by the breached site's primary domain, matched exactly. A breach filed under `twitter.com` does not match `x.com`.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Since (I think?) we're not planning to use this, would it maybe be safer to leave it out? So that future contributors can be sure that it's unused.

Comment thread openapi.yml Outdated
Comment on lines +63 to +75
emails:
type: array
minItems: 1
description: Email addresses to target. Omit it to target every monitored address the breach affected.
items:
type: string
isSensitive:
description: Indicates if the breach is considered [sensitive](https://haveibeenpwned.com/FAQs#SensitiveBreach)
type: boolean
format: email
dataClasses:
type: array
minItems: 1
description: Data classes to mark resolved for the selected emails. Each must be one the referenced breach actually leaked, so a breach that leaked only email addresses takes `email-addresses`, not `passwords`. Sending one it did not leak is a `400`, so refresh your Remote Settings copy before retrying.
items:
$ref: "#/components/schemas/DataClass"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Maybe we should leave those out? I think in the designs I've seen, the user can only resolve everything at once (or at least, email and password leaks for all affected emails), so it might not be worth taking up the maintenance burden.

@GregHilstonMozilla
GregHilstonMozilla marked this pull request as ready for review September 9, 2026 14:31
Provisioning is not part of this integration, so POST /user does not
belong in the contract.
/api/v1/user/breaches is already the web app's session-authenticated
route. Presumably he front end develops against stage. info.version
disagreed with the /v1 in the path.
Remote Settings gives Firefox every breach keyed by HIBP name, so the
response only needs that name to join on. Says so at both the response
id and the request breachId, since a numeric id was the likelier read.
We keep a checked list, IE no timestamp, and no way back. A resolved
flag invites an undo we do not support.
The panel's one action is "Mark as done" on a password, and Firefox
already holds every breach's data classes from Remote Settings. Sending
a user's other exposures would be unnecessary data with no consumer, so
the server narrows this down to what is only used today. With an easy
way to extend this later, that is backwards compatible.
An empty batch is a client bug, not a convenience. Firefox's one write
is a single "Mark as done", so nothing computes an empty list. minItems
makes it a validation failure.
Product wants the panel to alert on an email-only breach, and Vincent
wants about:passwords to warn on the same ones. Depends on MNTOR-5363
widening the Remote Settings sync, so the join guarantee is now
explicit: every id we return resolves in fxmonitor-breaches.
The privacy panel must not surface a sensitive breach. So
the rule moves server side and the parameter goes away.
We check users against HIBP live per request, and a failed check
currently reads as "no breaches found", so an outage would have told
every client its user was clear, which is not desired.

Freshness now covers only the catalog, the one thing we cache. While
the 503 tells clients to keep the state they hold.
The request body has always required each data class to be one the
breach actually leaked.
DataClass said to treat it as an open set while listing an enum, which
is the closed type...
Every other failure has a documented shape and the most ordinary one
had none, so a client had nothing to code against if we break.
Every response shape was a named component and the POST body item was
inline, so a generated client had to invent a name
The privacy panel has one "mark all as done" control, so the emails
array was future-proofing for a UI we are not building.
@GregHilstonMozilla
GregHilstonMozilla added this pull request to the merge queue Sep 9, 2026
Merged via the queue into main with commit ba0ef7a Sep 9, 2026
19 checks passed
@GregHilstonMozilla
GregHilstonMozilla deleted the mntor-5342 branch September 9, 2026 14:49
@GregHilstonMozilla GregHilstonMozilla changed the title Mntor 5342 Rewrite openapi.yml contract for Firefox Breach Integration Phase 2 (mntor-5342) Oct 16, 2026
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