Skip to main content
  1. Legal documents/

fremverk Record of Processing Activities (ROPA)

On this page

title: Records of Processing Activities (Article 30 GDPR) date: 2026-05-14 status: Active. Reviewed quarterly; updated on every sub-processor change, every new processing activity, and every significant change to legal basis or retention. controller: fremverk ApS, CVR 39150689, Ringager 4C, 2. tv, 2605 Brøndby, Denmark contact: compliance@frem.sh dpo: not appointed (fremverk does not meet the Art. 37(1) mandatory-DPO criteria — not a public authority, core activities are Git hosting + CI infrastructure not large-scale systematic monitoring of data subjects, and Customer Personal Data does not include Art. 9 special-category or Art. 10 criminal-conviction data on a large scale). Assessment dated 2026-05-10, re-evaluated annually with the next §A.9 DR-drill review window (or sooner on material change to processing scope). compliance@frem.sh handles DSARs and supervisory-authority correspondence. #

Records of Processing Activities #

This document is the controller’s Article 30 record for the fremforge product. It reflects the current state of processing as of the date above and is reviewed at every sub-processor change, every privacy-impacting feature release, and at minimum quarterly.

A separate ROPA exists for fremverk corporate operations (employee data, customer-relationship-management, accounting), which is out of scope here.

1. Controller identification #

  • Name: fremverk ApS
  • Address: Ringager 4C, 2. tv, 2605 Brøndby, Denmark
  • Email: compliance@frem.sh
  • Privacy contact: compliance@frem.sh
  • Representative for non-EU controllers: not applicable (fremverk is established in the EU)
  • Data protection officer: not appointed; see header above for rationale.

2. Processing activities #

For each activity below: purpose, lawful basis, categories of data subjects, categories of personal data, recipients (internal teams, sub-processors), international transfers, retention, technical and organisational measures (TOMs).

2.1 Customer signup + tenant provisioning #

FieldValue
PurposeCreate the customer’s fremforge organisation; verify the customer’s email; route them through the right billing country / VAT-treatment branch.
Lawful basisArticle 6(1)(b) — performance of contract (the Service the customer is signing up for).
Categories of data subjectsProspective customer’s signing-up individual (sole-trader operator OR an authorised employee of a customer entity).
Categories of personal dataEmail; chosen org slug; chosen display name; billing country code; VAT identifier (if EU B2B); IP address (audit only). No special-category data.
Recipients (internal)Operations on-call (ops@frem.sh), security on-call (security@frem.sh if anomalous signup investigation needed).
Recipients (sub-processors)T Cloud (RDS — primary store of tenant + signup-attempt rows, OBS — verification-mail audit trail, LTS — operational logs); Lettermint B.V. (email delivery for the verification link); EU Commission VIES service (VAT lookup, public-sector lookup not an Art. 28 sub-processor — see DPA §11.2 amendment).
International transfersNone. T Cloud + Lettermint are EU. VIES is the European Commission.
RetentionFour distinct tiers, scope-stamped per data class:
signup_pending_confirmations rows (raw email + org_slug + display_name held until the customer clicks the confirmation link): ≤ 24 h, hard-deleted by the daily retention job past expires_at; on consumption the row migrates to the tenants table with full audit trail. Matches DPA Annex A.4.
signup_attempts rows (anti-abuse metadata — email-hash + IP + outcome): 30 days then anonymised.
tenants rows (core tenancy record): lifetime of the tenancy + 90 days post-cancellation (DPA §9 hard-delete window).
• Accounting records subset of the above (invoice line items + tenancy identifiers required to reconcile invoices): 5 years from end of the accounting year per Danish Bogføringsloven §10. After 90 days the row is pseudonymised — only the accounting-relevant columns survive into the 5-year archive; identifiers + email + display-name are nulled.
TOMsTLS-in-transit; KMS-encrypted-at-rest; per-IP rate limit; Altcha (self-hosted, HMAC-signed PoW) gate above soft threshold; signed-token confirmation flow with single-use enforcement (per audit batch 2 finding M-31).

