Regixo docs
🔧 For the engineer·Step 2 of 7 — Connect your sources·see the whole journey ↗
Data catalog · engineer

Connect your sources

Point Regixo at your real databases and SaaS. It reads the connection string from an environment variable you name — your secret never touches regixo.yml. This page covers every connector that’s actually built, the exact strings, and how to reach a locked-down database.

Connect one estate, end to end (the worked example)

A fintech with a Postgres app database, Stripe, a Snowflake warehouse, and dbt for lineage. Here is each source through all four steps — and, for each, where the secret lives:

SourceConnect itSecret lives in…Verify
app-db (Postgres)regixo add postgres --ref DATABASE_URL.envDATABASE_URLregixo test app-db → ✓
Striperegixo add stripe --ref STRIPE_API_KEY (test-mode key).envSTRIPE_API_KEYregixo test stripe → ✓
Snowflakeregixo add snowflake --ref SNOWFLAKE_URL.envSNOWFLAKE_URLregixo test snowflake-dwh → ✓
dbt (lineage)regixo add dbt --from target/manifest.json --target app-dbno secret — it reads a fileappears in regixo sources

Then regixo sources lists all four, and regixo start scans them into one map. Every estate is that same loop; the rest of the page is the exact steps per connector, then the branches.

Step 1 · List every source you need on the map

Before you connect anything, write the list: each production database (Postgres, MySQL, SQL Server, Redshift), each warehouse (Snowflake, BigQuery), each SaaS that holds people’s data (Stripe today; anything else through a BYOC connector), any dbt project for lineage, and any system you can’t reach live but still need mapped (add it from a CSV of its schema). A source you leave off the list is simply absent from the map — the coverage line reports only the sources you added. The list is what tells you when Step 4 is done.

How connecting works

Each source is one entry in regixo.yml. The entry holds the name of the env var that carries the secret (connectionRef), never the secret itself. At scan time Regixo resolves the value from your environment. Two ways to add a source:

Anything the first scan missed — a database behind an env var Regixo doesn’t know, a CSV of a schema you can’t reach, or a dbt manifest for lineage — is added by hand below. File sources (CSV, dbt) are never auto-detected, so they are always a manual regixo add.

Built today

Ten source kinds ship natively: the four SQL drivers (Postgres, Redshift, MySQL, SQL Server), Snowflake and BigQuery (cloud warehouses), Stripe, manual CSV, dbt (lineage), and script — a bring-your-own connector you author for anything else. HubSpot, Salesforce, Google Workspace, S3/GCS/Azure Blob and OpenAPI/JSON-schema import are on the roadmap, not shipped — reach those through BYOC.

Honest caveat: Snowflake, BigQuery and Stripe ship, but none has yet been run against a live account, and Redshift has never been pointed at real Redshift (it rides the verified Postgres driver). They're proven by fixtures, a stubbed transport and gated live tests, and fail loudly on a bad token. Treat a first live scan as one to check.

Step 2 · Connect each source

Work down your list one source at a time. Every connector is the same two moves: put the secret in .env (the value, and only the value, lives there — never in regixo.yml), then regixo add <type> to register it. Find your source below and follow its exact steps.

The secret always goes in one place: .env For every live connector, regixo add stores only the env-var name in regixo.yml and writes a placeholder into .env (git-ignored) with <PASTE-YOUR-TOKEN-HERE> where the secret goes. You — or whoever holds the secret — replace that marker in .env. Until it is replaced, regixo test, start and doctor answer SECRET_PLACEHOLDER_UNREPLACED and name the variable. If an AI agent is running add, it fills every non-secret part and leaves the marker for you — it never asks you to paste the secret into the chat.

SQL databases (Postgres · MySQL · SQL Server · Redshift)

One connector serves four drivers. Each reads a standard connection string from an env var:

DatabaseDefault env varConnection string
PostgresDATABASE_URLpostgres://user:pass@host:5432/db (or postgresql://)
RedshiftREDSHIFT_URLredshift://user:pass@host:5439/db
MySQLMYSQL_URLmysql://user:pass@host:3306/db (one database per string)
SQL ServerSQLSERVER_URLsqlserver://user:pass@host:1433/db (or mssql://)

Set the env var, then add the source (this example is Postgres):

say

