Status · 2026-06-22 · Auth PROVEN in sandbox · Azure security-hardened (9 fixes live 2026-06-11)
One tap on a refill-reminder text or email and the patient lands in the refill wizard already logged in — no DOB entry, no verification code. Azure runs the bridge; Salesforce serves the wizard. The mint → redeem → JWT-bridge auth is now proven end-to-end in the sandbox; the storefront itself only renders in production.
Azure platform built, deployed, security-hardened (2026-06-11), and re-verified live (2026-06-22). Auth proven end-to-end in the sandbox. Salesforce-prod go-live not yet started; SFMC real-send gated on credential rotation.
singleaccess bridge. SF
LoginHistory 4/4 success from NAT IP
135.119.140.149, zero failures (2026-05-26).
One live exposure + eight landmines. Adversarially verified; build + 11 tests green. State tags: live deployed to prod · repo / decided shipped in code or a recorded decision.
allow=false
2026-06-22.
usp_CreateMagicLink idempotency revive
live
(contactId, idempotencyKey) after
expiry/auto-revoke no longer hits a
UNIQUE(ShortCodeHash) 500 — the proc now matches in
any state and revives the row; 2627/2601 → THROW 50409.
HashPepperVersion; mint regenerates the
short URL with the row's stored pepper version on replay. Rotation
no longer breaks live links. Unit tests added.
/healthz WAF rate-limit + pepper cache
live
ScannerSuspected for observability;
do not gate the bridge — correct for 72h
multi-use links (a false positive would block a real patient). No
behavioral change.
MagicLink:Settings:Sentinel;
reverting the endpoint values alone won't propagate. Runbook now
says bump the sentinel (or restart) at cutover.
SyncControl bookkeeping
repo
Sync_SFDC_PortalUser_Full now records
SetSyncInProgress / UpdateSyncSuccess + an idempotent bootstrap
row (activates with Phase 2 portal-user sync).
SfmcTokenValidator OIDC caching
repo
ConfigurationManager is cached per metadata
address (it was rebuilt per request) — the validator is a DI
singleton.
When SFMC sends a refill-reminder text or email, the message carries a short URL. The patient taps it once and lands inside the Salesforce refill wizard already logged in — no DOB lookup, no verification code, no password. Three systems each do one thing: SFMC handles the send (hooks into the existing refill-reminder pipeline — no new flow); Azure mints the link, holds the signing key, and runs the OAuth handshake at click time; Salesforce establishes the session and serves the wizard.
The bulk of the build lives in the existing AdvancedRx Azure VNet — the same one that already hosts eFax, the e-script integration, and the patient-matcher service. The Salesforce footprint stays small; §4 lists exactly what's required there.
SFMC sends the message; Azure mints the link, holds the signing key, and runs the OAuth handshake; Salesforce establishes the session and serves the wizard. Three systems, one job each.
singleaccessRefill_Reminder__c scheduled-path flow fires at the
record's Send_Date_Time__c, and
JBSystemFlow_Refill_Reminder_c (a
Salesforce flow, not SFMC) fires the bulk event
that enters the SFMC journey. SFMC's job from here is render +
deliver.
HTTPPost2 to the machine-only mint host
https://mint.advancedrx.dev/api/magic-links with the
patient's Contact Id and portal User Id, channel,
retPath, and an idempotency key.
{ shortUrl, expiresAtUtc } to SFMC.
https://login.advancedrx.net/r/Kj3pQ9xMv7nR (a
separate host from the machine-only mint endpoint).
CryptographyClient.SignAsync handles the signature
in-vault.
/singleaccess for a
one-time-use redirect URL.
AdvancedRx already operates a HIPAA-compliant Azure VNet for eFax, e-script, and patient-matcher. Reusing it for magic-link gives wins that are hard to get inside Salesforce.
Because the link expires by time rather than by event, the Salesforce footprint is small and well-bounded. It's fully built + proven in the sandbox (the ECA, cert binding, and demo patient all verified 2026-05-26); production go-live repeats it against the prod org (§8). Two items max:
AdminApprovedPreAuthorized permitted-users policy bound
via SetupEntityAccess to a small permset, and IP
relaxation (Bypass; clicks come from arbitrary patient
IPs). Five metadata files: ECA, OAuth Settings, Global OAuth
Settings, Configurable Policies, Certificate.
Cert binding: the Key Vault keypair must exist first (Phase
1); then the public cert is bound to the ECA
inline as base64 in
GlobalOauthSettings.<certificate>, deployed via
the metadata API
— no JKS, no Setup-UI import. Salesforce holds the public cert only;
Azure signs with the non-exportable Key Vault key. (Bound + verified
in ClaudeTest 2026-05-26.) Full procedure in
cert-rotation-runbook.md.
Once created, the ECA's consumer key is handed back to Azure as App
Config MagicLink:Salesforce:EcaClientId — Azure redeem
is non-functional until that's set.
Explicitly not in scope on the Salesforce side: Apex, Named Credentials, flows, community-reachable endpoints, Custom Objects, Big Objects, LWC, public Experience Cloud routes, CMDT allowlists, AMPScript JWT minting.
Three calls shape the architecture. Each was evaluated explicitly against alternatives; each is reversible if practice proves the trade wrong.
The architecture depends on two things working that aren't documented for our exact configuration. Both spikes are small, parallelizable, and gating — neither requires a single line of production code.
/singleaccess (returned
frontdoor_uri JSON), followed the redirect chain
(sid session cookie set, HTTP 200 on the storefront
page).
SetupEntityAccess.SetupEntityType is
platform-inferred not writable. All folded into plan.md §6 Phase 0
so the production build doesn't re-derive them.
href values
completely unmodified — no wrapping through
click.advancedrx.email. Caveat: SFMC Test Sends often
skip click-tracking link wrapping; real journey/triggered-send
wrapping behavior deferred to Phase 6a A/B rollout for definitive
verification. V2 design accommodates either outcome.
Order-of-magnitude monthly estimate at expected refill-reminder volume. SQL adds are near-zero (reuses existing DB); Key Vault and App Insights are small even at scale.
The auth flow is proven end-to-end in the sandbox and the Azure plane was security-hardened on 2026-06-11 (see "Where we are now"). What remains is the Salesforce-prod go-live plus the one open storefront-render gap (prod-only data, not a flow defect).
Bridge_Success ×2 and SF LoginHistory 4/4
successful logins all from the Azure NAT IP, zero impersonation. The
JWT bridge is exonerated.
Magic_Link_Bridge ECA + permset +
SetupEntityAccess, bind its public cert inline, and hand the
consumer key to Azure as
MagicLink:Salesforce:EcaClientId; Azure then reverts
its 3 sandbox App Config values (TokenEndpoint,
SingleAccessEndpoint, EcaClientId) back to prod
and bumps MagicLink:Settings:Sentinel
so running instances pick them up (audit finding #6). Watch-out: the
ECA source has the sandbox org Id baked into
orgScopedExternalApp — swap it for the prod org
Id before deploy. Doesn't touch SFMC creds, so it's not gated. See §4
+ plan §6 Phase 4.
Contact.Portal_User__c (the CCP Login user, stamped at
provisioning), one hop from the reminder record — so SF supplies it
via a one-line edit to the refill flow's data binding and Azure
validates it at redeem (plan §7.9).
Blocked on SFMC credential rotation (MARISSA-HANDOFF.md
§2 #2). Stage in the SFMC sandbox; flip to prod sends only after
Marissa confirms rotation complete.
If the prod CCP Login + singleaccess exchange fails, an alternative Salesforce-only architecture is available as a fallback design record at ../magic-link-portal-login.md.
The architecture is reviewed against the existing Azure infrastructure repo and the live Salesforce + SFMC landscape.
fn-magiclink-prod-east2 Running + HTTPS-only; SCM and FTP
basic-publishing-credentials both allow=false (finding #1
confirmed live). App Config endpoint values are readable only from
inside the VNet (jumpbox) — confirm / revert at go-live.singleaccess bridge was exercised in
ClaudeTest against the demo portal user. Proof on both
sides: Azure SQL Bridge_Success ×2 /
RedeemCount=2 with zero failures, and Salesforce
LoginHistory showing
4/4 successful logins, all from the Azure NAT IP
135.119.140.149
(2 Magic_Link_Bridge ECA token exchanges + 2 storefront
session handoffs), with zero human/impersonation logins — the JWT
bridge is fully exonerated. The only post-auth failure is the
storefront render (prod-only commerce data; §8 + plan §10 Risk
#19).advancedrx-document-integration. The mint contract in
§7.1 is reconciled directly against the source
(MintMagicLinkFunction.cs) — confirming mint requires
both Contact Id and portal User Id, returns
{ shortUrl, expiresAtUtc }, and authenticates via Entra
OAuth client credentials. Split hosts: machine-only
mint.advancedrx.dev + patient
login.advancedrx.net, both fronted by Azure Front Door.
As-built facts in plan.md §4.6.storefront-data-audit.md (B2B storefront serving at
https://advancedrx.net/vforcesite/ on the CCP Login
license profile), integrations/sfmc.md (the existing
refill-reminder send pipeline at
JBSystemFlow_Refill_Reminder_c), and the in-progress SFMC
credential rotation per MARISSA-HANDOFF.md §2 #2.ClaudeTest 2026-05-18 — full
handshake (token endpoint → singleaccess → frontdoor redirect →
sid cookie set) confirmed for the CCP Login license.hello@advancedrx.email, vanity click-tracking host
click.advancedrx.email, dual-DKIM signed, DMARC pass)
captured in plan.md §4.5.ClaudeTest sandbox on
2026-05-21 to validate the deployable shape before the production
build. Three execution gotchas surfaced — cert binding requires an
imported public cert (not a Salesforce-generated one); ECA policy
enums differ from legacy ConnectedApp (AdminApprovedPreAuthorized
+ Bypass);
SetupEntityAccess.SetupEntityType is platform-inferred,
not writable via Apex. All three folded into plan.md §6 Phase 0 + §7.6
+ the Phase 4 build steps so the production deploy doesn't re-derive
them. The sandbox artifacts are throwaway; production deploy is still
pending. Cert-import procedure:
cert-rotation-runbook.md.