Customer data processing agreement — Vej SaaS API
DRAFT FOR LEGAL REVIEW — 2026-10-10. Not legal advice. Nothing signed or sent. This template is not an offer of a live, verified service. Complete all brackets, settle retention and implement its enforcement, resolve the provider review, and pass the ADR launch gates before use.
1. Parties, roles and precedence
Controller: [customer legal name, address, registration number, privacy contact]. Processor: [Vej operating legal entity, address, registration number, privacy contact]. Main service agreement: [reference/date]. Effective date: [date].
The customer determines the purposes and means of processing and is the controller. Vej processes personal data on its behalf as processor under GDPR Article 28 (retrieved 2026-10-10). This DPA, including its annexes, governs that processing and prevails over conflicting service terms about data protection. If the customer instead acts as processor, counsel must adapt this template to the controller's instructions and authorization before signing.
Legal review must identify any account administration, billing or statutory records for which Vej acts as an independent controller and disclose them in a separate privacy notice with purpose, legal basis and retention. They must not be silently treated as processing under this DPA. The present API implements no payments, billing integration, self-service signup or customer login.
2. Subject matter, duration and processing instructions
Subject matter: native probability inference over developer-supplied outcomes through authenticated realtime and asynchronous batch API calls, plus the metadata necessary for authentication, limits, metering and job orchestration. Purpose: provide the customer's requested decision probabilities and operate that service. Nature: receive, validate and transiently compute on content; return probabilities; read/write customer batch objects; store the disclosed service metadata in Annex A. No content is used for training.
Processing lasts for the service agreement and agreed metadata deletion/return periods. Content processing lasts only while executing the request or batch shard attempt; cancelled, expired and failed work is discarded. Batch retries read again from the customer's storage. There is no guaranteed 24-hour batch completion. Jobs expire at the earliest submitted URL expiry, at most seven days.
This DPA, the agreed configuration and authenticated API submissions are the customer's documented instructions. Additional instructions must be documented in writing by [authorized contacts/channel]. Vej processes only on those instructions, including instructions about transfers, unless Union or Member State law requires otherwise. Vej informs the customer of that legal requirement before processing unless the law prohibits notice on important public-interest grounds. Vej immediately informs the customer if an instruction infringes applicable data protection law and suspends that instruction pending resolution.
The customer establishes a lawful basis, gives required notices, selects lawful inputs and purposes, and maintains its own storage, access and retention policy. These responsibilities do not remove Vej's processor obligations.
3. Content ZDR scope and data categories
The proposed promise is reproduced exactly from the economics report:
“Your request content and returned probabilities are processed in the EU, are not written to persistent storage, are not retained for reuse after the request, and are not used for training. We retain disclosed account, billing, and operational metadata.”
This promise concerns Vej-controlled service storage. Batch input and output files remain in the customer's own EU object storage, accessed through customer-issued pre-signed GET/PUT URLs; the customer instructs Vej to write results there. Customer storage retention is outside Vej's content-ZDR scope. The reference to billing does not add a billing implementation to this API. The promise does not guarantee instantaneous forensic erasure of every freed RAM/VRAM byte or exemption from mandatory lawful obligations. No routine abuse, support, analytics or training content-retention exception is authorized.
Data subjects: [customer's employees, contractors, end users, customers, prospects or other persons represented in inputs; customer to complete]. Personal data: [customer to specify identifiers, communications, documents, images and any other categories present in state, outcomes or rubric inputs]. Returned probabilities may relate to these persons. Any special-category or criminal-offence data and the applicable safeguards must be specified here: [categories/conditions, or none]. This draft does not approve such use cases. Service metadata can also be personal data even where identifiers are digests.
4. Confidentiality, subprocessors and assistance
Vej limits access to authorized persons who need it to perform these instructions and are bound by confidentiality or an appropriate statutory obligation. The obligation continues after their access or employment ends. Real request content, probabilities and pre-signed URLs must not be copied into support tickets.
The customer grants general written authorization only for subprocessors in Annex C's Authorized subprocessors table. Before adding or replacing one, Vej gives written notice to [customer contact] at least [N] days beforehand, describing identity, location, service and data scope. The customer may object on reasonable data protection grounds within [N] days. The parties seek a compliant alternative; if none is available, the affected processing will not move to that subprocessor and [termination/refund arrangement] applies. Notice periods and emergency arrangements must be agreed against upstream provider terms before signing.
Vej imposes equivalent data protection obligations on each subprocessor by written contract, including sufficient Article 32 guarantees, and remains fully liable to the customer for that subprocessor's performance of those obligations. Self-hosted Postgres and Temporal are software components, not separate hosted service suppliers; any external hosting/access parties must be included in Annex C.
Taking account of the nature of processing, Vej assists the customer through appropriate technical and organizational measures with data-subject rights under GDPR Chapter III. It forwards requests promptly to [customer contact] and does not independently answer except on instructions or as required by law. Content cannot be retrieved from Vej after processing; assistance concerns retained metadata and customer-controlled batch objects. No account-management API is currently implemented, so an operator procedure must be agreed.
Taking account of the processing and information available, Vej assists with Articles 32–36 obligations, including security, breach notices, DPIAs and prior consultation with supervisory authorities. [Assistance channel, response targets and lawful fee arrangement to be agreed.] Do not send real content to establish a support reproduction.
5. Personal data breaches
Vej notifies [customer security contact/channel] without undue delay after becoming aware of a personal data breach and, as an additional contractual ceiling, within [N] hours after awareness — to be agreed. This placeholder does not delay the without-undue-delay obligation or create a confirmed provider SLA.
The initial notice supplies available information about the nature of the breach, affected data/data-subject categories and approximate numbers, contact point, likely consequences, and containment/remediation measures. Vej supplies missing information in phases without undue further delay, preserves content-free incident evidence, cooperates in mitigation and assists the customer's statutory notifications. Incident handling does not authorize retaining live request content.
6. Return, deletion, audits and transfers
At the customer's choice, Vej returns or deletes personal data processed under this DPA at the end of services and deletes existing copies, unless Union or Member State law requires retention. [Return format, deadline and deletion confirmation procedure] must be agreed. There is no service-side content archive to return. Batch files stay with the customer; Vej cancels pending work and wipes stored URL ciphertext. Annex A's ordinary periods do not override an earlier valid deletion instruction or the end-of-service choice.
Any mandatory retained data must be identified with legal basis, category and expiry, isolated from further use except the required purpose, and deleted when the obligation ends. Backup expiry, Postgres WAL and Temporal deletion procedures must be settled before signature; a SQL NULL update alone is not erasure of historical copies.
Vej makes all information necessary to demonstrate Article 28 compliance available and allows/contributes to audits, including inspections, by the customer or its appointed auditor. [Reasonable notice, safe access, confidentiality and costs] shall be agreed without preventing statutory rights, regulator access or necessary incident audits. Evidence can include configuration, content-free canary results and provider reports; no audit may expose another customer's data.
No international transfers are planned: service processing, support access, metadata, backups and approved storage endpoints must remain within the EU. Vej will not introduce a routine non-EU transfer under this DPA without amended written instructions, customer approval and a lawful GDPR Chapter V mechanism, including SCCs and supplementary safeguards where required. SCCs alone do not preserve the stated EU-only service scope. Mandatory legal exceptions are handled under clause 2; unresolved provider transfer permissions must be closed before this promise is signed.
7. Liability, governing law and execution
Liability and any contractual allocation: [to be agreed consistently with GDPR, including Article 82; statutory rights and subprocessor responsibility preserved]. Governing law and competent courts: [EU Member State/jurisdiction to be agreed]. Customer signatory/date: [ ]. Vej signatory/date: [ ]. All placeholders and annexes require legal approval before execution.
Annex A — metadata categories and retention schedule
This inventory uses the final schema after migrations 0001–0005, including batch tables, model alias, submitting key and idempotency digest migration. Periods below marked “to be decided” are placeholders, not existing cleanup jobs or a signed schedule. UTC calendar-month quota windows are not retention periods. Set a trigger, responsible operator, purge job and backup deadline for each category before launch.
| Category/store | Actual fields or payload scope | Purpose | Retention/deletion trigger |
|---|---|---|---|
| Organizations/Postgres | id, name, tier, vision_enabled, created_at | Account attribution and admission | [N] months after account closure — to be decided |
| API keys/Postgres | id, organization_id, key_hash (32-byte SHA-256 digest), prefix, created_at, revoked_at | Authentication, attribution and revocation | [N] months after revocation/account closure — to be decided |
| Usage events/Postgres | id, organization_id, api_key_id, occurred_at, source, route, requests, processed_tokens, checkpoint_digest, status_class | Metering and quota enforcement | [N] months after event — to be decided |
| Batches/Postgres | id, organization_id, api_key_id, endpoint, cloudflare_model, status, idempotency_key_sha256, created_at, expires_at, cancelled_at, completed_at, shard_count, shards_completed, shards_failed, shards_expired, shards_cancelled, shards_quota_exceeded, lines_ok, lines_failed, processed_tokens | Polling, reconciliation, metering and organization-scoped idempotency | [N] months after terminal state — to be decided; includes digest expiry/reuse window |
| Shards/Postgres | id, batch_id, ordinal, status, attempts, lines_ok, lines_failed, processed_tokens, finished_at | Work progress, retry and final accounting | [N] months after terminal state — to be decided; cascade on batch deletion |
| Shard URL ciphertext/Postgres | input_url_enc, output_url_enc, AES-GCM encrypted | Customer-authorized GET/PUT while unfinished | Set to NULL at shard terminal state; earliest URL expiry ≤7 days triggers expiration/wipe when reconciled; backup/WAL purge deadline [N] days — to be decided |
| Temporal history/visibility, separate Postgres databases | Batch/shard IDs, counts, workflow status/timing, expiry/parallelism and fixed failure codes; no content or URLs | Durable orchestration and recovery | Namespace initialization sets 1 day of closed-workflow retention; verify deployed configuration and actual deletion lag; visibility/backup/WAL purge [N] days — to be decided |
| Service operational logs | HTTP method, fixed route, status, latency and correlation identifier; no bodies, raw paths, account IDs, keys or URLs | Operations and incident diagnosis | [N] days after event — to be decided; verify each deployed sink and provider telemetry scope |
| Metadata backups/WAL/replicas | Copies of the above metadata, possibly pending URL ciphertext | Recovery | [N] days from backup/WAL creation — to be decided; agree deletion on termination and restored-copy purge |
The raw idempotency_key column is removed by migration 0005. Digests are scoped by organization for uniqueness. No custom_id, request/response content or raw customer Cloudflare account ID is a database field. Cloudflare batch paths use the fixed account placeholder batch; only route enum and model alias persist. No billing or payment columns exist. Vej's migration bookkeeping is technical schema state, not customer request metadata. Any new metadata category requires an updated disclosure and schedule before collection.
Annex B — Article 32 security measures and implementation status
These are repository controls and deployment requirements, not claims of a running production installation or independent certification.
| Measure | Repository evidence and boundary |
|---|---|
| Transport protection | Worker enforces HTTPS for production storage, validates allowlisted hosts/resolved addresses and disables redirects: storage policy, handler. Public TLS ingress must be supplied by the operator; deployment guide requires exposing only the API and configuring Postgres TLS. Internal service HTTP is not represented as end-to-end TLS. |
| No body logging or disk spooling | API startup filters logs to the fixed request category and removes proxy HTTP loggers; worker startup clears logging providers and removes storage/adapter HTTP loggers. ADR ZDR boundaries prohibit content in telemetry/durable stores. Ingress raw-path/body logging, host swap/crash dumps and provider captures require separate verification. |
| EU-only scope | Production storage startup requires a verified EU host allowlist; hostname checks do not establish residency. Operators must verify hosting, support, replication and each customer endpoint. No automated geographic attestation or production EU deployment is claimed. |
| Stored URL encryption | UrlProtector uses AES-GCM with a 32-byte configured key and shard/purpose binding. Shard processing and terminal transitions wipe ciphertext. Key custody/rotation and historical-copy expiry must be operationally agreed. |
| API-key protection and minimized identifiers | API key seed persists a SHA-256 digest and prefix; migrations store digests rather than full keys. Batch idempotency stores 32-byte digests, with organization-scoped uniqueness. These controls do not anonymize all metadata. |
| Network isolation and host hardening | SaaS NetworkPolicies default-deny traffic, restrict adapters/worker/Temporal, and bound database/storage egress. Services are ClusterIP; containers use non-root users and restricted privileges. Temporary paths /tmp and /dev/shm use memory-backed volumes; adapter /cache volumes use node disk for model/runtime caches and still require checks for request content. Operators must configure database CIDRs, restrict namespace writers and verify CNI enforcement; templates are undeployed. |
| Recovery and evaluation | Self-hosted Postgres/Temporal retain only disclosed metadata; workflow carries identifiers and non-content orchestration data. Canary procedure scans logs, databases, histories and temporary directories. Its bounded success is not proof for every deployment/failure path. Metadata backup/restore, deletion enforcement and operator access procedures remain to be verified. |
Vej shall maintain measures appropriate to risk, including availability, resilience, timely restoration and regular effectiveness evaluation under Article 32. The operational owners, review frequency and backup/restore evidence are [to be agreed and verified before signature]. Material changes must preserve the agreed protection and be reflected in this annex.
Annex C — subprocessors
Authorized subprocessors
None. No provider DPA has been signed. The table below grants no authorization to any candidate.
| Entity | Function/data scope | Location | Authorization status |
|---|---|---|---|
| None | — | — | No subprocessors authorized |
A candidate becomes authorized only after the provider gate is closed, a provider DPA imposing the required equivalent obligations is signed, and clause 4's written notice and objection period has elapsed with any objection resolved. Vej then adds the entity, agreed scope and location to this table before processing begins.
Candidates (not authorized)
| Entity | Function/data scope | Location | Authorization status |
|---|---|---|---|
| Hetzner Online GmbH | Proposed hosting for transient inference and disclosed service metadata | GEX45 HEL1, Finland; EU support per published DPA | Chosen provider; provider gate and signed contract pending |
| Hetzner Finland Oy | Proposed downstream building rental/technical support for Finland hosting, as listed in Hetzner DPA Appendix 3 | Finland | Confirm exact access/data scope and flow-down terms before approval |
Before signing, identify the actual approved hosting chain, including any separate control-plane/Postgres host and downstream provider parties that process data. The provider review identifies publications and unresolved questions. Its global lists are not automatically approved here. There is no managed inference API subprocessor. The customer's own EU bucket provider is chosen/contracted by the customer; confirm its role and permissions per customer, rather than treating it as an undisclosed Vej storage supplier.