“Add my Postgres database to Regixo.”

Your agent fills in everything except the token — you put that in .env yourself.

Show the commandHide the commandShow the sentenceHide the sentence
run
$ export DATABASE_URL='postgres://readonly:••••@db.internal:5432/app'
$ regixo add postgres --ref DATABASE_URL --label "App DB" --region eu-central-1
then

The source lands in regixo.yml with only the env-var NAME — never the value. Nothing is scanned yet; adding and scanning are separate acts.

Check it worked: the source appears in regixo sources, and regixo test connects to it and reads nothing. If your agent asked you to paste the connection string into the chat, that is a bug — it belongs in .env, and only you put it there (why).

Show what it prints in the terminalHide the terminal outputShow what your agent reportsHide what your agent reports
example output
 added postgres source "app-db" (App DB)
  connection reads from $DATABASE_URL (never stored here)
  ↳ wrote a placeholder to .env (git-ignored, never in regixo.yml):
      DATABASE_URL=postgres://<user>:<PASTE-YOUR-TOKEN-HERE>@<host>:5432/<db>
  next:  regixo test app-db   (check it connects)   ·   regixo start   (scan it in)
  undo:  regixo sources remove app-db

The resulting regixo.yml entry:

regixo.yml
version: 1
sources:
  - id: app-db
    kind: sql
    driver: postgres
    label: Application database
    connectionRef: DATABASE_URL     # the env-var NAME, never the secret
    region: eu-central-1            # feeds the "transfers outside the EU" suggestion
    role: controller

Rename a source — the label:

The label: is the human name Regixo shows for a source — you meet it on the Map’s source fold and its per-source trust card, and in regixo sources. The id stays stable (everything keys off it); the label is only the display name, so change it whenever you like — edit regixo.yml, or re-run regixo add … --label "New name". Set it to something a reader recognises (“Billing DB”, not app-db) before you share the map.

SQL Server encryption & other options

SQL Server connections default to encryption on with trustServerCertificate on. Override in the connection string with ?encrypt=false (and ?trustServerCertificate=false). Redshift rides the Postgres driver, so redshift://… and redshift+postgresql://… both work.

Snowflake

Snowflake is reached over the SQL REST API — there's no TCP driver — and it's metadata-only: Regixo reads information_schema for tables, columns and types, never row values. One env var carries the whole connection, with the token as its only secret:

Default env varConnection string
SNOWFLAKE_URLsnowflake://<account>/<DATABASE>?warehouse=<WH>&role=<ROLE>&token=<TOKEN>
say

“Add my Snowflake warehouse to Regixo.”

Your agent fills in everything except the token — you put that in .env yourself.

Show the commandHide the commandShow the sentenceHide the sentence
run
$ export SNOWFLAKE_URL='snowflake://ab12345/ANALYTICS?warehouse=WH_XS&role=REGIXO_RO&token=••••'
$ regixo add snowflake --ref SNOWFLAKE_URL