2.2 Authentication + session management #

FieldValue
PurposeAuthenticate users to fremforge; issue and validate session tokens; maintain audit trail of authentication events.
Lawful basisArticle 6(1)(b) — performance of contract; for security-monitoring traces, Article 6(1)(f) — legitimate interest in fraud + abuse prevention.
Categories of data subjectsAny authenticated fremforge user (org member, admin, or break-glass operator).
Categories of personal dataOIDC/SAML subject identifier; email (if the IdP propagates it); session ID; access-token hash (stored hashed, never plaintext); IP; user agent; timestamp.
Recipients (internal)Operations on-call (audit log review during incident response).
Recipients (sub-processors)T Cloud RDS (session-row store); T Cloud DCS Redis (ephemeral session cache, see DPA Annex A.4 amendment). Customer-side: the Customer’s own OIDC/SAML IdP (Microsoft Entra, Okta, Google Workspace, Authentik, etc.) — the Customer’s processor, not fremverk’s sub-processor.
International transfersDetermined by the Customer’s IdP location. fremverk-side processing is EU-only.
RetentionActive session: TTL 7 days. Session table after expiry: 30 days for forensics. Authentication audit trail: 90 days hot + 3 years immutable WORM archive (DPA Annex A.7).
TOMsTLS-in-transit; HTTPS-only cookies; SameSite=Strict; CSRF token; rate-limit on /login/discover; Altcha (self-hosted, HMAC-signed PoW) gate on threshold.

2.3 Repository content + Git operations #

FieldValue
PurposeHost the customer’s source code, run Git operations (clone, push, pull), display issues + PRs, deliver webhooks.
Lawful basisArticle 6(1)(b) — performance of contract.
Categories of data subjectsCustomer’s developers (org members), commit authors (may include former contributors who are no longer org members), people referenced in issues/PRs/code-review comments.
Categories of personal dataCommit author name + email (in git log metadata); issue/PR comment text (free-form, may include any personal data the Customer chose to include); SSH public keys; webhook endpoint URLs.
Recipients (internal)Operations on-call (only on incident-response basis with audit-logged justification).
Recipients (sub-processors)T Cloud SFS Turbo (git object store); T Cloud OBS (LFS objects + repository-archive snapshots); T Cloud RDS (Forgejo’s metadata DB — issues, PRs, users, hooks).
International transfersNone. T Cloud eu-de only.
RetentionActive repository content: lifetime of the tenancy. After cancellation: 90 days post-cancellation hard-delete window (DPA §9). After repository deletion within an active tenancy: 14 days backup-retention grace before purge from snapshot tier (the same 14-day window the live-tier backup lifecycle in DPA §9 + Annex A.9 enforces — audit P2-27 fixed the broken cross-reference; the previous “DPA Annex A.10” cite was wrong, A.10 is Personnel). Audit log of repository-level operations: 90 days hot + 3 years immutable WORM archive (DPA Annex A.7).
TOMsKMS-encrypted-at-rest (SFS Turbo + OBS); per-tenant access control (Forgejo orgs); webhook-egress filtered through outbound proxy when implemented (currently /32-allowlisted via auto-refresh CronJob, see fremforge/forgejo/.infrastructure/k8s/forgejo-egress-refresh.yaml).

2.4 Billing + payment processing #

