Security
isn't a feature.
It's the architecture.
Database-level tenant isolation. Composable role-based access. Row- and column-level policies declared as metadata, not buried in application code. Self-hosted by default, anywhere you want.
One database
per tenant.
No exceptions.
The strongest isolation model available. No shared tables. No query filters to forget. If one tenant's database is compromised, other tenants are completely unaffected.
Read: Only You Own Your DataEach tenant has its own PostgreSQL database. Not a schema, not a row filter — a real database.
Unique DB user per tenant. No shared connection. No master role with cross-tenant reach.
Module schemas (crm, hr, fin, wms) live inside each tenant's own database. Always namespaced.
User identities live in a separate auth service. Tenant data never touches the auth store.
One workspace.
Many boundaries.
Zero code.
Separate organizations get separate workspaces — their own database, walled off completely. Inside one workspace, folders carve the same data into slices: a department, a division, a region, a warehouse. Grant someone a folder and you grant exactly the data its filter defines — nothing more.
A folder is a saved filter over your entities. Records aren't moved into it — they appear when they match, and the same record can live in several folders at once.
Assign a role inside a folder and it only reaches that slice. Anna manages the East division, Bob the West — one role, two boundaries, no custom code.
Row access (folders), column access (views) and operations (roles) are independent blocks. Define each once and combine freely — no role-per-department explosion.
Every query carries the folder's filter, and writes can't push a record out of its slice. The boundary holds at the SQL layer, never just the UI.
Four layers.
All declarative.
Every access rule is metadata. Versioned, reviewable, auditable. No security logic scattered across controllers and stored procedures.
Composable, additive roles. Sales Rep + Finance Viewer = full CRM + read-only Finance. Roles never revoke each other.
role SalesRep can: read, update.own
role FinanceViewer can: read.fin
user alice
roles: [SalesRep, FinanceViewer]Per-record rules gate individual rows by their values, owner, or status — layered on top of folder scope and enforced at the SQL layer, never the UI.
policy OwnOpenDeals on Deal
for SalesRep
where owner = $userPer-role field visibility and editability. Sales sees the contract value but not the margin. Viewers see summary, not internal notes.
field Contract.margin
visible: Finance, Exec
hidden: Sales, ViewerEven an enabled action only runs when the user holds the right and the action's own canExecute rule passes for the target record.
action Approve on Invoice
canExecute: status = 'draft'Every data mutation tracked: who, what, when, before, after. Financial modules carry full audit trails.
Refresh tokens, short-lived access tokens, secure rotation. No passwords stored in tenant databases.
Self-host in your region, your jurisdiction, your network. Backups, encryption, and policies under your control.
Your infrastructure.
Your rules.
Hosted at dforge.app. Managed infra, automatic backups, security patches, SSL/TLS in transit, db-level isolation per tenant.
- › managed postgres · per-tenant db
- › automated daily backups
- › patches applied automatically
- › eu & us regions
- › soc 2 · gdpr aligned
Run dForge inside your network. Docker, Kubernetes, or bare metal. Bring your own Postgres. Data never leaves your jurisdiction.
- › docker · k8s · airgapped
- › bring your own postgres
- › your own backup & encryption
- › custom firewall & network policies
- › regulatory data residency
Got compliance
questions?
We're happy to walk through your security and compliance requirements in detail — including DPAs, BAAs, and architecture deep dives.