The token is a Programmatic Access Token by default; for an OAuth token add &token_type=OAUTH. A read-only role with USAGE on the database and warehouse is enough. As with every source, regixo.yml stores only the variable name — the token lives in your environment, never in the file (Hard Rule #6).

BigQuery

BigQuery is a metadata-only REST source: Regixo lists datasets and tables and reads each table's schema (nested RECORD fields are flattened), never row values. The env var holds a bigquery:// URL with your project id and one of two credentials:

Default env varConnection string
BIGQUERY_URLbigquery://<project-id>?token=<OAUTH_TOKEN>
— or —
bigquery://<project-id>?key_file=/path/to/service-account.json
say

“Add my BigQuery project to Regixo.”

Your agent fills in everything except the token — you put that in .env yourself.

Show the commandHide the commandShow the sentenceHide the sentence
run
$ export BIGQUERY_URL="bigquery://my-project?token=$(gcloud auth print-access-token)"
$ regixo add bigquery --ref BIGQUERY_URL

A short-lived OAuth token (token=) is easiest for a one-off scan; a service-account key file (key_file=) is durable, so it suits a scheduled regixo watch. A key-file path is not a secret, so it may sit in the URL — the token is, so it stays in the env var only, never in regixo.yml.

Stripe

Stripe is metadata-only: Regixo pings /v1/balance to check the key works, then maps a curated object schema (customer, charge, invoice, payment_method, subscription) so the classifier can flag fields like email and card_last4. It never fetches customer objects. Use a test-mode key.

say

“Add our Stripe account to Regixo.”

Your agent fills in everything except the token — you put that in .env yourself.

Show the commandHide the commandShow the sentenceHide the sentence
run
$ export STRIPE_API_KEY='sk_test_••••'
$ regixo add stripe --ref STRIPE_API_KEY

Stripe is added with role: processor by default — it processes on your behalf.

dbt (lineage)

dbt isn’t a data source — it’s a lineage provider. Point Regixo at your compiled manifest.json and the warehouse source its models map onto, and Regixo adds the model-to-model ref graph as lineage. It reads no warehouse rows.

First, produce the manifest. dbt writes target/manifest.json when it compiles. If you don’t have one yet, run dbt compile (or any dbt run/dbt build) in your dbt project — that creates target/manifest.json, the file you point Regixo at below.

say

“Add our dbt models to Regixo so the map shows lineage.”

Show the commandHide the commandShow the sentenceHide the sentence
run
$ regixo add dbt --from target/manifest.json --target app-db

Describe a source by hand (CSV)

Can’t reach a system, or want to document one Regixo can’t connect to yet? Describe its schema in a CSV — no live system, no secret. This is the “never a dead end” path.

schema.csv — header: dataset,column[,type,nullable]
dataset,column,type,nullable
legacy_crm.contacts,email,varchar,false
legacy_crm.contacts,full_name,varchar,true
legacy_crm.orders,amount,decimal,false
say

“Describe my unreachable source to Regixo from a CSV of its schema.”

Show the commandHide the commandShow the sentenceHide the sentence
run
$ regixo add manual --from schema.csv
CSV only Manual import reads a CSV with that header. JSON/YAML schema import and a “type it into the portal” editor are on the roadmap, not built. There is no --from schema.json.

Bring your own connector (any SaaS or internal API)

Don’t see your tool in the list? For any SaaS, or your organisation’s own internal API, you can stand up a connector with a coding agent. Unlike the CSV above it’s live:

Open your agent (e.g. Claude Code) in the project and say “add <your tool> to Regixo”; it reads the playbook and wires it up:

say

“Write a Regixo connector for our HubSpot data and register it.”

Your agent fills in everything except the token — you put that in .env yourself.

Show the commandHide the commandShow the sentenceHide the sentence
run
$ regixo connectors --skill

The playbook’s core is an interview: a private/internal API has no public docs the model knows, so the agent asks you how it authenticates and what its objects/fields are (or reads an internal OpenAPI spec / a sample response) — then authors the connector. Everything runs out-of-process: Regixo never imports or runs the authored code inside itself. How it works:

A generator script (script) — works for any source
The agent writes a small script in regixo-connectors/ that prints your schema (the same CSV/JSON as above). Regixo runs it as a subprocess each scan and ingests only the printed schema — never row values. Name the token env var after the tool (HUBSPOT_TOKEN), not a generic name.
say

“Write a Regixo connector for our orders API and register it.”

Your agent fills in everything except the token — you put that in .env yourself.

Show the commandHide the commandShow the sentenceHide the sentence
run
$ regixo connectors new orders-api     # scaffold regixo-connectors/orders-api.mjs
$ regixo add script --generator regixo-connectors/orders-api.mjs --id orders-api --ref ORDERS_API_TOKEN
Honest about what these are

The connector files live in regixo-connectors/ at your project root (next to .env, committed to your repo — a rm -rf .regixo never deletes them). The token stays in .env; config keeps only the variable name.

These connectors are best-effort: labelled user-authored on the map and excluded from the freshness guarantee. They fail loudly, never stale silently.

Metadata-only is a documented expectation, not a sandbox — Regixo runs your generator as a subprocess with your resolved env. See AI agents for the full authoring flow.

regixo add — the flags

FlagMeaning
--ref <ENV_VAR>Name of the env var holding the secret (live sources). Defaults per type (DATABASE_URL, MYSQL_URL, …).
--from <file>File path for manual (CSV) and dbt (manifest.json).
--target <id>dbt only — the warehouse source id the models map onto (required).
--generator <file>script (BYOC) only — the generator script Regixo runs each scan (scaffold one with regixo connectors new).
--role controller|processorYour GDPR role for this source. Default controller (Stripe defaults processor).
--region <region>SQL sources — the host region; feeds the transfers-outside-EU suggestion.
--id <slug> · --label <text>Override the source id / display label.
--skillPrints the agent playbook for connecting a source (no config, no scan) — pipe it into your AGENTS.md.
--yes · --jsonNon-interactive; machine-readable output.

On a terminal, regixo add with no type opens a picker (Databases · SaaS · Import from a file). Headless, pass the type and flags. It writes config only — the headless path never scans; run regixo start after.

Remove a source

Two built-in ways, depending on whether you want to drop one source or wipe everything. Both are Regixo’s own commands. Neither touches your database — the scan only ever read metadata — and neither deletes your secret.

Remove one source

regixo sources remove <id> is the exact undo of an add: it drops the source from regixo.yml and clears its datasets, personal-data flags and lineage from the map, so the map stays honest. Because that erases mapped data, it asks first — confirm with --yes:

say

“Remove the source myfintech1 from Regixo — I added it by mistake.”

Show the commandHide the commandShow the sentenceHide the sentence
run
$ regixo sources remove myfintech1 --yes
then

The source drops out of regixo.yml and its datasets clear from the map. Your .env is left alone — removing a source never touches a secret.

Check it worked: it is gone from regixo sources, and the coverage meter on the portal counts one fewer source. The map itself refreshes on the next scan.

Show what it prints in the terminalHide the terminal outputShow what your agent reportsHide what your agent reports
example output
 removed source "myfintech1"
  cleared its datasets from the map
  the map refreshes on the next regixo start

Without --yes it prints what would happen and stops — a scanned source warns that its mapped tables + personal-data flags will be erased; a never-scanned source says it’s safe (nothing is mapped yet).

Your connection string stays in .env Remove clears the source from regixo.yml and the map, but it does not touch your .env — that’s your secret file, and Regixo never deletes your secrets (it only ever stored the variable name, never the value). If you want the connection string gone too, delete that line in .env yourself.

Start over — wipe everything

To remove every source, the whole map and the draft record in one motion, delete the local folder Regixo wrote in this project:

$ rm -rf .regixo

.regixo/ holds the catalog (index.db), the drafts, and the auto-generated regixo.yml. Deleting it is a clean slate: the next regixo start is a brand-new first run.

Your .env sits outside .regixo/, so it survives — delete it by hand if you want the connection string gone. Same for a regixo.yml you keep at the project root yourself: that one is outside .regixo/ too, so remove it separately.

If the portal is running, use your other terminal If regixo open is running, the terminal it is running in is busy — so type this one in the terminal you keep for commands. You do not need to stop the portal: it re-reads your catalog on every page load, so the removed source is gone the moment you refresh the page. Why regixo open gets its own terminal →

Auto-detect — and a source the scan missed

On a first run with no regixo.yml, regixo start looks for these env vars and offers to add what it finds: DATABASE_URL, MYSQL_URL, REDSHIFT_URL, SQLSERVER_URL, STRIPE_API_KEY. It also reads the variable names (never the values) from a local .env, so a source shows up even if the value is only exported at runtime. File sources (CSV, dbt) are never auto-detected — add those by hand.

A source didn’t show up on the first run? It is one of two cases, and both fix the same way. Either its secret lives in an env var Regixo doesn’t auto-detect (a non-standard name, or a warehouse like Snowflake/BigQuery) — so add it by hand, regixo add <type> --ref YOUR_ENV_VAR (Step 2) — or it is a file source (CSV, dbt), which is never auto-detected. Nothing was lost; the source was simply never on your list. Add it, then re-run regixo start to fold it into the map.

How secrets are resolved

At scan time Regixo resolves each source’s connectionRef in order:

  1. The env var named exactly by connectionRef (e.g. DATABASE_URL).
  2. REGIXO_SECRET_<REF> as a fallback.
  3. Otherwise a SECRET_UNRESOLVED error naming the variable to set.
Never in the file Secrets live in your environment (or a secret manager), never in regixo.yml. Commit regixo.yml freely — it contains only variable names and non-secret config.

Local-only, or paired with the portal

Connecting a source changes nothing about where your catalog lives. By default your install is local-only: it talks to nothing on the internet, and a Refresh just re-scans your sources on this machine — nothing is uploaded. For most people that is the whole product.

Once you forward a draft (regixo invite, or the portal’s hand-off), the install is paired with the hosted portal: a metadata-only snapshot lives there too, and a Refresh can also send an updated snapshot up so the two stay in step. There is an honest in-between — the portal’s copy is only ever as fresh as the last snapshot you sent, so it can lag your local map until you Refresh again; the free portal’s hand-off card tells you when it has changed since. The portal it pairs with is app.regixo.com by default, or whatever you set REGIXO_PORTAL_URL to.

What each Refresh actually sends, and how to keep a paired snapshot current from CI: Keep it current →.

Branch · a database behind a VPN or firewall

A partial scan is fine — an unreachable source is marked and coverage stays honest (“4 of 6 reachable”). When a database sits on a private network Regixo can’t reach from here, there are three real routes, and no --tunnel flag pretends otherwise:

Step 3 · Verify each connection (and fix a source that won’t connect)

Dry-run every connection — this checks credentials and reachability and scans nothing. Run it after each regixo add, and any time a source looks off:

say

“Check that my Regixo source connections still work.”

Show the commandHide the commandShow the sentenceHide the sentence
run
$ regixo test
then

It connects to each source and reads nothing — no scan, no schema, no rows. A ✓ means the credentials work and the host is reachable from here.

Check it worked: an ✗ names the reason — a 401, a refused connection, a bad host. regixo doctor turns that reason into a runnable fix. A source on a network your agent is not on will never connect from here, and no amount of retrying changes that.

Show what it prints in the terminalHide the terminal outputShow what your agent reportsHide what your agent reports
example output
 app-db — connected
 stripe — STRIPE_API_KEY in .env still holds the placeholder — no real API key yet
 snowflake-dwh — Snowflake rejected the token (401) → fix: regixo doctor
2/3 source(s) failed — see fixes above.

Turn any problem into a fix:

say

“One of my sources won’t connect — find out why and fix it.”

Show the commandHide the commandShow the sentenceHide the sentence
run
$ regixo doctor

It resolves each env var and actually probes the connection (the same probe as regixo test, so they never disagree), then prints a specific fix.

ErrorWhat it means & the fix
SECRET_UNRESOLVEDThe env var isn’t set. export <REF>='postgres://…' and retry.
SECRET_PLACEHOLDER_UNREPLACEDThe .env value still holds <PASTE-YOUR-TOKEN-HERE>. Open .env, replace the marker with the real secret, and retry — never paste it into a chat.
SOURCE_UNREACHABLEHost/port/network. Check the route (VPN, firewall) then regixo test <id>.
DRIVER_MISSINGUnknown connection scheme or source kind — check the :// scheme is one of the supported drivers.
NO_SOURCE_DETECTEDNothing to scan and no regixo.yml yet. Set an env var or regixo add.
SOURCE_NOT_FOUNDUnknown source id — list them with regixo sources.

Full list: Errors & fixes.

The read-only access Regixo needs

The scanner only ever issues SELECT against information_schema.tables and .columns, and (Postgres/Redshift) reads catalog tables (pg_class, pg_depend, pg_rewrite) for row-count estimates and view lineage. A read-only role with catalog visibility is enough. A restricted role simply loses the estimates and auto-lineage — the scan never breaks. No writes, no DDL, and it never SELECTs your row data.

Step 4 · Confirm you have them all

List every source and whether Regixo could reach it. Check it against your Step-1 list — nothing on the list should be missing, and nothing reachable should read unreachable:

say

“List my Regixo sources and tell me which ones it could reach.”

Show the commandHide the commandShow the sentenceHide the sentence
run
$ regixo sources
example output
 app-db  [sql/postgres]  reachable · last scan 9m ago
 dbt  [dbt/dbt]  reachable · last scan 9m 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

A source you just added but haven’t scanned reads not scanned yet until the next regixo start — that is expected, not a failure. A ✗ unreachable is the one to act on: run Step 3 to see the reason and the fix.

How you know you’ve connected everything

You are done with this page when all three hold:

Then scan them into one map and read it — the next page.

REGIXO — documentation · secrets stay in your environment, never in regixo.yml · Command reference