Skip to content

Data & Security

How GitLab Sync handles and protects your 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

GitLab Sync books the time logged in GitLab as hours in Exact Online, one draft line per person, issue and day, turns GitLab issues (and milestones) into Exact WBS activities (and deliverables), and writes the hour status back to GitLab as exact::… labels.

Data we access

From Data Use
GitLab (gitlab.com or your self-hosted instance) time logs, issues, milestones, labels and project metadata to create the draft hour lines and WBS lines, and to write status labels back
Exact Online projects, WBS deliverables/activities, hour lines (project/TimeTransactions) and employees the synchronization target, one draft hour line per person/issue/day

GitLab Sync never reads your source code, branches or diffs, only the time logs, issues, milestones, labels and project metadata listed above.

How data flows

  1. An administrator links a GitLab project to an Exact project (the link requires an organization admin with two-factor authentication).
  2. On schedule, on a webhook or on "Sync now", GitLab Sync reads time logs, issues and labels from GitLab, and the current project/WBS/hour state from Exact.
  3. It writes to Exact only draft hour lines and WBS lines (hour lines are never written as anything but draft, and only while they are still draft or rejected), and writes the exact::submitted/approved/rejected labels back to GitLab.
  4. Every write is recorded with a hash so a run is idempotent, it never writes the same line twice.

What we store, and why

Data Where Protection
The GitLab access token of each connection the app's database AES-256-GCM encrypted, one key per organization, bound to its own record (AAD). Only the last four characters are ever shown; the token itself is never returned or logged
Linked projects and sync state (cursors, last run, the hashes of the written lines) the app's database, per organization to keep the sync idempotent and resumable
GitLab usernames and e-mail addresses of people who logged time, and their match to an Exact employee the app's database, per organization so a time log lands on the right employee
The webhook secret of each linked project as a SHA-256 hash (the secret itself is not kept) to verify a webhook came from your GitLab
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. The sync reads a time log, writes the hour line, and discards the rest. We hold no copy of your Exact projects, employees, invoices or any other Exact data, only the identifiers and hashes a correct next run needs.
  • No GitLab source code, branches or diffs.
  • No Exact refresh tokens. The portal's token broker hands GitLab Sync a short-lived access token (10 minutes, memory only) per call; the refresh token never leaves the portal.
  • No cache. GitLab Sync does not cache Exact or GitLab data in any form.
  • No telemetry or tracking. No analytics, no license check, no advertising.

How the data is protected

In transit

  • TLS everywhere: browser ↔ GitLab Sync, GitLab Sync ↔ GitLab, GitLab Sync ↔ Exact Online, GitLab Sync ↔ portal.
  • Between the portal and the app the edge exchanges the session for a short-lived, EdDSA-signed assertion (60 s, bound to this app); the app and portal authenticate each other on an internal network with a per-app service token.

At rest

  • GitLab access tokens are AES-256-GCM encrypted with a versioned keyring and an AAD bound to the connection, so a token copied from one row does not decrypt in another.
  • Webhook secrets are stored only as a SHA-256 hash and checked in constant time.

Outbound safety (SSRF)

  • Customer GitLab URLs are reached only through a safe fetch pinned to the host the tenant configured for that instance, so the token can reach nothing else.
  • The connect-time DNS answer is checked (rebinding-safe), private/loopback/link-local ranges are refused, redirects are refused, and only the fixed /api/v4 and /api/graphql paths are used.
  • Exact access is limited to the organization's enabled administrations (via the broker), and the writes are limited to the project/WBS/time resources by the resource schemas.

Access control

  • Changes (tokens, links, mappings) require an organization admin with two-factor authentication; "Sync now" is available to members.
  • Webhooks are triggers only: the secret is verified, the payload is ignored, and the sync re-reads GitLab, a spoofed webhook cannot inject data.
  • The audit log in the portal records who changed what.

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

  • Deleting the organization in the portal immediately deletes everything GitLab Sync stores for it: connections (and their encrypted tokens), links, mappings and sync state.
  • Replacing a token from GitLab connections rotates it without touching the linked projects.
  • The audit log lives in the portal and is kept for the lifetime of the organization.

Who receives the data

To What Why
your GitLab instance the token's calls (time logs, issues, labels) and the exact::… labels written back the purpose of the service
Exact Online (start.exactonline.*) draft hour lines, WBS lines, and the project/WBS/hour reads, for the enabled administrations the purpose of the service
Mollie the payment for the subscription, in the portal billing