FieldValue
PurposeCharge subscription Fees; issue invoices; reconcile payment failures; send payment-receipt emails.
Lawful basisArticle 6(1)(b) — performance of contract; Article 6(1)(c) — legal obligation (Bogføringsloven §10 retention).
Categories of data subjectsAuthorised billing contact for the customer organisation (typically the operator who signed up).
Categories of personal dataBilling contact email; billing country; VAT identifier; payment-method tokenized identifier (Mollie returns a token, never the PAN); SEPA mandate ID; transaction state-machine timestamps; invoice line items + amounts. No card PAN. No bank account number.
Recipients (internal)Finance + operations on-call.
Recipients (sub-processors)Mollie B.V. (payment processor — sees full card or SEPA details under PCI-DSS scope; fremverk receives only the tokenized result); T Cloud RDS (invoice + tenant-billing-state store); Lettermint B.V. (invoice email delivery); Visma Dinero ApS (accounting / 5y statutory invoice retention under Bogføringsloven §10 — see DPA Annex B).
International transfersNone at fremverk’s scope. Mollie’s card-network sub-processors (Visa Europe Services Inc. UK branch; Mastercard Europe SA Belgium) are PCI-DSS-attested; per DPA Annex B note.
RetentionActive billing: lifetime of the tenancy.
Post-cancellation: invoices + transaction records (the accounting-records subset) are retained 5 years from the end of the accounting year per Danish Bogføringsloven §10. Mollie / Dinero processor-side records follow the same legal floor (handled under each processor’s DPA). Customer-Personal-Data fields not required for accounting reconciliation (email, display-name, repository content references) are pseudonymised at 90 days post-cancellation under DPA §9 — only the accounting-relevant columns survive into the 5-year archive.
TOMsTLS-in-transit; PCI-DSS Level 1 at the Mollie boundary; idempotency token on every webhook; Mollie egress IP allowlist on the inbound webhook ELB (per audit batch 2 finding H-15a).

2.5 Operational logs + observability #

