Validating a mapping file
Validate a mapping directly in the FGA Dashboard, from the Sync pipeline’s Mappings tab: paste the YAML into the Mappings field and click Add Mappings (or Update Mappings, if you’re changing an existing one). Validation checks, in order:- YAML syntax — malformed YAML is rejected with a line/column pointer before anything else runs.
- Structure — required fields, valid
actionvalues, and the other structural rules described in Mapping Language. - Consistency with your selected FGA model — every relation a tuple template writes to must actually exist on that model.
fga mapping command group:
Using the CLI
Beyond validation, the same command group lets you develop and test mapping files locally, entirely offline, with no store reads or writes, before they run against live input.fga mapping test is the only way to actually execute a mapping’s embedded tests: cases; the dashboard checks syntax, structure, and model consistency when you add or update a mapping, but never runs them.
This tooling is for transforming data that’s still in an external system’s own schema (events, webhooks, API payloads) into FGA tuples. If your data is already shaped as FGA tuples (YAML, JSON, or CSV) and you just need to load it, you don’t need the mapper at all. See Import tuples instead.
The mapping file path is a positional argument, not a flag, for example
fga mapping validate mapping.yaml --model-file model.fga.
run’s default output is JSONL, one operation per line. --writes-only emits bare tuples (no op field, deletes dropped) in exactly the shape fga tuple write --file accepts:
fga tuple write doesn’t read from stdin yet, so this is a two-step handoff through a file rather than a single pipe. If stdin support ships later, this collapses into one command.
Offline limitation. run can dedupe writes/deletes and detect conflicts without a store, but delete-by-filter rules (tuple_filters without a fully-specified tuple) need a live FGA Read to know what they match. Offline, these are reported as a stderr warning, and under tuple_filter_operations in the --format json output, instead of being expanded into concrete deletes. Fully-specified delete tuples still work normally.
Exit codes (all four commands):
Piping live Auth0 events into fga mapping run
fga mapping run reads JSON Lines from stdin, but it doesn’t fetch events itself. To run a mapping against real tenant activity instead of a static input file, pipe it from the Auth0 CLI’s own Events API consumer:
auth0 event-streams subscribe --json-compact emits is {"type": ..., "offset": ..., "event": {...}}. offset is a resume cursor for the CLI itself, not something a mapping ever reads; type duplicates event.type. The mapping’s when and variables expressions run against input.data.object... (see Getting Started), which lives inside that inner event object — so jq strips the wrapper down to just .event before handing each line to the mapper. select(.event) also drops heartbeat lines (offset-only), which carry no event field.
For example, an organization.member.added event arrives from auth0 event-streams subscribe --json-compact as:
select(.event) | .event, that’s what fga mapping run actually sees as one line of its input, and what a rule’s input.* expressions resolve against:
tests: case’s input: field (see Embedded tests) and as the sample event objects in the Events API’s SSE examples — just JSON instead of YAML, and one line instead of an indented document.
--unbuffered matters here: without it, jq holds output in a buffer and only flushes once enough bytes accumulate, so tuples show up in bursts instead of as each event arrives, which defeats the point of piping a live stream.
This is for exploring a mapping against real events as they happen, not for backfilling or production use: fga mapping run runs entirely offline (see Using the CLI above), so it never writes to your store. Pair it with --writes-only and hand the output to fga tuple write to actually apply the tuples, the same as with any other input source. --writes-only drops deletes, so tuples that should be removed stay in your store.