figma guide

Designing breach victim eligibility verification portal UI in Figma: token checks, impact disclosure, and remediation routing

Design breach victim eligibility verification portal UI in Figma with signed token flows, step-up authentication, segment disclosure, monitoring enrollment routing, and handoff for privacy teams.

Published
Updated
Aug 21, 2026
Read time
7 min
Level
Intermediate

Quick answer

Breach victim eligibility verification portal UI lets affected individuals confirm whether their account is in an impacted segment—without exposing other victims’ data or publishing forensic field names on a public page. Design a signed-token entry flow from individual notification links, step-up authentication before account-specific disclosure, segment-level impact summary aligned with notice FAQ NL-* versions, and routing to remediation when eligible. Connect to remediation offers, call center verification, email OTP, and privacy request queue. Start from the Figma guides hub and pair with forms, login recovery, and Dev Mode handoff.


Who this is for

  • Product designers building self-service “Am I affected?” flows after mass breach notification—not generic account login pages.
  • Privacy and engineering teams who need tokenized links that expire, rate-limit, and never put PII in query strings.
  • Support leads who want eligibility outcomes to match call center and FAQ answers.

Portal entry and token model

EligibilityPortalEntry — Incident VIN-992 · Campaign IND-441 · Token model v2
├── Entry paths:
│   ├── Signed link from email/SMS — token in path segment, not ?email=
│   ├── Manual check — Email + incident reference from notice letter
│   └── Call center handoff — Agent generates one-time link after Tier 2 verification
├── Token properties (design for handoff):
│   ├── incident_id (VIN-992) · campaign_id (IND-441) · expires_at · single_use (optional)
│   ├── No account_id in URL — resolved server-side after auth
│   └── Invalid/expired → Friendly error + link to [notice FAQ](/designing-breach-faq-and-notice-landing-page-ui-in-figma/)
├── Rate limiting UI:
│   ├── 5 attempts / 15 min per IP · CAPTCHA after 3 failures
│   └── Lockout message — "Try again later or call support" · No hint if email exists
├── Locale: Match [individual notification](/designing-affected-individual-breach-notification-and-communication-ui-in-figma/) segment
└── Analytics: Aggregate completion rate only · No per-user funnel tracking on breach URL
ElementPurpose
Signed token in pathPrevents tampering and email enumeration via query params
Incident reference fieldSupports users who lost email link but have postal notice code
Expired token stateDirects to public FAQ—not “contact us” dead end
No PII in URLShareable screenshots and browser history stay safe

Verdict: The portal is not a login page—it is a bounded disclosure session tied to one incident and one identity proof.


Step-up authentication and verification tiers

VerificationFlow — Session ELIG-8821 · Step 2 of 3 · Incident VIN-992
├── Tier 0 — Token-only (pre-authenticated from email link):
│   ├── Show generic "We are verifying your eligibility" · Spinner
│   └── If token binds to account → Skip to Tier 1 OTP
├── Tier 1 — Email confirmation:
│   ├── Display masked email: j***@example.com (from token, not user input)
│   ├── Send OTP → [email verification UI](/designing-email-verification-and-otp-ui-in-figma/) pattern
│   └── Wrong email? → Manual check path with incident reference
├── Tier 2 — Additional factor (high-risk incidents):
│   ├── Last 4 of phone on file OR zip code · Match [call center Tier 1](/designing-breach-call-center-and-agent-script-ui-in-figma/)
│   ├── Required before account-specific data category list
│   └── 3 failures → Lock session · Offer callback ticket with incident tag
├── Session limits:
│   ├── 30-minute idle timeout · Re-auth to view impact again
│   └── One active session per account per incident
└── Audit: session_id · verification_tiers_passed[] · faq_version (NL-992-v3) · outcome

Design progress stepper consistent with progress indicators elsewhere—users under stress need predictable steps, not a surprise MFA wall.


Impact disclosure and eligibility outcome

ImpactDisclosurePanel — ELIG-8821 verified · Outcome: Affected · FAQ NL-992-v3
├── Outcome states (mutually exclusive):
│   ├── Affected — Account in IND-441 segment
│   ├── Not affected — Account outside confirmed scope (explain scope definition)
│   ├── Unable to determine — Investigation ongoing · Link to notice updates
│   └── Duplicate check — Already enrolled in monitoring · Show status
├── Affected view:
│   ├── Plain-language summary — Same categories as [notice FAQ](/designing-breach-faq-and-notice-landing-page-ui-in-figma/)
│   ├── Data categories involved — "Email, name, hashed password" · Not column names
│   ├── Recommended actions — Password reset · Enable 2FA · Watch for phishing
│   ├── Primary CTA — [Enroll in credit monitoring](/designing-breach-remediation-offers-and-credit-monitoring-enrollment-ui-in-figma/)
│   └── Secondary — Download notice PDF · Contact support
├── Not affected view:
│   ├── Explain why (e.g., account created after incident window)
│   ├── Link to general [trust center](/designing-trust-center-and-security-documentation-ui-in-figma/) security tips
│   └── Option to register for updates if scope expands
├── Version stamp: Impact text locked to NL-992-v3 · Banner if FAQ updated since session start
└── Print / email summary — Optional receipt with incident ref · No full account details
OutcomeShowHide
AffectedCategory-level impact, remediation CTAOther users’ data, exact record counts
Not affectedScope explanationWhy other segments were hit
UnknownTimeline for updateSpeculative categories