FieldValue
PurposeDiagnose product errors; trace incidents; meet audit obligations under DPA Annex A.7.
Lawful basisArticle 6(1)(f) — legitimate interest in service stability + security monitoring; Article 6(1)(c) — legal obligation (audit-trail retention under DPA Annex A.7 for AUP enforcement).
Categories of data subjectsAny user whose request transits the fremforge stack (request-path traces include user identifier + IP).
Categories of personal dataRequest paths; user-agent strings; IPs (anonymised or pseudonymised before storage where feasible); user identifiers; structured business-event metadata.
Recipients (internal)Operations on-call (LTS read access); security on-call (audit-stream read access).
Recipients (sub-processors)T Cloud LTS (log store); T Cloud OBS WORM bucket (3-year audit archive — per DPA Annex A.7); T Cloud SMN (operator alert delivery for byte-rate / chain-break / stream-sprawl signals — no Customer Personal Data in the message body, only resource identifiers).
International transfersNone.
RetentionOperational logs (api/forgejo/jobs LTS groups): 30 days hot. Audit logs (audit LTS group): two-tier. Hot (queryable) tier with full event payload (actor, action, fields_json) is a per-tenant policy with presets of 90 / 180 / 365 / 730 days; default 90 days for the standard plan, 365 days for enterprise / enterprise_trial / internal plans (Customer tenant admin sets the tier at Authentication policy → Audit log retention; the CHECK constraint at migration 0146 enforces BETWEEN 1 AND 730). After the per-tenant cutoff, the audit-payload-reaper redacts actor and fields_json to null while the SHA-256 chain hashes are retained for the full 3-year window. Hash-chain anchor objects under the WORM bucket prefix chain-anchors/<stream>/: 3 years (locked by the same compliance-mode WORM policy). The retention split is the primary mitigation in DPIA §5.1 and the DPIA’s Art-6(1)(f) balancing has been re-run with the 730-day worst-case (DPIA v1.2, 2026-05-25).
Processing flowsFour in-cluster CronJobs touch this data:
(a) lts-quota-guard (every 6h) — lists LTS streams via the LTS API, computes per-stream byte-rate over a 6-hour window, alerts SMN if the extrapolated daily volume crosses the 5 GiB/day threshold. No content read; only metadata (stream id, byte size of API response).
(b) lts-archive-and-anchor (every 5min) — queries each of the four LTS streams for the last 5 minutes of entries, computes SHA256(prev_anchor_hash || entries_hash), writes the integrity anchor to s3://fremforge-prd-lts-worm-archive/chain-anchors/<stream>/<ts>.json. Entry contents themselves are NOT copied here; only the SHA256 digest. The 3-year archive of entry contents is performed by the OTC op_svc_lts service principal via separate LTS transfer tasks, on the same bucket but under per-stream prefixes (api-default/, forgejo-default/, jobs-default/, audit-default/).
(c) lts-anchor-verifier (hourly) — backward-walks the anchor chain from latest.json, recomputes hashes, alerts SMN oncall-critical on any mismatch. Verifier tolerates pre-existing orphan-genesis anchors (bootstrap-test artefacts) — these are reported as WARN_orphans, not chain breaks. See DPA Annex A.7 for the same disclosure on the customer-facing surface.
(d) audit-chain-anchor (every 2min) — per-tenant integrity flow committed in DPA Annex A.7. For each tenant with new audit_events rows since the last anchor, the job walks the rows in primary-key order, computes a running SHA256(prev_row_hash || canonical_row_bytes) chain hash, and writes a small anchor object {tenant_id, chain_hash, event_count, ts} to s3://fremforge-prd-lts-worm-archive/audit-chain-anchors/<tenant>/<ts>.json. Event payloads themselves are NOT copied — only the hash + count + identifier triple. This is the cadence commitment surfaced in DPA Annex A.7 and is distinct from the per-stream lts-archive-and-anchor flow above: the latter anchors LTS log streams platform-wide; this flow anchors the per-tenant audit_events row history so tenants can independently verify their own slice of the audit chain via the self-service export bundle (docs.frem.sh/data-export). Pseudonymous tenant identifiers + chain hashes only — no direct Customer Personal Data crosses the WORM-bucket boundary on this path.
TOMsKMS-encrypted-at-rest on both LTS hot and WORM archive (DEW CMK, annual rotation enabled); WORM compliance-mode lock on the OBS bucket prevents tamper-with-or-delete inside the 3-year retention window; least-privilege IAM scope on the read paths. The fremforge-lts-quota-guard IAM user is bound to five project-scoped roles: lts_full (read LTS streams + content query), smn_adm (publish to SMN oncall topics — note the documented Tenant Guest dependency), tenant_guest (read-only across services, the Tenant Guest dependency role required by smn_adm), obs_operate (PUT/GET on the WORM bucket’s chain-anchors/* prefix only — bucket policy restricts), kms_admin (datakey ops on the WORM CMK so KMS-encrypted PUTs succeed). The same credential is reused by lts-archive-and-anchor, lts-anchor-verifier, and bunny-edge-refresher (the last for SMN publish only). The credential is provisioned by the platform-foundation IAM stack and lands as the lts-quota-guard-creds Secret in the fremforge-prd namespace. No other automated read-paths exist.

2.6 Customer support + correspondence #

FieldValue
PurposeHandle support tickets, security disclosures, abuse reports.
Lawful basisArticle 6(1)(b) — performance of contract; Article 6(1)(f) — legitimate interest in security/abuse handling.
Categories of data subjectsAnyone who contacts fremverk via the operator-mailbox set: support@, security@, abuse@, compliance@, hello@, ops@, enterprise@, and info@fremverk.com (8 mailboxes — canonical enumeration per DPA §11.2 + Annex B Heinlein row).
Categories of personal dataEmail content (free-form, may include any personal data the sender included); attachments.
Recipients (internal)Operations + customer-success (shared mailbox access).
Recipients (sub-processors)Heinlein Hosting GmbH (mailbox.org — IMAP host for shared mailboxes; data residency Berlin DE).
International transfersNone.
RetentionSupport correspondence: 12 months. abuse@ correspondence: 5 years (legitimate-interest basis: DSA Art 16 + Art 24 transparency-reporting horizon; Danish Forældelsesloven 5y limitation). security@ correspondence: 24 months (per privacy-product.md §3.6(c) — vulnerability-report retention aligned with industry CVD norms).
TOMsTLS-in-transit; mailbox.org server-side encryption; access via SSO + 2FA for operators.

2.7 Marketing + waitlist #

FieldValue
PurposePrivate-beta signup capture; product-update communication.
Lawful basisArticle 6(1)(a) — consent (for marketing emails); Article 6(1)(f) — legitimate interest (transactional product-update emails to existing customers).
Categories of data subjectsPrivate-beta signup requesters; existing customers’ billing contacts.
Categories of personal dataEmail; timestamp.
Recipients (internal)Operations (ops@frem.sh shared mailbox triages each signup).
Recipients (sub-processors)T Cloud FunctionGraph (signup handler, EU/Germany); Lettermint B.V. (outbound transactional email, NL); Heinlein Hosting GmbH / mailbox.org (ops@frem.sh shared mailbox, DE).
International transfersNone.
RetentionEmail lands in the ops@frem.sh shared mailbox; retained per the email-records retention policy in §3 (until onboarding completes or withdrawal + 90 days). No fremverk-owned data store touches signups post-2026-05-29 — the OBS bucket previously used was destroyed at cutover. Marketing-email subscriber list: until unsubscribe + 30 days.
TOMsLettermint TLS-only; APIG per-IP throttle; per-IP rate limit on submit; Bunny Shield Advanced WAF.

3. Cross-cutting controls #

  • Encryption-at-rest: per-domain DEW KMS CMKs on RDS, OBS, EVS, SFS Turbo, CBR, LTS WORM. Provider-managed keys on DCS pending OTC platform support (disclosed in DPA Annex A.4).
  • Encryption-in-transit: TLS 1.2+ everywhere. Bunny edge → ELB origin TLS uses cert-manager-issued certificates from Actalis S.p.A. (Italy, Aruba Group, eIDAS QTSP) via ACME-DNS-01 against acme-api.actalis.com (activated 2026-05-04). The CA receives only the FQDN being certified (*-origin.frem.sh) — no Customer Personal Data — and is carved out of the sub-processor list (same posture as VIES). Issuing chain: Actalis DV Server ACME CA G1Actalis Authentication Root CA, both Italian-issued under EU Trusted List Reg. 910/2014. D-TRUST GmbH (Germany, Bundesdruckerei) retained as paid eIDAS-QTSP fallback if Actalis discontinues the free ACME service.
  • Access control: scoped IAM users per stack (no shared admin credentials in production); kube-RBAC role-bindings scoped per-resource by name; T Cloud bucket policies scoped per-prefix.
  • Audit log integrity: 3-year WORM bucket on OBS (compliance-mode lock); LTS hash-chain anchor (v2 — pending) for tamper detection.
  • Data subject rights: see DPA §6 for the operational paths (RTBF, access, export, restriction).

4. Change-log #

VersionDateChange
1.02026-05-03Initial publication. Replaces the placeholder reference in Privacy Notice §2 + plan.md §464.
1.12026-05-04Audit batch 3: §2.5 expanded with the lts-quota-guard / hash-chain-anchor / verifier processing flows and the actual five-role IAM scope on the lts_quota_guard credential. §3 updated to record that the origin-TLS workstream is paused pending CA selection (EU-jurisdictional ACME-supporting CAs in evaluation; D-TRUST and HARICA are the current candidates). The CA, when chosen, receives only FQDNs and is not a sub-processor under Article 28 — DPA Annex B explicitly carves it out. Also: lts_quota_guard credential moved from broad system roles (smn_adm + tenant_guest + kms_admin) to a custom least-privilege IAM policy (smn:topic:publish + smn:topic:list) plus a per-key KMS grant against the LTS WORM CMK only. Five role-bindings → two role-bindings + one custom policy + one KMS grant.
1.22026-05-04Origin-TLS workstream activated. §3 “Encryption-in-transit” updated: Actalis S.p.A. (Italy, Aruba Group, eIDAS QTSP) chosen as origin-TLS CA, ACME-DNS-01 validated end-to-end. Posture unchanged from v1.1: CA receives only FQDNs, carved out of sub-processor list. D-TRUST retained as paid fallback.