Data & Security¶
How Data Bridge handles and protects your Exact Online data. It covers what Exact's App Center Data & Security review asks: the purpose of the app, the data it uses, and how that data is used and protected.
Purpose¶
Data Bridge exposes your Exact Online data as a normalized REST API and an MCP server for AI tools, so your own scripts and the tools you authorize can read your administrations. Grants per key, data type, access level and administration control what each caller can do.
Data we access¶
Every data type is one resource in the API and MCP server. A key (or connected app) can only reach a resource and administration you have explicitly granted.
| Resource | Exact endpoint | What it is | Operations today |
|---|---|---|---|
accounts |
crm/Accounts |
Customers, suppliers and prospects (relations) | list, get |
contacts |
crm/Contacts |
Contact persons of relations | list, get |
items |
logistics/Items |
Products and services | list, get |
sales-invoices |
salesinvoice/SalesInvoices |
Sales invoice headers (number, customer, dates, status, amounts) | list, get |
gl-accounts |
financial/GLAccounts |
General-ledger accounts (chart of accounts) | list, get |
The resources shipped today are read-only. The grant model already distinguishes read, write and delete per resource and enforces the correct level per operation, so a write or delete grant is only possible on a resource that actually offers those operations, a read-only key can never change data.
For each resource, only a fixed, allowlisted set of fields is ever fetched from Exact (an explicit
$select), and only allowlisted filters and sort keys are accepted. Unknown filters are rejected
before any Exact call is made.
How data flows¶
- A caller authenticates, an API key (
Authorization: Bearer exg_live_…) for REST, or an MCP OAuth 2.1 access token for AI tools. - Data Bridge asks the portal whether the organization's subscription is active, then checks the key's or token's grants (resource × read/write/delete × administration) and the key's optional IP allowlist.
- Only then does it read from Exact Online (
start.exactonline.*) through the portal's token broker, using a short-lived access token for the administrations you have enabled. - The result is normalized and returned to the caller. Metering records that an operation happened (per day, resource and operation), never the data itself.
The response is returned to the caller and nowhere else. It contains only the fields the resource exposes, from the administrations the caller is allowed to see.
What we store, and why¶
| Data | Where | Protection |
|---|---|---|
| API keys | the app's database | SHA-256 hash only; the key itself is shown once at creation and never kept |
| Grants and IP allowlist per key | the app's database, per organization | to decide what each call may do |
| MCP OAuth authorizations (tool, grants, approver) | the app's database, per organization | payloads AES-256-GCM encrypted; opaque tokens keyed by SHA-256 of their id |
| Usage metering (day × resource × operation) | the app's database, per organization | counts only, no data |
| The opt-in cache, when it is on | encrypted, per organization, TTL up to 24 h | see the cache below |
| Account, organization and billing records | in the portal | see the portal's data & security document |
What we do not store¶
- Exact data is passed through, not kept. A call reads from Exact, is checked against the grants, and is returned to the caller. We hold no standing copy of your customers, invoices or ledger, the only exception is the opt-in cache below, which is encrypted, per organization, TTL-bounded and purged the moment the connection it came from is disconnected or disabled.
- No Exact refresh tokens. The portal's token broker hands Data Bridge a short-lived access token (10 minutes, memory only) per call; the refresh token never leaves the portal.
- No credentials, sessions or billing records. Accounts, sessions, two-factor authentication and billing live in the portal.
- No telemetry or tracking. No analytics, no license check, no advertising.
How the data is protected¶
In transit¶
- TLS everywhere: caller ↔ Data Bridge, Data Bridge ↔ Exact Online, Data Bridge ↔ portal.
- Between the portal and the apps the edge exchanges the session for a short-lived, EdDSA-signed assertion (60 s, bound to this app); the apps and portal authenticate each other on an internal network with per-app service tokens.
At rest¶
- API keys are stored only as a SHA-256 hash, a database dump cannot recover them.
- OAuth/MCP payloads are AES-256-GCM encrypted with a versioned keyring; each ciphertext is bound to its own record (AAD), so a value copied into another row does not decrypt.
- The cache (below) is encrypted the same way.
The opt-in cache¶
Caching is the one place a copy of Exact data can briefly rest inside Data Bridge, so it has the strictest controls:
- Off by default. An organization owner or administrator turns it on, with two-factor authentication, and the change is written to the portal's audit log.
- Encrypted at rest. Every entry is AES-256-GCM encrypted with the versioned keyring and an AAD bound to the organization and the cache key, so a ciphertext only decrypts under its own organization and request.
- No filter values leak. The cache key is a SHA-256 over the administration, resource and version and the request parameters (canonicalized); the filter values themselves are not part of the stored key.
- Time-bounded. The TTL is set by the organization between 1 minute and 24 hours. Entries expire with their TTL and a periodic sweep removes expired rows.
- Authorized on every hit. The access policy runs before any lookup, and a hit is only served while the Exact connection is active and the administration is still enabled, so disconnecting Exact or disabling an administration stops cached data being served immediately.
- Bound to the connection. The key includes the connection's creation time, so reconnecting (possibly to another Exact company) never serves the previous connection's data.
- Purged aggressively. Entries are dropped when the cache is switched off or its TTL is shortened, when a write invalidates that resource and administration, when the portal reports a disconnect or re-authorization, and when the organization is deleted.
- Bounded size. A single entry larger than 512 KB is not cached, and errors are never cached.
When a Valkey (Redis) store is configured the cache lives in memory only; otherwise it is the encrypted Postgres table described above. In both cases the entry is encrypted before it is written.
Access control¶
- Least privilege by default: a new key starts with no access; you grant data types, access levels and administrations explicitly.
- Creating keys and approving an AI tool require an organization owner or administrator with two-factor authentication, and an MCP connection only keeps working while that remains true (re-checked on every call).
- Denied calls are recorded in the portal's audit log (what, by which key, and why).
Hosting and operations¶
- Hosted in the EU. Containers run as a non-root user on a read-only root filesystem with all capabilities dropped.
- Dependencies and container images are scanned for vulnerabilities daily (Trivy, HIGH/CRITICAL fail).
- Error reports (GlitchTip) are opt-in and scrubbed: no headers, cookies, bodies, query strings or user information are collected.
Retention and deletion¶
- The cache is TTL-bounded and purged on disconnect, disable, switch-off, write and deletion, as above.
- API keys, grants, OAuth authorizations, metering and cache are all deleted immediately when the organization is deleted in the portal.
- The audit log lives in the portal and is kept for the lifetime of the organization.
Who receives the data¶
| To | What | Why |
|---|---|---|
| your keys and connected AI tools | the Exact data the call is granted | the purpose of the service |
Exact Online (start.exactonline.*) |
the reads (and future writes) the calls trigger | the purpose of the service |
| Mollie | the payment for the subscription, in the portal | billing |