Verdict: Disclosure copy must reuse FAQ blocks—do not let engineering inject forensic field names in the eligibility API response UI.


Remediation routing and support handoff

RemediationRouter — ELIG-8821 · Affected · Monitoring offer MON-992-A
├── Pre-fill enrollment:
│   ├── Pass signed session token to [remediation UI](/designing-breach-remediation-offers-and-credit-monitoring-enrollment-ui-in-figma/)
│   ├── Eligibility flag: MON-992-A · Expires 2026-11-26
│   └── Skip re-verification if session < 15 min old
├── Decline monitoring:
│   ├── Capture optional reason (aggregate analytics only)
│   └── Still show password reset and security checklist links
├── Support escalation:
│   ├── "I disagree with this outcome" → [privacy request queue](/designing-privacy-request-queue-and-case-management-ui-in-figma/) DSAR-style case
│   ├── Pre-fill incident_id · session_id · verification log reference
│   └── SLA banner — "We respond within X days per [privacy settings](/designing-privacy-settings-and-data-management-ui-in-figma/)"
├── Call center parity:
│   └── Agent sees same outcome enum when caller completes portal · [Script sync](/designing-breach-call-center-and-agent-script-ui-in-figma/)
└── Re-check flow: User returns after scope expansion → New IND-* token · Show changelog from notice v3 → v4

Comparison: eligibility portal vs adjacent surfaces

SurfaceFocusThis UI adds
Notice FAQPublic generic answersAccount-specific affected / not affected outcome
Individual notificationOutbound email/SMSInbound confirmation and remediation routing
Remediation offersEnrollment formsEligibility proof before offer display
Call center scriptsVoice verificationSelf-service parity for same tiers
Privacy queueDSAR and disputesDisputed eligibility cases

Handoff checklist (Dev Mode)

  • EligibilityPortal — incident_id, campaign_id, entry_mode (token, manual, agent), faq_version_id (NL-*), locale.
  • EligibilityToken — token_id, incident_id, expires_at, single_use, masked_email_hint, status.
  • VerificationSession — session_id, token_id, tiers_passed[], locked_at, outcome_enum, faq_version_at_disclosure.
  • ImpactDisclosure — outcome, data_categories[], recommended_actions[], remediation_offer_id, copy_block_ids[].
  • RemediationHandoff — session_id, offer_id (MON-*), prefill_token, skip_reauth_window_minutes.
  • DisputeCase — links to privacy queue case_id, session audit reference.
  • ErrorStates — expired_token, rate_limited, verification_failed, scope_unknown — each with CTA URLs.

Common mistakes

MistakeWhy it hurtsFix
?email=user@x.com in notification linksEnumeration, leak via referrerSigned opaque token only
Show “not affected” without scope explanationUsers assume company is hiding truthLink to FAQ scope definition
Full forensic detail after loginHelps attackers; overwhelms usersCategory-level copy from NL-* blocks
Different outcome than call centerTrust collapseShared outcome enum and FAQ version
No session timeout on shared computersAccount impact visible to next user30-min idle + re-auth
Track per-user analytics on portalPrivacy violation on breach flowAggregate metrics only
Monitoring CTA without eligibility proofLegal exposure for unfunded offersPass MON-* flag from verified session
Portal works but notice FAQ is draftDisclosure without public recordGate portal on NL-* published state

  1. Define outcome enums and verification tiers with legal before wireframes—tiers map to data sensitivity of disclosure.
  2. Reuse FAQ copy components from notice landing page for affected and not-affected panels.
  3. Generate tokens in individual notification campaign builder—one token model per IND-* wave.
  4. User-test error states (expired link, wrong OTP) with plain-language recovery paths.
  5. Sync with call center so agents generate equivalent one-time links and see matching outcomes.
  6. Archive session audit samples (redacted) to compliance exports if jurisdiction requires proof of disclosure method.

FAQ

Should users log in with their normal password first?

Not as the first step. Prefer token + OTP to email on file—password login conflates breach response with account recovery and excludes users who forgot passwords during panic.

Can one token work for a household?

Design for one account per token. Family plans need separate notifications and tokens per account holder.

What if scope expands after “not affected”?

Trigger new IND- wave* with fresh tokens; show in-portal banner: “Scope updated since your last check—please verify again.”

Manual check without email access?

Offer postal notice code + last name + zip path with higher manual review rate—route edge cases to privacy queue.

Mobile vs desktop layout?

Mobile-first—most users open email links on phones. Use progress steppers and large tap targets; avoid multi-column impact tables on narrow viewports.


Next steps

Share on X

§ Keep reading

Related guides.