Architect your catalog for your organization
Your first run maps one database. An organization catalog is a deliberate set of
sources, a chosen mode, and a committed regixo.yml your whole team shares. This page is
the whole set-up job, in order: five steps take you from that first laptop run to a plan the whole
team scans the same way. Work them top to bottom; each ends with a way to check it landed.
regixo.yml that decides what the whole team scans — and
because everything scanned stays in the record, that also decides what the record covers. Do these
five in order; each is a decision, walked below:
- Plan the sources you scan — the source list is the record's boundary. (the decision walk ↓)
- Set the mode —
catalog,complianceorcatalogOnly: what every teammate's portal leads with. (which to pick ↓) - Declare DORA scope — on only if you are a regulated financial entity. (how ↓)
- Name the load-bearing fields —
regionandrolefeed the record, not just the label. (what each does ↓) - Commit a shared
regixo.yml— one file, no secrets, one estate. (the worked file ↓)
Walk one company through all five steps (the worked example)
Before the reference, set one real estate up end to end so the five steps are concrete. Aurelia Payments is an authorised EU payments firm. Its product runs on a Postgres database in the EU; it bills through Stripe (US-hosted); it analyses in a Snowflake warehouse in the EU; and a dbt manifest describes how the warehouse models derive from the app tables. Here is each step for it:
| Step | The decision for Aurelia | What the engineer does |
|---|---|---|
| 1 · Plan sources | All three systems hold customer data, so all three belong in the record. The warehouse is not a duplicate of the app database — it re-shapes the data and sits elsewhere — so it is its own source. | Point Regixo at app-db, Stripe, Snowflake and the dbt manifest. regixo start scans the two it can reach; Stripe and Snowflake wait on their env vars. Status reads 2 reachable · 2 unreachable — honest, and a rollout target. |
| 2 · Set the mode | The reason to install is the RoPA and DORA, so the portal should open on the record, not the map. | Set intent: compliance. |
| 3 · DORA scope | Aurelia is an authorised payments firm, so DORA binds it. The catalog can't infer that — it is an explicit opt-in. | Set dora: true. |
| 4 · Load-bearing fields | Stripe is US-hosted (a transfer out of the EU) and processes on Aurelia's behalf; the app database is EU and Aurelia controls it. | On Stripe: region: us-east-1, role: processor. On app-db: region: eu-central-1, role: controller. |
| 5 · Commit | Every teammate and the CI runner should scan the same estate. | Commit regixo.yml (no secrets). A colleague clones, sets their own .env, runs regixo start, and gets the same map. |
The five sections below are that same run, walked in full — the decision inside each step, then exactly how to make it, then how to check it landed.
Step 1 · Plan the sources you scan
You don't have to connect everything on day one. Start with what the machine you're on can
already reach — a database whose DATABASE_URL is set, a Stripe test key in the
environment — then add the rest one at a time.
Decide what goes in — the walk
Because everything scanned and flagged personal becomes a candidate activity, and there is no per-table “leave this out” switch, choosing the sources is choosing the record's boundary. For each system you could point Regixo at, ask in order:
| Ask about the system… | Then → | Because |
|---|---|---|
| Does it hold personal data — customers, staff, users? | Include it. Scan it. | Everything scanned and flagged personal becomes a candidate activity; the scan set is the record's boundary. |
| Reachable from this machine now? | Add it now — regixo add <type>, then scan. | The fastest way onto the map; only the env-var name is stored, never the secret. |
| Holds data, but not reachable yet? | Still include it — bring it in by one of the three routes below. | A missing system is a blank spot in the record, not a smaller record. Don't drop it. |
| A pure replica of a source you already scan? | Skip the duplicate; scan the primary. | The map would count the same columns twice. (A warehouse is not a duplicate — it re-shapes data and often crosses a region.) |
| Holds no personal data at all? | Optional. Include it for a complete catalog; it adds nothing to the record. | It enriches the map without changing what the record must account for. |
Do this. Run the first scan where a source is already reachable:
“Set Regixo up in this project — scan my sources and build the data map.”
Show the commandHide the commandShow the sentenceHide the sentence
$ regixo startThen add each further warehouse or SaaS, one at a time — each entry carries the name of the env var that holds its secret, never the secret:
“Add my Postgres database to Regixo.”
Your agent fills in the host, port and env-var name — you put the secret in .env yourself.
Show the commandHide the commandShow the sentenceHide the sentence
$ regixo add postgresFull connector detail: Connect your sources.
Check it. regixo status summarises the reachable estate against the target;
regixo sources lists each source with a ✓ or ✗. The map opens at
the portal with the datasets it found. Here is Aurelia's estate
after the first scan — the two live sources in, Stripe and Snowflake still waiting on their env vars:
sources: 4 configured · 2 reachable · 2 unreachable (snowflake-dwh, stripe)
datasets: 4 mapped · 4 hold personal data
columns: 20 in total · 9 hold personal data
coverage: ⚠ 2 of 4 sources reached — the map EXCLUDES snowflake-dwh, stripe (fix: regixo doctor)
record: RoPA drafted — DRAFT · DORA register (DRAFT); review: regixo open · forward to your compliance team: regixo invite✓ app-db [sql/postgres] reachable · last scan 11m ago ✓ dbt [dbt/dbt] reachable · last scan 11m ago ✗ snowflake-dwh [sql/snowflake] couldn't connect · Regixo does not record when it was last read ✗ stripe [saas/stripe] couldn't connect · Regixo does not record when it was last read remove one: regixo sources remove <id> --yes
regixo connectors new
<name> scaffolds one and regixo add script wires it in. The value is the
compliance-evidence engine, not connector breadth — HubSpot, Salesforce and the rest are roadmap.
Where a system can't be reached yet, the CSV route below keeps it from being a blank spot.Read the coverage meter as a target
A partial estate is normal and honest. When a source can't be reached, Regixo marks it and keeps the count truthful — “4 of 6 reachable”. Treat that ratio as a rollout target, not a one-off result: the goal is to close the gap over successive sessions, not to reach 6 of 6 on the first run. There are three real routes to bring an unreachable source in — none of them a dead end:
- Bring the key — set up your own VPN or SSH tunnel and give Regixo a connection string
that reaches the host through it. There is no
--tunnelflag; Regixo just needs a reachable host on the normalDATABASE_URL. - Bring Regixo inside — run
regixo starton a machine inside the network and merge the maps (see Roll it out). - Describe it — hand Regixo a CSV of the schema (
regixo add manual --from schema.csv). No live system, no secret.
Step 2 · Set the mode
One setting decides what your team's portal leads with. All three still scan metadata
only; the difference is emphasis — and, for catalogOnly, visibility. Set it once in
regixo.yml (below) so every teammate's portal opens the same way.
Which mode to pick — the walk
Ask these in order and stop at the first “yes”:
| Ask, in order… | If yes → |
|---|---|
| 1. No EU-compliance need at all — non-EU, or you never keep a RoPA or DORA register? | catalogOnly: true — hide every compliance surface; a plain data catalog. |
| 2. The RoPA / DORA is the reason your team installed? | intent: compliance — lead with the record, end the run on the hand-off. |
| 3. You want the catalog first, with compliance available but not front-and-centre? | intent: catalog (the default) — lead with the map; the draft is still generated. |
The reference for exactly what each mode does:
| Mode | How to set it | What the portal does |
|---|---|---|
intent: catalogthe default when unset | nothing to set, or intent: catalog | Leads with the map. The RoPA is still drafted and the Record route still exists — the compliance call-to-action is just de-emphasised. |
intent: compliance | intent: compliance in regixo.yml | Leads with the record and ends the run on the hand-off (regixo invite). For a team whose reason to install is the RoPA. |
catalogOnly: true | catalogOnly: true (or REGIXO_CATALOG_ONLY) | Hides every EU-compliance surface — Record/RoPA, DORA, the compliance card, invite/unlock, the Art. 9/10 wording. A plain worldwide data catalog. |
intent: catalog only
de-emphasises the compliance surface — the draft, the Record route and the Art. 9/10
language are all still there. catalogOnly removes them from view, for an
audience with no EU-compliance need (a non-EU or worldwide catalog team). It is visual only: the
draft is still generated underneath and the compliance commands still run, so flipping
catalogOnly back off restores everything. Personal-data discovery on the map stays in
both modes — it just reads as plain “sensitive” under catalogOnly.Check it. Read the settings back — the fastest confirmation, no browser needed. Ask your
agent, or run regixo config:
“Show me Regixo’s current settings.”
Show the commandHide the commandShow the sentenceHide the sentence
$ regixo configRegixo settings — ./regixo.yml catalog-only off — EU compliance (RoPA + DORA) shown intent compliance dora on Change a setting: regixo config catalog-only on|off
Then open the portal (regixo open) to see the emphasis land: intent:
compliance opens on the record and ends the run on the hand-off; catalogOnly: true
shows no Record, DORA or Unlock surface at all. regixo config catalog-only on|off flips
catalogOnly live without hand-editing the file.
Step 3 · Declare DORA scope
DORA binds authorised or registered financial entities, and the catalog can't infer whether you are one — so it's an explicit opt-in that adds the DORA Register DRAFT alongside the RoPA. It is not a one-way door: you can turn scope on or off at any time — flip it off and the register drops out of view, flip it back on and it returns, drafted from the same map. Three equivalent ways to declare it:
- dora: true
- In
regixo.yml— the committed, team-wide way. The object form (dora:withrefPeriod/baseCurrency/nca) also turns scope on and carries the EBA filing parameters. - regixo start --dora
- Turns scope on for a run from the command line.
- the first-run question
- On an interactive first run Regixo asks “Is your organisation a regulated financial entity?”; answering yes sets scope.
The DORA register only appears when DORA scope is on — see The DORA register for what the map part-fills and what your team supplies.
Check it. With scope on, the portal grows a DORA lens next to the record, and
regixo status reports the register alongside the RoPA. With it off, neither appears.
Step 4 · Name the load-bearing fields
A coherent org catalog reads consistently across sources. Set four things per source, and know
that two of them — region and role — feed the compliance record rather than
just labelling a row. Get these two right and the record's transfer and controller/processor calls
start from the truth.
- id
- A short, stable slug (
app-db,billing-stripe). It's how the source is referenced in lineage, inregixo test <id>, and in commit diffs — pick it once and keep it. - label
- The human display name on the map (“Application database”). Cosmetic — make it the name your team already uses.
- region load-bearing
- The host region (
eu-central-1,us-east-1). Not cosmetic: it feeds the RoPA “transfers outside the EU” suggestion. A US-hosted source with EU personal data is exactly the transfer your compliance team must account for, andregionis how Regixo raises it. - role load-bearing
controllerorprocessor— your GDPR role for this source. It feeds the controller/processor classification in the record. To decide: do you determine why and how this data is processed — is it your product's own data? →controller. Do you hold or process it on someone else's behalf, or does a third party process it for you? →processor. Default iscontroller; Stripe and other SaaS processors default toprocessor(they process on your behalf). Set it honestly per source.
Check it. Open the record and read an activity: a US-hosted source with EU personal data
raises the “transfers outside the EU” suggestion, and a processor source is
marked as such. If a transfer you expect is missing, the source's region is probably
wrong — fix it in regixo.yml and re-scan.
Step 5 · Commit a shared regixo.yml
The whole point of the file is that it carries no secrets — only env-var names and non-secret config — so you commit it and the whole team scans the same estate. Here is a multi-source example carrying every decision from steps 2–4 — intent, DORA scope, the controller identity, the load-bearing fields and an org PII policy:
version: 1 intent: compliance # step 2 — portal leads with the record + ends on the hand-off dora: true # step 3 — regulated financial entity — add the DORA register draft controller: # the Art. 30(1)(a) organisation the record is FOR name: Aurelia Payments Oy contact: dpo@aurelia.example sources: # step 1 — the estate; step 4 — region + role per source - id: app-db kind: sql driver: postgres label: Application database connectionRef: DATABASE_URL # the env-var NAME, never the secret region: eu-central-1 # EU — no transfer raised role: controller # Aurelia's own product data - id: stripe kind: saas driver: stripe label: Stripe (billing) connectionRef: STRIPE_URL region: us-east-1 # US — feeds the "transfers outside the EU" call role: processor # Stripe processes on your behalf - id: snowflake-dwh kind: sql driver: snowflake label: Snowflake DWH connectionRef: SNOWFLAKE_URL region: eu-west-1 role: processor - id: dbt kind: dbt driver: dbt label: dbt lineage path: dbt/manifest.json # warehouse model-to-model lineage target: app-db pii: # org PII policy — extend / suppress the classifier extraPatterns: - "^cust_ref$" # your own personal-data column names allowList: - internal_batch_id # never flag this one (false-positive)
connectionRef
name — never written into regixo.yml. That is what makes the file safe to commit.Check it. Commit the file and have a teammate clone the repo, set their own
.env, and run regixo start. They should get the same source list and the
same map you do — git diff regixo.yml is now the reviewable record of every estate
change. If their scan differs, a secret or an env-var name is out of sync, not the committed config.
You finished: a deliberate source list, a chosen mode, DORA scope set honestly, the
load-bearing fields named, and one committed regixo.yml. Your team gets: the same
estate on every machine, a map that reads consistently, and a record drafted from real
region/role facts. The three sections below are optional depth — how the two
lenses stay consistent, and how lineage and enrichment become a shared standard.
Beyond the five steps · one map, two lenses
Regixo keeps a single catalog and renders it through two lenses: the free Data lens (the map — datasets, columns, owners, personal-data flags) and the Compliance lens (the RoPA record, and the DORA register when in scope). The record is derived from the map, never typed twice. Correct a classification on the map and the RoPA activity's data categories update on their own; there is no second place to edit the same fact. That single-source-of-truth design is why an org catalog stays internally consistent as it grows.
Walked step by step in Your first session; the classifier itself is Classify & correct.
Lineage — automatic inside, asserted across
Two kinds of data flow, two ways Regixo gets them:
- Automatic, inside a warehouse
- A dbt
manifest.json(regixo add dbt --from … --target …) gives the model-to-model ref graph, and on Postgres/Redshift the scanner readspg_depend/pg_rewriteto emit view→table edges. No warehouse rows are read. - Human-asserted, across systems
- A Stripe→database flow crosses systems no scanner can join. Assert it once with
regixo lineage add <from> <to>; the edge is tagged “asserted by you” and survives every re-scan.
Enrich as an org standard
Three enrichments turn a bare map into shared organizational knowledge. All three run locally — no network call, no model call — and each is persisted outside the scanned snapshot, so a re-scan never clobbers the work your team layered on.
- regixo describe
- A one-line description per dataset (“Registered customer accounts — one row per person”). Regixo drafts it from metadata; a human confirms. Feeds the team and any connected AI agent.
- regixo glossary
- House terms and their meaning, so “MRR” or “data subject” means one thing across the org.
glossary suggestproposes seeds; a human confirms. - regixo lineage
- The asserted cross-system edges above — the flows the catalog standard should record because no scanner can.
regixo catalog export writes regixo-catalog.json (descriptions, glossary,
asserted lineage, classification overrides). regixo catalog import merges it in and
never downgrades a confirmed answer. Governance for who may change what lives in the next page.