Bring your own database
By default your workspace lives on the hdls-managed database, isolated from every other workspace by Postgres row-level security. Bring-your-own-database (BYO-DB) is the alternative for teams who want their records to live in their own Postgres: you link an existing database, and hdls operates on it directly through the same tools — discovering its tables and serving them as MCP tools, just like a managed product.
💬 Just ask
- "Connect hdls to my own Postgres database and show me its tables."
- "Use my company's database instead of the managed one."
You don't call these tools yourself — just tell your assistant; the technical reference below is for when you want the details.
Most customers never need this. The managed database needs no setup and is isolated by the database itself. BYO-DB is for teams with a hard requirement that their data stay in a Postgres instance they control.
At a glance
| Step | What happens | Who can do it |
|---|---|---|
| Link your Postgres | hdls validates the connection string, encrypts it, and stores it as a linked data source | admin / owner |
| Mint a key scoped to it | A scoped API key is issued, bound to that data source + a schema + a role | admin / owner |
| Use it | Any call presenting that key operates on your database; the engine introspects it and serves its tables | per the key's role |
When you connect with a BYO-DB credential, isolation is your own database boundary — there is no shared multi-tenant surface, because no other workspace's data lives in your Postgres. That also means a few managed-only features (like workspace memory and cross-product links) don't apply on a linked source.
How linking works
You hand hdls a standard Postgres connection string and the schema you authorize it to operate within. hdls then operates on that database directly. Two things happen before anything connects:
- The connection string is validated against a strict safety check (below).
- It's encrypted at rest. The string is envelope-encrypted and stored as ciphertext — decrypted only in memory at the moment a query runs, and never logged or returned.
From then on, the engine introspects your database and exposes its tables through
the same generic power tools — list_tables, describe_table,
query_records, and the rest.
The guardrails that keep it safe
A connection string is a powerful thing to hand a server — left unchecked, it could be pointed at an internal host or a cloud metadata endpoint to turn hdls into a confused deputy inside its own network. hdls refuses that. Every linked connection string must pass a hard SSRF check:
- Real network Postgres only. It must be a
postgres:///postgresql://network host. Unix-socket and host-less strings are rejected. - No private, loopback, or metadata addresses. The host is resolved and checked
against a blocklist of private, loopback, link-local, and cloud-metadata ranges —
including
169.254.169.254,127.0.0.0/8, the RFC1918 ranges (10/8,172.16/12,192.168/16), CGNAT, and their IPv6 equivalents. If any resolved address falls in a blocked range, hdls refuses to connect. - DNS-rebind protection. To close the gap where a hostname passes the check and is then re-pointed at an internal host the instant before connecting, hdls resolves and validates the host's IP once, then pins the connection to that exact address. The original hostname is still used for TLS certificate verification, so security isn't weakened — the socket simply can't be redirected after the check.
Crucially, this check runs twice — when you link the database and every time hdls opens a connection to it. So even a row that somehow slipped past the first check still can't connect to a forbidden host. Defense in depth, by design.
Minting a key scoped to it
Once a database is linked, you mint a scoped API key bound to that data source. The key carries:
- the data source it's pinned to (your linked Postgres),
- the schema it may operate within,
- a role (
reader/member/admin/owner) that gates what it can do, - optionally an expiry and fine-grained scopes.
The plaintext key is shown to you exactly once at creation and only ever stored hashed — a database compromise can't leak a usable key. Treat it like a password: keep it in a secret manager, never in source control.
Authorization: Bearer hdls_…
Present that key on your requests, and every call resolves to your linked database — the engine introspects it and operates on it, with no shared row-level security because there's no other workspace's data to isolate from.
What you're responsible for
| Concern | hdls handles | You handle |
|---|---|---|
| Connection safety | SSRF blocklist + DNS-rebind pinning, checked at link and connect | Provide a real, externally-reachable Postgres host |
| Secret handling | Connection string envelope-encrypted at rest, decrypted only in memory, never logged | — |
| Key handling | Hashed at rest, scoped, revocable, optional expiry | Store the one-time key in a secret manager; rotate/revoke; never commit |
| Isolation | Your own database boundary (no shared multi-tenant surface) | Your database's own access controls and backups |
Admin/owner only. Linking a database and minting keys are privileged actions. A reader or member can use a BYO-DB key once it exists, but cannot create the link or issue the credential.
Where to go next
- Operate the linked database with the power tools.
- Review the full trust model — RLS, OAuth, signed webhooks, encryption — on the Security & trust page.