Self-service and case workflows for municipalities
Case workflows that run themselves
AabenForms is an open source platform (Drupal 11 and Nuxt) for municipal self-service and case handling. Workflows are built as configuration in a visual editor and execute automatically. The result is a readable artifact rather than bespoke code inside a vendor codebase.
Eighteen municipal flows ready, six KOMBIT integrations, four ESDH systems. GPL, so the municipality owns it.
Modern for the citizen. Transparent for the administration.
Citizens meet a fast, accessible frontend. The administration can read, review and sign off on the workflow itself, because it is a diagram rather than code.




Integrations follow the KOMBIT standards directly
Not a generic form builder with Danish fields bolted on. The service contracts are part of the engine.
- MitID and NemLog-in
OIDC with PKCE and nonce. NSIS assurance is enforced inside the flow, not only at login.
- CPR and CVR lookups
Serviceplatformen SF1520 and SF1530. Family and custody lookups via SF6006.
- Digital Post (SF1601)
MeMo format, delivery receipts via Beskedfordeler, remote print as fallback.
- Case index and distribution
Journalising via SF1470 and distribution to line-of-business systems via Fordelingskomponenten (SF2900).
- ESDH
GetOrganized, SBSYS, WorkZone and Acadre. ESDH is a swappable connector, not a dependency.
- Administrative law is encoded
Partshøring and appeal guidance are mandatory steps. Deadline calculation skips public holidays.
A full case engine, not a form collector
- The whole journey
From application through journalising and decision to appeal and handover to the line-of-business system.
- Lawful state changes enforced in the database
No code path, not the admin form nor JSON:API, can move a case into an unlawful state.
- Every transition is a revision
Who, when and why. A complete audit trail.
- Deadlines computed correctly
Working days in Danish local time, public holidays skipped, per case area.
- CPR is always encrypted
AES-256. The system refuses to store plaintext.
- Multi-tenant
One installation can serve several municipalities or departments with isolated data.
School transfer: the chain nobody assembled
Building permits and address changes are linear. Workflows about children are not. They involve several parties with distinct rights, and sending to the wrong one is a data breach.
A school transfer requires somebody with parental custody to apply. Under shared custody, school choice is a significant decision under the Danish Parental Responsibility Act, so both holders must agree. Where disagreement is known, the municipality cannot proceed at all. The decision must reach both custody holders in Digital Post separately. That has been law since 21 March 2022.
Every building block exists in Danish infrastructure. CPR holds custody. SF1601 sends Digital Post. borger.dk has run co-signature by link for years. Nobody has assembled the chain. In OS2Forms the request for parallel parties in a workflow has been open since January 2026, and there is not a single issue about custody lookup anywhere in the public OS2 trackers.

- Sole custody
The registry confirms a single holder. The case goes straight to the school leader at the requested school.
- Shared custody, agreed
The other holder receives a secure link in Digital Post, signs in with MitID and approves. A 14 day window.
- Known disagreement
The flow refuses to decide. The case moves to manual handling with partshøring, per the Ombudsman ruling FOB 2025-9.
Tested against the engine, not against a mock
The tests create a real MitID session, post to the live endpoint and read the step trace the engine returns. The workflow layer is not mocked.
Applicant without custody
- completedaabenforms_mitid_validate Citizen identity verified via NemID/MitID national eID
- failedaabenforms_custody_verify Adult is not a registered custody holder of the child
- failedaabenforms_workflow_deny Ansøgningen blev ikke behandlet, fordi CPR-registret ikke bekræfter, at du har forældremyndighed
Pre-pilot POC. Here is exactly what that means.
- RunningLive on aabenforms.dk and api.aabenforms.dk.
- Test railsAgainst test and mock integrations. No Serviceplatformen certificate has been issued, so CPR lookups run against test data and Digital Post writes to a local log instead of SF1601.
- HonestA step that ran against test data writes "demo" in the trace. An audit trail that lies is worse than no audit trail.
- RealThe engine, the case model, the branching, deadline calculation, encryption and audit. What is missing is certificates and a pilot municipality.
The case engine, step by step
Two real ECA workflows recorded as they run: MitID, registry lookups, a decision, Digital Post and a GDPR trace. Watch them below, or open the interactive demo to step through every node.