Skip to main content

Pause and resume

Pause sits at the top of the pipeline’s detail page, next to its status badge, and asks you to confirm before taking effect. Pausing stops the worker from consuming new events; events themselves aren’t lost immediately, since the Auth0 Events API retains them for a limited time, so you can catch up once you resume. The retention period isn’t documented by Auth0 yet, so don’t assume a specific duration; an expired position is rejected with a 410 (see the Events API error responses). Once paused, the Sync pipeline shows a Paused badge, and the header now offers Resume alongside Delete (Delete only appears once the pipeline is paused; see Delete a Sync pipeline below). Resuming also asks you to confirm. By default, Resume continues syncing from the last cursor it had processed, with no explicit time limit on your side; events held during the pause are delivered and processed in order, up to the Auth0 Events API’s retention limit (see Reconciling below). If that retention is exceeded, the cursor is lost and events in the gap are silently not replayed; see the PAUSED_CURSOR_LOST row in the status reference below. You can instead resume from an explicit point in time rather than the last cursor. This is capped at 7 days back. See Troubleshooting if you hit this.

Change the model or mapping

A mapping is only ever valid against a specific model, since the relations it writes to have to exist on that model. Both live on the same Mappings tab: a Model dropdown (with a view icon to inspect the selected model’s schema) above the Mappings field. There’s no separate model-picker flow; changing the model is just selecting a different one from that same dropdown. To change either, update the dropdown selection and/or the mapping YAML as needed, then click Update Mappings. Because your mapping may reference relations that don’t exist on the newly selected model, saving re-runs the same mapping/model compatibility check from setup. If it fails, you’ll see diagnostics so you can fix the mapping (or pick a different model) before saving; a failed validation has zero effect. The Sync pipeline keeps running exactly as it was, on its previous model and mapping, as if the save had never happened. See Validating a mapping file for what gets checked. The worker picks up the change automatically, with no restart or downtime required.
If your change renames or removes a relation the mapping previously wrote, there is currently a brief window where the old and new mapping could both process events: the worker finishing an in-flight event under the old mapping right as the new one takes over. For a purely additive change this is harmless. For a rename or removal, an event landing in that window can be processed under the old rules only, leaving a stale tuple under the new relation with nothing to fix it afterward.Pause the Sync pipeline before saving a rename- or removal-style change, and resume it once the change is saved; see Pause and resume. Pausing first closes the window entirely, since nothing processes events while paused.
Mappings are not versioned today: updating a mapping overwrites it, with no history of prior versions and no built-in way to roll back. Keep your own copy of a mapping file before changing it if you want to be able to revert.

Delete a Sync pipeline

A Sync pipeline must be paused before it can be deleted; pause it first if it’s still active. Delete only appears at the top of the pipeline’s detail page, alongside Resume, once the pipeline is paused; it’s hidden entirely while a pipeline is Active. You’re asked to type the pipeline’s name to confirm, and this cannot be undone. Deleting stops the worker and removes the Sync pipeline’s mapping and public key. The FGA tuples already written to your store are not affected; you manage those directly in FGA, independent of the Sync pipeline that created them. After deleting, you’re returned to the empty Auth0 Relationship Sync page, ready to set up a new one, for example to connect a different tenant.

Rotating credentials

FGA imposes no expiration of its own on the signing key. The sole source of truth for how long it stays valid is your Auth0 client’s own credential configuration: Never, From certificate, or a Custom date, set on the Machine-to-Machine application’s Private Key JWT credential in Auth0. Auth0 does not send a notification ahead of any of these, so either set the expiration to Never and rotate on your own schedule, or set an actual date and configure your own reminder on the Auth0 side before it lapses; nothing on the FGA side will warn you. Rotation is available on demand at any time; nothing on the FGA side forces it on a schedule. A Sync pipeline keeps at most two keys at once: an Active key, and, while you’re mid-rotation, a Candidate.

01. Generate a new key

On the Credentials tab, click Generate New Public Key JWT. FGA generates a new RSA key pair and lists it as a Candidate, downloadable as an RS256 PEM certificate. This is the only time it’s shown, so store it securely.

02. Add the new key to Auth0

Upload the new PEM certificate to your Machine-to-Machine application as an additional Private Key JWT credential; see Auth0’s Rotate credentials guide for the current steps. Auth0 supports multiple registered keys at once, so your current Active key keeps working while you do this.

03. Promote the new key

Back on the Credentials tab, use the Candidate key’s … menu to promote it. This flips it to Active, and the worker immediately switches to signing with the new key. The key it replaces is relabeled Deprecated.

04. Remove the old key from Auth0

Once the new key is confirmed working, remove the old key’s credentials from your Auth0 application, then delete the Deprecated key from the Credentials tab’s … menu. You’re asked to type the application’s name to confirm, and this cannot be undone; the warning is scoped to the one key, not the whole Sync pipeline.
A Sync pipeline needs a working Active key to authenticate. Confirm the new key is live in Auth0, and promoted, before removing the old one.

