Swappable backends — external OpenFGA/NATS/DB drivers (the microlith → connected-services move) #10

Open
opened 2026-08-06 18:15:47 +00:00 by ginjiruu · 0 comments
Owner

Goal

Make the platform's embedded backends swappable for external services — the move from "microlith" to "connected services." Today every app embeds OpenFGA, NATS, and SQLite because those are the only options; the ability to run against an external OpenFGA, NATS, and a real database driver is what unlocks the next architecture level.

Scope

For each embedded backend, decide the seam and provide the external option:

  • OpenFGA — run against an external OpenFGA instance via embeddedfga.Client instead of the embedded OpenFGAServer. Note: the Client and Server are not interchangeable today (different method signatures, different arg order, different tuple types — SDK client.ClientTupleKey vs embeddedfga.Tuple), so this needs a shared backend interface first.
  • NATSembeddednats vs an external JetStream cluster.
  • Databasetoolbelt/db is SQLite-only today. sqlc already supports Postgres, MySQL, and SQLite (https://docs.sqlc.dev/en/latest/reference/language-support.html), so other drivers would "only require a lot of plumbing" — but the plumbing is real: migrations, driver wiring, dialect-specific SQL, and the toolbelt/db abstraction.

Not in scope here: the design details of each seam. This issue tracks the effort; it spawns its own tickets.

Decisions this effort must make

  1. The backend interface shape shared by embedded and external implementations (starting with FGA: the authz.Backend read interface + the existing embeddedfga.Server write seam).
  2. What stays embedded-by-default vs configurable, and the config surface (fga.mode, nats.uri, db driver fields).
  3. Migration/plumbing cost per driver, and whether toolbelt/db becomes driver-agnostic or gains a Postgres/MySQL variant.

Why it's separate

Ruled out of the glue-absorption map ("Toolbelt glue absorption — map: what the toolbelt absorbs from duplicated consumer glue") — this is a platform architecture effort, not absorption of duplicated consumer glue. Tracked here so the absorption map can reference it and a fresh effort can chart it later.

## Goal Make the platform's embedded backends swappable for external services — the move from "microlith" to "connected services." Today every app embeds OpenFGA, NATS, and SQLite because those are the only options; the ability to run against an external OpenFGA, NATS, and a real database driver is what unlocks the next architecture level. ## Scope For each embedded backend, decide the seam and provide the external option: - **OpenFGA** — run against an external OpenFGA instance via `embeddedfga.Client` instead of the embedded `OpenFGAServer`. Note: the Client and Server are **not** interchangeable today (different method signatures, different arg order, different tuple types — SDK `client.ClientTupleKey` vs `embeddedfga.Tuple`), so this needs a shared backend interface first. - **NATS** — `embeddednats` vs an external JetStream cluster. - **Database** — `toolbelt/db` is SQLite-only today. sqlc already supports Postgres, MySQL, and SQLite (https://docs.sqlc.dev/en/latest/reference/language-support.html), so other drivers would "only require a lot of plumbing" — but the plumbing is real: migrations, driver wiring, dialect-specific SQL, and the `toolbelt/db` abstraction. Not in scope here: the design details of each seam. This issue tracks the effort; it spawns its own tickets. ## Decisions this effort must make 1. The backend interface shape shared by embedded and external implementations (starting with FGA: the `authz.Backend` read interface + the existing `embeddedfga.Server` write seam). 2. What stays embedded-by-default vs configurable, and the config surface (`fga.mode`, `nats.uri`, db driver fields). 3. Migration/plumbing cost per driver, and whether `toolbelt/db` becomes driver-agnostic or gains a Postgres/MySQL variant. ## Why it's separate Ruled out of the glue-absorption map ("Toolbelt glue absorption — map: what the toolbelt absorbs from duplicated consumer glue") — this is a platform *architecture* effort, not absorption of duplicated consumer glue. Tracked here so the absorption map can reference it and a fresh effort can chart it later.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ginjiruu/toolbelt#10
No description provided.