Appearance
MFA code store
Supplier-portal browser automations (playwright-automations, and the older stagehand-automations workers) sign in to portals that send a one-time code by email or SMS. n8n catches those codes and keeps the latest one per provider in dbo.EthMFAAsAService; the WebAPI serves it.
Data
dbo.EthMFAAsAService — one row per provider, overwritten on every new code.
| Column | |
|---|---|
service_provider_name | Provider as n8n names it, e.g. Sedgwick (RepairLine), Unity (Auto & General) |
latest_mfa_code | The code |
updated_at | UTC, when n8n stored it. Null on old rows |
Written by n8n "Keep MFA store up to date": the shared mailbox (Outlook poll, every minute) and the SMS forwarder webhook feed an LLM gate and extractor that pull out the provider name and code, then upsert the row with inline SQL. The table, that workflow and the older spEthMFAAsAServiceGetLatest / spEthMFAAsAServiceUpsert procs predate DbMigrations and aren't in it.
API
GET api/Mfa/{serviceProviderName} (Basic auth, like the rest of WebAPI) → 200 { serviceProviderName, latestMfaCode, updatedAt }, or 404 when the provider has no row. Backed by dbo.spEthMFAAsAServiceGetCode (DbMigrations/Scripts/Programmable/Procedures/).
How a caller uses it
A code that's already in the store belongs to an earlier sign-in, so callers:
- Read
updatedAtbefore submitting credentials (the floor). - Submit credentials — the portal sends a new code.
- Poll every few seconds (the automations use 5 s, up to 150 s) and accept only a row whose
updatedAtis later than the floor.
Only the latest code per provider is kept, so two sign-ins to the same provider at once can take each other's code; callers run one sign-in per provider at a time.
Any WebAPI Basic-auth caller can read any provider's latest code.