Backfilling and reconciling

Auth0 Relationship Sync processes events from the moment the Sync pipeline is activated; it does not import historical Auth0 data automatically. There are three situations where the FGA store can fall out of sync and require manual reconciliation. Reconciliation is a self-serve process using the Auth0 Management API as the source of truth. Loading existing Auth0 data into FGA is called backfilling; it is the same process whether you are populating FGA for the first time or repairing drift.

When you need to reconcile

Initial setup (backfill): any Auth0 data that existed before the Sync pipeline was activated (users, organization memberships, role assignments, groups) is not in FGA. You need to backfill it before going live. Extended downtime: FGA has no queue of its own; whether you pause the Sync pipeline yourself or it’s paused/disconnected automatically, the only thing standing between you and lost events is the Auth0 Events API’s own retention window, bounding how far back a Sync pipeline can resume from. If this window is exceeded, the events inside it are gone and the Sync pipeline cannot replay them on resume. Treat it like an initial setup and backfill from the Management API snapshot. This surfaces as the PAUSED_CURSOR_LOST status; see Sync pipeline status reference. Mapping or model changes that affect synced tuples: see Change the model or mapping above for how to make the change itself; this covers when the change also requires reconciling tuples that were already synced. Not every change requires reconciliation. Only changes that alter how already-processed events produce tuples need it:
  • Requires reconciliation: renaming a relation, changing the user: or object: template in an existing rule, removing a rule that was previously writing tuples, changing role normalization logic; also adding a new relation that should apply to existing Auth0 data (the Sync pipeline won’t retroactively process old events to populate it).
  • Does not require reconciliation: adding a new rule for an event type that wasn’t previously mapped (no old tuples to fix), adding a new relation type that your application populates directly.
Suspected drift, for any other reason: Auth0 doesn’t guarantee that every change produces an event or that events arrive in order (see Event delivery and consistency), so FGA can diverge from Auth0 even while the Sync pipeline is healthy and running. If you notice a permission that looks wrong, or otherwise suspect FGA has fallen out of sync with Auth0 without one of the specific triggers above, the same reconciliation approaches below still apply; there’s nothing special about why you suspect drift. There’s no dedicated drift-detection tooling today; start from How to reconcile below using the Auth0 Management API as the source of truth. Since drift from a missed event can happen at any time and without warning, plan to run this check periodically rather than only when you happen to notice something wrong.

How to reconcile

The general process: read the current state from the Auth0 Management API, translate it into FGA tuples, and write them to your store. There are two approaches. Approach A (recommended): fga mapping run + fga tuple write. Export the current Auth0 state as a JSONL stream of synthetic events (one per user, membership, role assignment, etc.), feed it through your existing mapping file, and write the result to FGA:
--aggregate reconciles the whole batch rather than streaming record-by-record, which matters when the same object appears in multiple exported records. Because this reuses the actual mapping file, the reconciliation logic can’t drift from what the Sync pipeline itself does; there’s nothing to keep in sync by hand. See Working with Mapping Files for the full CLI reference. Approach B: direct FGA SDK writes. Read the current state from Auth0, compute tuples inline in a script, and write them to FGA using the SDK:
The mapping logic isn’t reused here: you’re re-implementing the same rules in your reconciliation script, so keep it in sync if your mapping file changes. Use this when Approach A’s offline reconciler can’t cover your case (see the caveat below) or when a genuinely custom transform is easier than reshaping data into the mapping engine’s input.

Handling stale tuples after a mapping change

If you are reconciling because your mapping changed, FGA may contain tuples written by the old mapping that are no longer correct. You have two options: Clear first, then write new: delete stale tuples before writing the new ones. Avoids a mixed state with contradictory permissions, but causes a brief window where affected users have no permissions. Write new, clean up after: write the new tuples first so users always have valid access, then identify and delete stale tuples. Safer for access continuity but risks a brief period where both old and new tuples coexist. Which to prefer depends on whether the old and new tuples are contradictory (e.g., granting access where none should exist) or just redundant. Neither option has a universal “right” answer; match your application’s tolerance for access gaps vs. overly permissive states. A mapping’s tuple_filters reconcile mode can help with the cleanup: if you can express the “desired state” for affected objects in your mapping, the read-diff-write mechanism will compute and apply the minimal set of writes and deletes automatically.
This cleanup pattern relies on delete-by-filter rules (a tuple_filters entry without a fully-specified tuple), and fga mapping run can’t resolve those offline; it needs a live FGA Read to know what a filter matches. Use Approach B for this specific cleanup, not Approach A. Approach A is safe for populating or backfilling state where every rule either writes a fully-specified tuple or deletes one.

Sync pipeline status reference