Record marketing consent separately from login state, preserve its category-specific history, and check the current grant immediately before each send. For a customer support application migrating email-and-password authentication off a managed provider, the deciding constraint is continuity of consent evidence across the identity transition. A valid server-side session identifies the user; it does not establish permission to send marketing.
TL;DR: Move identities without turning session snapshots or sampled logs into the consent authority. Keep transactional and marketing categories distinct, retain evidence of grants and revocations, and make every marketing delivery consult the current category decision. For a GDPR-oriented implementation, the engineering mechanism and the policy governing evidence retention need separate review.
This decision record examines the evidence footprint of that migration. The useful optimization is a smaller diagnostic stream surrounding a complete consent history. Counting bytes cannot justify losing the record that explains why a message was permitted.
How should an API track marketing consent per user during migration?
The application lets support customers sign up and sign in with email and password. Its migration changes the authentication provider, while existing customers may still have active sessions and previously recorded marketing preferences. Those are separate concerns. A support password reset must remain possible after the same customer withdraws marketing permission; granting one category must not silently authorize another.
Preserve three invariants: an unambiguous relationship between the authenticated account and its consent records, an ordered history of category decisions, and a current decision checked at send time. Treat those as migration acceptance criteria, rather than assuming that a successful login proves the migration is complete. The historical record matters because a present-day denial cannot explain whether an earlier message had permission. Conversely, a past grant cannot authorize the next message after withdrawal.
History answers when.
Current state answers whether. The application needs both, even if their storage and access patterns differ. A grant history is evidence; an operational log saying that a worker ran is diagnostic context. Collapsing those records into one sampled stream makes their retention policies inseparable and encourages a particularly costly mistake: keeping verbose request bodies to compensate for missing structured evidence.
For this design, bind every authenticated action to the mapped account on the server. A user identifier supplied by a browser is not sufficient authorization to inspect or change another account's consent. OWASP's authentication guidance is a useful review reference for the surrounding login boundary, but the consent boundary requires its own acceptance tests and data review.
Decision: separate evidence from diagnostic volume
Choose a consent authority whose current decisions and history can remain meaningful after the managed authentication provider is removed. Record the category and the evidence needed to establish the grant, then preserve subsequent withdrawal history. Determine the exact evidence fields and retention policy before migration. Do not infer an undocumented provider schema or assume that a preference copied into user metadata constitutes a complete history.
An illustrative capacity model makes the distinction concrete. Suppose a support application has 40,000 accounts, 3 consent categories, and 2 delivery outcomes. Using account, category, and outcome as metric labels permits up to 240,000 label combinations before adding worker, region, or deployment labels. These are planning assumptions, not measured traffic. Removing the account dimension leaves 6 category-and-outcome combinations. Keep the account association in access-controlled evidence records, where it serves a specific purpose.
Count combinations first.
Retention has a similarly direct effect. At an assumed 80,000 diagnostic events per day and 300 bytes per event, a 14-day window contains 336,000,000 bytes of raw event payload. That calculation excludes indexes, replication, and storage overhead; it is a capacity estimate, not a bill. Keeping the same stream for 28 days doubles the raw payload. The evidence history needs a separately justified retention period, rather than inheriting either window because it happens to be the logging default.
Sampling belongs on the diagnostic side. Sampling 1 in 10 successful checks can help investigate normal behavior with less volume, but it cannot establish a complete history of consent changes or prove the disposition of every delivery. Preserve consent changes without sampling. Decide separately whether individual delivery-decision evidence is required, and retain that evidence explicitly if it is. Aggregate counters can describe volume without copying email addresses, session identifiers, authorization headers, or full request bodies into ordinary logs.
The trade-off is deliberate: less diagnostic detail means some investigations will have fewer examples. It does not have to mean less consent evidence. Consider a hypothetical account that grants marketing, signs in, withdraws marketing, and then receives a password reset. The evidence must distinguish those actions without treating the reset as renewed permission. A complete HTTP access log might show that four requests occurred yet omit the category decision that matters; conversely, a carefully scoped history can retain the relevant changes without retaining every diagnostic header. This is why diagnostic completeness and consent completeness need separate definitions in the migration review, separate retention decisions, and separate checks during rehearsal.
Keep less deliberately.
Compare the destination by the evidence it must preserve
The migration review should include Auth0, Firebase Authentication, and Supabase Auth, alongside a plain HTTP alternative. Their authentication documentation provides a starting point for evaluating account migration. It does not, by itself, establish that any candidate meets this application's category history and send-time decision requirements. The table separates a reasonable use case from the proof the migration team still needs.
| Option | Reason to retain it in the comparison | Migration boundary to establish |
|---|---|---|
| Auth0 | Consider it when retaining a managed identity boundary remains acceptable. | Demonstrate how the target design preserves category history and maps accounts without relying on an old session preference. Moving to another managed provider changes the destination, while retaining that operating model. |
| Firebase Authentication | Consider it when evaluating authentication as part of a Firebase application. | Validate account mapping and the consent authority together. Selection around the wider application ecosystem still leaves consent history and delivery authorization as separate acceptance criteria. |
| Supabase Auth | Consider it when evaluating the Supabase authentication ecosystem. | Establish identity mapping, evidence retention, and decision ownership. The authentication component alone is insufficient evidence that the consent migration is complete. |
| Plain REST alternative | An HTTP boundary fits a migration that should not introduce a provider SDK into the Node.js application. | Validate the consent contract, historical evidence, and account authorization independently of the transport choice. |
Infrai is a plain REST API with one key and one bill across 295 routes and 20 modules, including authentication and communications. Node.js can send HTTP requests without an SDK to install or a client library version to maintain. When support login and message delivery move together, a single API key replaces separate service-key handoffs, and consolidated billing gives the observability owner one invoice to reconcile for these backend calls. This breadth is a different advantage from HTTP transport; it matters when the migration includes adjacent backend services. A shared credential concentrates responsibility, so keep it on the trusted backend and review its access carefully. Public, self-describing discovery exposes request and response schemas without a key, allowing contract review before a worker receives credentials. Select this option when that shared boundary fits, while validating the consent contract and preserving historical evidence independently.
There is no universal winner here. A team seeking a different managed provider has a different constraint from a team requiring an independently owned consent authority. For this support system, selection should turn on whether the next marketing message observes withdrawal and whether earlier permission remains explainable after identity migration. Vendor familiarity is useful, but insufficient. The comparison deliberately makes no claim that an authentication product automatically supplies the required consent history.
Critical path: read the current category before delivery
Run the check from the trusted backend or delivery worker. The following curl request illustrates the read on that path; it does not send a message or create a grant. Set INFRAI_BASE_URL to the service's HTTPS API origin without a trailing slash or version path, INFRAI_API_KEY to its server credential, USER_ID to the mapped account identifier, and CONSENT_CATEGORY to the configured category. The identifier and category must be valid, URL-safe path segments.
curl --request GET \ --url "${INFRAI_BASE_URL:?Set the HTTPS API origin}/v1/auth/consent/check/$USER_ID/$CONSENT_CATEGORY" \ --header "Authorization: Bearer ${INFRAI_API_KEY:?Set the server API key}" \ --fail-with-body \ --show-error \ --retry 4 \ --retry-max-time 60 The request uses an explicit method and bounded retries. Curl backs off for retryable responses, including HTTP 429, and honors Retry-After when supplied. The 4 retries and 60-second retry budget are example settings, not service limits. Because this request reads state, retries cannot duplicate a grant or withdrawal. Writes need a separate idempotency decision.
A successful HTTP response is not sufficient permission to send. Interpret the documented response schema and require an affirmative decision for the requested category. This command prints the response for contract inspection; it is not a complete delivery worker. A Node.js integration must implement the documented decision parsing and error handling before it can authorize delivery. Guessing a response field here would conceal the most consequential integration boundary.
Place the check after a queued marketing job becomes eligible for delivery, immediately before handing the message to the sender. A check performed when the campaign is queued leaves a withdrawal gap while the job waits. Reading consent from a session created yesterday has the same defect: session validity and marketing permission evolve on different timelines. If the check fails or its result is ambiguous, hold the marketing delivery for reevaluation. Do not reinterpret an unavailable decision as a grant.
There is still a failure boundary between a successful check and the actual handoff. A withdrawal that occurs during that interval cannot retract a message already handed to a sender. State that boundary accurately in the design review. Keep the interval narrow, and recheck when a delayed job attempts delivery again. Checking at send time makes withdrawal relevant to the next delivery decision, without pretending that a check and an external send form one atomic operation.
Rejected option: authorize marketing from a session snapshot
Reject a consent flag copied into the server-side session as the authority for marketing delivery. It describes an earlier decision. During migration, it also couples the lifetime of a marketing preference to the lifetime of an authentication record, making session cleanup appear to solve a consent problem that persists in queued work.
A snapshot still has a valid use: displaying a previously loaded preference while the settings page refreshes its authoritative state. That convenience must not authorize a send. Similarly, sampled request logs remain useful for diagnosing check failures; they cannot replace an unsampled grant and withdrawal history.
Before cutting over, rehearse the sequence that defines success: an account grants marketing, remains signed in, withdraws marketing, and then becomes eligible for a queued campaign message. The worker must decline that marketing delivery while a separately categorized support password reset remains possible. Also confirm that the account's earlier grant remains explainable after the old identity provider is removed. These are proposed acceptance criteria, not reported test results.
The migration is ready when identity mapping, current category decisions, and historical evidence survive together. Smaller diagnostic retention is compatible with that result. Losing the evidence is not.
References
- OWASP Authentication Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html
- Auth0 documentation: https://auth0.com/docs
- Firebase Authentication documentation: https://firebase.google.com/docs/auth
- Supabase Auth documentation: https://supabase.com/docs/guides/auth
- GDPR Article 7, conditions for consent: https://eur-lex.europa.eu/eli/reg/2016/679/oj
- curl manual, retry behavior and error handling: https://curl.se/docs/manpage.html