At a glance
- Level
- Intermediate
- Time
- 10 min
Prerequisites
- Familiarity with your database's roles and permissions
- Access to the Kimo Bridge console (workspace admin) to review settings
- Optional: a running bridge to test the controls against
You will end up with
A clear picture of what crosses the tunnel, how every query is authorized and audited, how to revoke access, and a checklist your security team can sign off.
Connectors used
What leaves your network, and what never does?
Start with the inventory, because every other control exists to keep it true. The table describes a source in Bridge mode; a source in Cloud mode additionally syncs the tables you choose, through the same tunnel and under the same allow-lists.
| Item | Leaves your network? | Details |
|---|---|---|
| Query results | Yes, when policy allows | Typically aggregates; capped in rows, bytes and time |
| Audit metadata | Yes (mirror can be disabled) | Who, which source, SQL hash, decision, row count, duration — never result values |
| Health and version | Yes | Tunnel status, bridge version, certificate expiry |
| Raw tables | No | Only in Cloud mode, and only tables you list |
| Database credentials | No | Read from files on your host; never sent to Kimo |
| Bridge private key | No | Generated on your host at enrollment |
| Policy file | No (a read-only summary is shown in the console) | Changes require editing the file on your host |
| Full SQL text | Optional | Off by default; when on, literals are redacted |
One nuance matters for European teams: query results can contain personal data, and the EDPB considers remote access from a third country to data in the EEA a transfer in its own right.7Source 7 · European Data Protection Board, 2021Recommendations 01/2020 on measures that supplement transfer tools, version 2.0edpb.europa.eu The bridge minimizes what moves and records every movement; your policy decides whether results include personal data at all. The whitepaper Your Data, Your Rules covers the regulatory side in depth, and the glossary explains data residency.
Design principles
- No implicit trust from location. NIST's zero trust architecture rejects trust granted to assets or accounts based solely on their physical or network location.1Source 1 · National Institute of Standards and Technology, 2020SP 800-207: Zero Trust Architecturecsrc.nist.gov Being connected through the tunnel authorizes nothing by itself.
- Deny by default. OWASP's first prevention measure for broken access control — the top category in its 2021 Top 10 — is to deny by default except for public resources.4Source 4 · OWASP Top 10, 2021A01:2021 – Broken Access Controltop10.owasp.org A new bridge can reach your database but answers nothing until you allow tables and columns.
- The customer holds the keys. Credentials, private keys and policy live on your host. Kimo cannot widen access, and a compromise of Kimo cannot reveal your database password.
- Defense in depth. The bridge's parser, the policy, the database role and database row-level security each block bad queries on their own.
- Everything is attributable. Each query carries the identity of the Kimo user who caused it, from dashboard click to database log.
Scroll sideways to see the full diagram.
Identity and the tunnel
Enrollment
On first start, the bridge generates an asymmetric key pair on your host and sends Kimo a certificate signing request together with the enrollment token from the Bridge console. One-time tokens (kbt_) expire after 24 hours or one use; group tokens (kbg_) for Kubernetes enroll multiple replicas and can require human approval per new member. Kimo returns a client certificate bound to the bridge's key, workspace and group, valid for 24 hours and renewed automatically well before expiry. The private key never leaves the host.
Mutual TLS over TLS 1.3
The bridge opens one outbound connection to Kimo's regional endpoint on TCP 443 and negotiates TLS 1.3 only. TLS is designed to prevent eavesdropping, tampering and message forgery, and TLS 1.3 supports certificate-based client authentication through the server's CertificateRequest message.2Source 2 · IETF / RFC Editor, 2018RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3rfc-editor.org Both sides present certificates: the bridge verifies Kimo's endpoint against a CA bundle pinned in the image, and Kimo verifies the bridge's client certificate. RFC 8446 has since been obsoleted by RFC 9846, a backward-compatible revision that keeps the TLS 1.3 version number, so nothing changes for deployed bridges.3Source 3 · IETF / RFC Editor, 2026RFC 9846: The Transport Layer Security (TLS) Protocol Version 1.3rfc-editor.org
Why outbound-only matters
Because the bridge dials out, nothing listens for connections from the internet: no inbound firewall rule, no port forward, no public IP, no VPN account for a vendor. Your attack surface does not grow with the integration, and your egress policy can allow exactly one destination. The glossary entry on outbound-only tunnels compares this pattern with VPNs and IP allow-listing.
How is each query authorized?
Kimo compiles queries from your semantic layer, with filters and aggregations pushed down to the source. The bridge treats every one of them as untrusted input and runs it through the same pipeline:
- Step 1:
Verify the request signature
Each request is signed by Kimo and carries workspace, user, source, a SHA-256 hash of the SQL, the expected policy version, a nonce and a 60-second expiry. The bridge verifies the signature against a key pinned at enrollment and rejects replays and expired requests.
- Step 2:
Parse, do not pattern-match
The bridge parses the SQL with the source's dialect grammar. Only a single read statement is accepted. Stacked statements, DDL, DML,
COPY,SET, locking clauses and calls to functions outside a read-only allow-list (for exampleset_config,pg_read_file,dblink) are rejected. - Step 3:
Check every referenced table and column
All table and column references, including those inside subqueries, CTEs and views, are resolved and checked against the allow-list.
SELECT *is expanded before checking, so a newly added sensitive column is never silently included. - Step 4:
Apply row filters and group sizes
Row filters from the policy are injected using the requesting user's attributes (for example their regions). For grouped queries, groups smaller than
min_group_sizeare suppressed. - Step 5:
Enforce limits
Per-source rate limits are applied before execution; row, byte and time caps during it. A query that exceeds a cap is cancelled and returns an error, never a silently truncated result.
- Step 6:
Execute with the read-only role and log
The query runs in a read-only transaction under the bridge's database role. The decision, row count, bytes and duration are written to the audit log whether the query succeeded, failed or was denied.
policy:
default: deny
functions: read_only # built-in allow-list of side-effect-free functions
tables:
analytics.accounts:
columns: [id, region, plan, mrr_cents, created_at, churned_at]
row_filter: "region = ANY({{user.attributes.regions}})"
analytics.tickets:
columns: [id, account_id, priority, opened_at, closed_at]
min_group_size: 5
limits:
max_rows: 50000
max_bytes: 20MB
timeout: 30s
rate: 20/s
alerts:
denied_per_minute: 10 # alert when denials spikeKimo reads a summary of this policy to hide disallowed fields from users before they ever build a query, but enforcement happens only on your host. If Kimo's summary and your file disagree, the file wins and the console flags the mismatch.
The database layer: read-only roles and row-level security
The bridge's role should be able to do nothing but read the schemas you intend — the setup is in the Docker guide. Where different users may see different rows, add database-native row-level security so that the database enforces the same rule as the bridge, independently.
PostgreSQL makes this straightforward with one caveat set. Once RLS is enabled on a table, a default-deny policy applies if no policy exists; superusers and roles with BYPASSRLS always bypass RLS, and table owners do too unless the table forces it.6Source 6 · PostgreSQL DocumentationRow Security Policiespostgresql.org The bridge role must therefore be none of those. The bridge passes the requesting user's attributes to the session in a transaction-local setting, which RLS policies can read:
ALTER TABLE analytics.accounts ENABLE ROW LEVEL SECURITY;
ALTER TABLE analytics.accounts FORCE ROW LEVEL SECURITY;
-- The bridge sets kimo.user_regions with SET LOCAL inside each transaction.
-- The bridge's parser blocks set_config(), so queries cannot change it.
CREATE POLICY bridge_region_scope ON analytics.accounts
FOR SELECT TO kimo_bridge
USING (region = ANY (string_to_array(
current_setting('kimo.user_regions', true), ',')));With both layers in place, a mistake in the bridge policy file is caught by the database, and a mistake in the database grants is caught by the bridge. That redundancy is the point.
What does the audit log record?
Every request produces one JSON line in /var/lib/kimo-bridge/audit.jsonl (or on stdout in Kubernetes). The fields follow the when / where / who / what structure the OWASP Logging Cheat Sheet recommends, and deliberately exclude what it says not to log directly — access tokens, connection strings, keys and sensitive personal data.5Source 5 · OWASP Cheat Sheet SeriesLogging Cheat Sheetcheatsheetseries.owasp.org
{
"ts": "2026-10-03T09:14:22.418Z",
"event_id": "aud_01J9Z8M3Q4",
"bridge": "fra-prod-01",
"group": "prod-eu",
"source": "crm_pg",
"workspace": "ws_acme",
"user": "usr_7f3a",
"origin": "dashboard:board-deck/tile-4",
"request_id": "req_5c21e0",
"sql_sha256": "9b1f…e07a",
"policy_version": "2026-09-30.3",
"decision": "allow",
"reason": null,
"rows": 24,
"bytes": 1832,
"duration_ms": 212,
"prev_hash": "c4d2…11b9"
}- Tamper-evident. Each record includes the hash of the previous one, so a modified or deleted record breaks the chain.
kimo-bridge audit verifychecks it. OWASP recommends exactly this kind of tamper detection, plus copying logs to read-only storage quickly.5Source 5 · OWASP Cheat Sheet SeriesLogging Cheat Sheetcheatsheetseries.owasp.org - Two copies. Records are mirrored to Kimo's Activity view for analysts, while the local file stays authoritative for your security team. Ship it to your SIEM with your usual agent.
- Denials are first-class. OWASP also advises logging access control failures and alerting on repeated ones.4Source 4 · OWASP Top 10, 2021A01:2021 – Broken Access Controltop10.owasp.org Denied requests are logged with a reason (
column_not_allowed,rate_limited,signature_expired…) and thedenied_per_minutealert fires on spikes.
How do you revoke access instantly?
| Action | Who | Effect | Time to effect |
|---|---|---|---|
kimo-bridge pause | Your operator, on the host | Tunnel closed, in-flight queries cancelled, until resume | Immediate |
| Stop the container or scale to zero | Your operator | No process, no tunnel | Immediate |
| Remove the egress rule | Your network team | Tunnel cannot be established | Next connection attempt |
| Revoke in the Bridge console | Kimo workspace admin | Certificate revoked, tunnel dropped, Kimo-side caches purged | Seconds |
| Rotate the database password | Your DBA | Bridge loses database access even if running | Immediate for new connections |
Test the kill switch before you need it. A quarterly drill — pause, confirm dashboards show the source as unavailable, resume — takes five minutes and turns a theoretical control into a practiced one.
What if something is compromised?
A security model is only as good as its answers to bad days. The table organizes them by STRIDE category — spoofing, tampering, repudiation, information disclosure, denial of service and elevation of privilege.8Source 8 · Microsoft LearnThreats — Microsoft Threat Modeling Tool (STRIDE model)learn.microsoft.com
| Scenario | STRIDE | What an attacker could do | What stops or limits it |
|---|---|---|---|
| A Kimo user account is phished | Spoofing | Run queries that user's permissions and your policy allow | SSO and MFA, row filters scoped to the user, rate limits, attributable audit trail |
| Kimo's cloud is compromised | Elevation of privilege | Send signed queries within your local policy | Local policy cannot be widened remotely; no credentials or keys stored at Kimo; revoke to stop |
| Traffic is intercepted | Tampering, information disclosure | Nothing useful | TLS 1.3 with mutual authentication and pinned endpoint identity |
| An enrollment token leaks | Spoofing | Enroll a rogue bridge into your group, which would receive queries but holds no credentials | Token expiry, single use or approval-required group tokens, new-member alerts |
| Someone floods expensive queries | Denial of service | Load the source database | Rate limits, statement timeout, read replica, connection limits |
| A user disputes running a query | Repudiation | Deny responsibility | User identity in every signed request; hash-chained local log |
| The bridge host is compromised | All | Read the bridge's database credentials | Read-only, schema-scoped role; RLS; host hardening — this host is in your security scope |
Security review checklist
Before you put a source in production
- The bridge role is read-only, schema-scoped, not a superuser, not
BYPASSRLS, and does not own any table. - The role has a statement timeout and a connection limit; the DSN points at a replica where one exists.
- Egress allows only DNS, the database, and Kimo's regional endpoint on 443. No inbound rules exist.
- Credentials are mounted as files from a protected secret store, not passed as environment variables.
- The policy file is in version control, has
default: deny, and excludes direct identifiers unless a measure needs them. min_group_sizeis set for sources with personal data.- Audit logs ship to your SIEM;
kimo-bridge audit verifyruns daily; denial spikes alert someone. - Kimo workspace uses SSO with MFA (SSO & SCIM docs), and user attributes used in row filters come from your identity provider.
- The kill switch has a named owner and has been tested.
Ready to install? Follow Install Kimo Bridge with Docker for a single host or Deploy Kimo Bridge on Kubernetes for production clusters, or read the Kimo Bridge overview.
Sources
8 references- SP 800-207: Zero Trust Architecture (opens in a new tab)National Institute of Standards and Technology2020csrc.nist.gov
No implicit trust based solely on physical or network location.
- RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3 (opens in a new tab)IETF / RFC Editor2018rfc-editor.org
Goals of TLS; CertificateRequest for certificate-based client authentication.
- RFC 9846: The Transport Layer Security (TLS) Protocol Version 1.3 (opens in a new tab)IETF / RFC Editor2026rfc-editor.org
Obsoletes RFC 8446 as a minor, backward-compatible revision with the same version number.
- A01:2021 – Broken Access Control (opens in a new tab)OWASP Top 102021top10.owasp.org
Deny by default; log access control failures and alert on repeats; rate-limit API access.
- Logging Cheat Sheet (opens in a new tab)OWASP Cheat Sheet Seriescheatsheetseries.owasp.org
When/where/who/what attributes; data not to log; tamper detection.
- Row Security Policies (opens in a new tab)PostgreSQL Documentationpostgresql.org
Default-deny; bypass by superusers, BYPASSRLS and table owners unless forced.
- Recommendations 01/2020 on measures that supplement transfer tools, version 2.0 (opens in a new tab)European Data Protection Board2021edpb.europa.eu
Remote access from a third country to EEA data is also considered a transfer.
- Threats — Microsoft Threat Modeling Tool (STRIDE model) (opens in a new tab)Microsoft Learnlearn.microsoft.com
STRIDE category definitions.
External sources were accessed at the time of writing. Kimo product details, customers and figures in examples are illustrative unless a source is cited.
Mark as done
0 of 9 sections done
Frequently asked questions
Can Kimo employees see my data?
They cannot read your database: Kimo holds no credentials for it, and the bridge only answers queries your policy allows, each attributed to a user in your workspace. In Bridge mode, results exist on Kimo's side only in transit and, if you allow it, in short-lived caches you can disable.
Can Kimo change my bridge policy remotely?
No. The policy is a file on your host. Kimo displays a read-only summary and can request less than it allows, but widening access requires editing the file and reloading the bridge.
Is the full SQL of each query logged?
By default the audit log stores a SHA-256 hash of the SQL, not its text. You can enable full SQL logging with literals redacted, which helps investigations without writing filter values such as names into logs.
What happens if Kimo is unavailable?
The bridge keeps retrying the outbound connection with backoff. Your database is unaffected, nothing is queued, and dashboards that rely on bridged sources show them as unavailable until the tunnel is back.
Does the bridge need internet access beyond Kimo?
No. It needs DNS, your database, and Kimo's regional endpoint on TCP 443. Image updates come from your registry or ghcr.io when you choose to pull them, not from the running bridge.
How quickly does revocation take effect?
Pausing or stopping the bridge on your host is immediate. Revoking in the Kimo console revokes the certificate and drops the tunnel within seconds, and purges Kimo-side caches for that bridge.
Skip the setup — start from a working version.
Open the app and follow along with the steps in this guide.




