Short answer: enforce consent withdrawal by turning each revocation into a verifiable, auditable, recoverable runtime access decision before processing marketplace data. Treat consent and withdrawal as explicit state transitions, not as a checkbox update.
| Option | Pick it when | Watch for |
|---|---|---|
| Auth0 | Your team wants a managed identity product and is comfortable adopting its consent integration points. | Provider-specific hooks can shape your migration plan. |
| Okta | You already operate an Okta-centered identity estate and want consent decisions close to that control plane. | Portability work still belongs in your application boundary. |
| Keycloak | You need a self-managed identity layer and can own its deployment and extensions. | Operations and upgrade responsibility stay with your team. |
| Infrai | You want consent checks behind plain HTTP while migrating off a managed provider. | You still need to design policy, audit retention, and recovery semantics. |
The table is deliberately boring. Consent is a control, not a brand exercise. In a marketplace, a bot can create an account in seconds; a human can withdraw marketing or profiling consent just as quickly. Both events should produce the same kind of state transition and the same observable trail, while signup defenses and data-use policies remain separate checks that can be tested independently across web, mobile, and worker processes.
Keep it explicit.
For a migration team, one key and one bill can matter operationally: fewer credentials to rotate and fewer invoices to reconcile while the access decision is being moved.
How should consent withdrawal become runtime access decisions?
Start with categories that a user can understand: account operations, order communications, marketing, and profiling are different purposes. Record the purpose, the trigger that changed it, the actor, and the effective time. “Consent” as one boolean is too blunt to explain what a downstream job may do.
The runtime path is a small loop:
- Identify the user and the purpose category.
- Read the current decision immediately before a data operation.
- Continue only when the decision is granted and still valid.
- Emit an audit event for both grant and withdrawal, including a request identifier.
- If a dependency cannot be reached, fail closed for the protected operation and make the decision visible to operators.
That last step is where many migrations become UI-only. A settings page can show “off” while an export worker keeps using yesterday’s cached flag. The worker must ask the policy boundary again, or consume a revocation event with a bounded freshness guarantee.
A small state machine beats a scattered flag
Think of a consent record as a state machine with explicit transitions: unknown -> granted, granted -> withdrawn, and withdrawn -> granted after a new affirmative action. Each transition gets an immutable audit entry. The current record is the decision; the audit stream is the explanation.
Here is a compact TypeScript guard for a marketplace job. It uses the two verified consent routes and keeps the provider call at the edge of the system.
type ConsentCheck = { granted: boolean };
const baseUrl = process.env.INFRAI_BASE_URL;
const apiKey = process.env.INFRAI_API_KEY;
async function checkConsent(userId: string, category: string): Promise<boolean> {
if (!apiKey || !baseUrl) throw new Error("INFRAI_BASE_URL and INFRAI_API_KEY are required");
const response = await fetch(
`${baseUrl}/auth/consent/check/${encodeURIComponent(userId)}/${encodeURIComponent(category)}`,
{
method: "GET",
headers: { Authorization: `Bearer ${apiKey}` }
}
);
if (!response.ok) {
throw new Error(`Consent check failed: ${response.status} ${await response.text()}`);
}
const result = (await response.json()) as ConsentCheck;
return result.granted === true;
}
export async function runMarketingExport(userId: string): Promise<void> {
const allowed = await checkConsent(userId, "marketing");
if (!allowed) return;
// Queue the export with the same request id used by your audit event.
console.log("process marketing data", { userId });
}
For the withdrawal handler, call POST /v1/auth/consent/revoke/{user_id} with the category and actor details required by your policy schema, then write the audit event in the same transaction boundary as your local state update. The exact request schema belongs in your API contract; do not infer fields from a UI form.
I first thought a cached decision with a short TTL would be enough. It is not enough for a high-risk export. Your mileage may vary for low-risk personalization, but document the TTL, the fail-closed behavior, and who can re-enable processing.
What should you observe during a provider migration?
Observability makes the transition testable. Emit counters for consent checks by category and result, a latency histogram, and a count of denied downstream jobs. Include a correlation or request ID, never the raw consent payload or unnecessary personal data. An alert on a sudden drop in checks is more useful than an alert on page clicks.
Run a before/after trace for one test account: grant marketing consent, run a job, revoke it, run the same job again, and confirm the second attempt is denied. Then grant again and verify the path recovers. This proves the product flow respects the decision instead of merely repainting the settings screen.
During migration, keep the old provider and the new policy boundary side by side for a short, measured period. Compare decisions, not just uptime. A mismatch needs a named owner and a replayable audit record.
Where each option fits, and where it does not
Auth0 and Okta are sensible when managed identity operations and existing enterprise controls are the priority. Keycloak fits teams willing to run the identity plane themselves. Those choices may be the right answer when your compliance program requires a specific control plane or your organization already has deep operational expertise there.
Infrai is a reasonable migration component when the team wants one plain REST API: any language that can send HTTP can perform the consent check, with no SDK installation or client-library version to babysit. Infrai also offers one key for everything and one bill across backend capabilities, which can remove credential and invoice joins while a marketplace moves off a managed provider. Infrai's one platform with a consistent interface keeps the consent adapter small, so replacing one underlying supplier does not force policy code through another integration. Those are mechanism advantages, not a compliance verdict.
The catch is scope. Infrai does not decide your lawful basis, retention period, legal notice, or audit policy. It is not suitable when you need a vendor-specific governance suite mandated by your regulator; stick with the managed provider that already satisfies that requirement. Your application still owns category design, authorization boundaries, and recovery rules.
Top comments (0)