Zum Hauptinhalt springen

Unterschriften-Verwaltung — E-Signatur (A-2)

Bezug: A-2, R4, R9, OP-SIGN-1 · Status: Provider-Abstraktion + Niveau-Matrix (Slice 4, 0.4.0) + Unterschriften-Assistent inkl. Vor-Ort-/Demo-Abschluss gebaut (MED-D-198, Kunden-Cockpit S5, 0.97.0) + DocuSign-HTTP-Adapter gebaut (MED-D-220, 0.100.0, JWT-Grant/WebCrypto + Envelope + Connect-Webhook, dormant ohne Secret) + echte Vor-Ort-/In-Person-Signatur gebaut (MED-D-236, 0.106.0, embedded/captive recipient + recipient view); der DocuSign-Kern ist live verifiziert (Demo-E2E JWT/Consent/Envelope/ Status/Reminder, MED-D-238; Webhook-Write-back in Produktion, MED-D-239), die eingebettete Vor-Ort-Strecke selbst ist noch nicht durchgeklickt; PandaDoc + QES-CSP-Anbindung bleiben offen (OP-SIGN-1 Rest). Ohne konfiguriertes Secret läuft die Strecke weiter gegen die Fake-Provider-Attrappe (durchgehend als Demo gekennzeichnet, MED-KB-5).

Vor-Ort-Signatur: echt (In-Person) vs. Attrappe (MED-D-236)​

Die „Vor Ort unterschreiben"-Strecke des Assistenten hat zwei Ausprägungen, je nach aktivem Provider — der Server entscheidet, der Client reagiert (eingebettet-Flag):

AspektEcht (DocuSign In-Person)Attrappe (Fake-Provider)
MechanikEmbedded/captive recipient (clientUserId gesetzt → kein E-Mail-Versand) + recipient view-URL, im iFrame auf dem Berater-GerätabschliessenDemo schließt ohne Roundtrip ab
Rechtswirkungrechtsgültig (SES/AES je Dokumenttyp; QES → CSP-Rest)keine — nur Demo (MED-KB-5)
HostDer eingeloggte Berater (Name = anzeigename, E-Mail = Identität; MED-D-237) — DOCUSIGN_HOST_NAME/_EMAIL nur als Fallback—
AbschlussDocuSign-Redirect auf …/oeffentlich/signatur/vor-ort-fertig?event=signing_complete → iFrame-Handler → abgleich (Write-back)direkt → erhalten (Prüfung offen)
Mehrere Dokumentesequenziell (ein iFrame je Envelope, Index-Fortschritt)Sammel-Abschluss
RoutePOST /api/dokumente/:docId/signatur/vor-ort (vorbereiten) + POST /api/signaturen/:id/vor-ort-ansicht (URL)POST /api/signaturen/:id/vor-ort-abschluss

Sicherheitsriegel unverändert: der echte Adapter bietet kein abschliessenDemo → der Attrappen- Abschluss liefert gegen DocuSign weiter 409 (nie fälschbar). Der Assistent blendet den Demo-Schnell- Abschluss bei echten Vorgängen aus; das Demo-Banner erscheint nur, solange die Sitzung gegen den Fake läuft. Landung wie Sign-on-Paper: das Dokument geht auf erhalten (Prüfung offen), nicht automatisch auf geprüft/unterschrieben — der Berater bestätigt die Vor-Ort-Unterschrift (G-4).

Host = eingeloggter Berater (MED-D-237). Der DocuSign-In-Person-Host ist die Person, die die Session leitet — bei uns der eingeloggte Berater (Name aus benutzer.anzeigename, E-Mail aus der Cloudflare-Access- Identität), damit der DocuSign-Audit-Trail den echten Bezeuger zeigt (G-4), statt eines generischen Sammel-Kontos. Harte Voraussetzung: die Berater-E-Mail muss ein Nutzer desselben DocuSign-Accounts sein (sonst lehnt DocuSign den In-Person-Host ab) — jeder Vor-Ort-Berater ist also im DocuSign-Account anzulegen. Fehlt die Identität (Dev/nicht eingeloggt), greift die Default-Konfiguration DOCUSIGN_HOST_NAME/_EMAIL als Fallback. Anlage und Signaturansicht nutzen denselben Host — die In-Person-Session sollte also derselbe Berater durchführen, der sie angelegt hat (DocuSign matcht den Host).

Live-Verifikation offen (OP-SIGN-1): Adapter unit-getestet gegen gemocktes fetch, echter In-Person- Roundtrip noch nicht gefahren — Runbook s. Deploy.md §7d.

Entscheidung (A-2)​

Unterschriften werden über einen Standard-E-Signatur-Dienst (DocuSign oder PandaDoc) eingeholt — kein Eigenbau (G-1). Medidentas spricht den Provider über eine Provider-Abstraktion an, sodass der Anbieter austauschbar bleibt und ein zweiter Provider (Fallback / Niveau-spezifisch) ergänzt werden kann.

eIDAS-Niveau je Dokumenttyp (zentral!)​

Elektronische Signaturen haben unterschiedliche Rechtswirkung — das Niveau muss zum Dokumenttyp passen (RISK-2):

NiveaueIDASWannBeispiel-Dokumenttyp
SESeinfache Signaturgeringe FormanforderungEinwilligung, Kenntnisnahme
AESfortgeschritten (Identität gebunden, Änderung erkennbar)erhöhte BeweiskraftStandard-Verträge, Vollmachten
QESqualifiziert (= eigenhändige Unterschrift, Zertifikat)Schriftform gesetzlich gefordertformgebundene Verträge

CH: Schweiz nutzt ZertES (nicht eIDAS); QES-Äquivalent ist die qualifizierte ZertES-Signatur. Niveau ist je Dokumenttyp begründet festzulegen (Compliance-Tracker §3).

Einordnung Selfservice-Onboarding & Identverifikation (D-30)​

Drei Schichten, die nicht vermischt werden dürfen:

SchichtFrageLösung bei Medidentas
Einwilligung/KenntnisnahmeHat der Kunde zugestimmt?Default: Checkbox + versionierter Text + Audit (öffentl. Onboarding-Formular, Slice 9) — kein Provider nötig (Art. 7 DSGVO: formfrei, Nachweisbarkeit genügt; SES-Fall der Matrix). N5 (MED-D-307, flag-gated/dormant): optional als echte SES über DocuSign (EINWILLIGUNG_PROVIDER=docusign) — bleibt SES-Niveau, gibt aber einen provider-signierten Beleg. Verhältnis zu D-30: D-30 hielt für die Einwilligung „kein Provider nötig"; MED-D-291 Q3 (jünger, Nutzerentscheid) sanktioniert die DocuSign-Option → per Flag aufgelöst, Default bleibt die providerlose SES-Checkbox.
Unterschrift (Willenserklärung)Hat er rechtswirksam gezeichnet?DocuSign/PandaDoc am Onboarding-Abschluss: Maklervertrag → AES, Vollmacht → QES (konservativ; § 167 Abs. 2 BGB formfrei — real entscheidet die Akzeptanz der Produktgeber)
IdentitätsverifikationIst er, wer er behauptet?Nur bei GwG-Pflicht (OP-GWG-1/RISK-25): Standard = Berater-Ident im Termin (Ausweis, Mandant+Audit); VideoIdent/PostIdent nur Fallback für terminlose Strecken; QES-Flow enthält die Identifizierung implizit

Anbieterwahl-Heuristik (OP-SIGN-1-Rest): Bei den wichtigsten Produktgebern abfragen, welches Niveau sie für Maklervollmachten akzeptieren — reicht AES → PandaDoc-Tendenz (Kosten/Templates); ist QES nötig → DocuSign mit EU-QES-Partner (CSP). In beiden Fällen: EU-Datenresidenz + AVV/Transfermechanismus (US-Konzern).

Anbietervergleich (OP-SIGN-1 — Entscheidungsgrundlage)​

KriteriumDocuSignPandaDoc
Marktreife / Verbreitungsehr hochhoch
eIDAS QES/AESja (über Partner/CSP)ja (über Partner)
EU-Datenresidenzverfügbar (Region wählen)verfügbar
Datenexport USUS-Konzern → Transfer prüfen (DPF/SCC)US-Konzern → Transfer prüfen
Dokument-Erstellung/Templatesstarksehr stark (CPQ/Proposals)
API / Webhooksreif, breitreif
Kostenhöhertendenziell günstiger

Empfehlung (vorläufig): Auswahl an den Pflicht-Niveaus und der Datenresidenz festmachen — wenn QES für formgebundene Verträge nötig ist, den Anbieter mit passender CSP-Anbindung und EU-Residenz wählen. Entscheidung in OP-SIGN-1 mit Begründung dokumentieren.

Provider-Abstraktion​

Einheitliche Operationen der Abstraktion: envelopeErstellen(dokument, unterzeichner, niveau) · statusAbfragen(id) · webhookVerarbeiten(event) · signiertesDokumentAbrufen(id).

Sequenz: Unterschrift einholen​

Nicht-funktional​

  • Idempotenz/Reconciliation: Webhook verpasst? → periodischer Status-Abgleich (RISK-6).
  • Nachweis (G-4): Signatur-Zertifikat/Audit-Trail des Providers zusammen mit dem Dokument archivieren.

Umgesetzt (Slice 4, 0.4.0)​

  • Provider-Abstraktion SignaturProvider (server/src/signatur/provider.ts): anfordern + status; FakeSignatur (signatur/fake.ts) für Tests/Staging. Provider-Wahl via SIGNATUR_PROVIDER (MVP: fake).
  • Niveau-Matrix (domain/signatur-niveau.ts, begründet, admin-editierbar gedacht): Vollmacht → QES, Vertrag/Auftrag → AES, Mandat/Einwilligung → SES, Default → AES.
  • Signatur-Dienst (api/signatur-service.ts): anfordern (Niveau aus Matrix) · idempotenter Status-Abgleich (RISK-6) · bei Abschluss Rückablage der signierten Fassung in die Ablage (R9; produktiv R2, MED-D-61) + Dokument-Status unterschrieben (R3) + Onboarding-Item geprüft (R2) — "eine Wahrheit" (G-2).
  • D1-Tabelle signatur_vorgang (Migration v3), Felder R4-F01..08. REST: POST /api/dokumente/:id/signatur, GET /api/mandanten/:id/signaturen, POST /api/signaturen/:id/abgleich, POST /api/signaturen/:id/vor-ort-abschluss (MED-D-198). Ohne Provider/NextCloud → 503.

Unterschriften-Assistent + Vor-Ort-/Demo-Abschluss (MED-D-198, Kunden-Cockpit S5)​

Ein geführter 3-Schritt-Assistent (Client-Overlay md-unterschriften-assistent) bündelt das Einholen: (1) Prüfen (Dokument(e) wählen, eIDAS-Niveau je Typ automatisch aus der Matrix oder manuell überschreiben) · (2) Versenden (Sammel-Umschlag: mehrere Dokumente in einem Zug, Frist → Wiedervorlage) · (3) Verfolgen (Status je Vorgang). Daneben eine Vor-Ort-Strecke für die In-Person-Signatur auf dem Berater-Gerät.

Sicherheitsriegel (nie fälschbare echte Vorgänge): der Vor-Ort-/Demo-Abschluss ist nur am Fake-Provider möglich (SignaturProvider.abschliessenDemo? existiert ausschließlich in FakeSignatur; vorOrtAbschluss in signatur-service.ts liefert 409 gegen einen echten Provider). Der Abschluss läuft über denselben abgleich-Write-back-Pfad → signierte Fassung in die Ablage (R4→R3→R2), Dokument unterschrieben, Onboarding-Item geprüft, Audit (G-4). Der Attrappe-Hinweis ist in der UI durchgehend sichtbar (MED-KB-5).

Ein Weg: jede Unterschrift über den Assistenten (MED-D-335/336)​

Kernaussage (Berater/Backoffice): Egal ob hochgeladenes, erzeugtes (Dokumentgenerierung) oder frei geschriebenes Dokument — zur Unterschrift geht es immer über den Unterschriften-Assistenten (Prüfen → Versenden → Verfolgen). Den früheren Direktversand ohne Prüfschritt gibt es in der Oberfläche nicht mehr.

Technik (IT-Dev): Der Assistent ruft POST /api/dokumente/:docId/signatur (bzw. /signatur/vor-ort). Stammt das Dokument aus einer Generierung oder einem Individualdokument (erzeugtesDokumentRef = docId, Status abgelegt), führt api/signatur-quelle.ts die Quelle beim Start nach: status = zur_unterschrift, signaturRef, Audit-Event dokumentgenerierung.zur_unterschrift / individualdokument.zur_unterschrift (G-4). Beim Individualdokument ist dessen gewählte Stufe die Vorgabe, solange der Assistent auf "automatisch" steht. Keine neue Persistenz (G-2).

DocuSign-HTTP-Adapter (MED-D-220, 0.100.0)​

Erster echter Provider hinter der Abstraktion: DocuSignSignatur (server/src/signatur/docusign.ts) spricht die DocuSign-eSignature-REST-API direkt via fetch an — das Node-SDK docusign-esign läuft nicht auf Cloudflare Workers, daher hand-gerollt:

  • Auth = JWT Grant (Server-to-Server, kein User-Redirect): RS256-JWT wird in-Worker über WebCrypto (crypto.subtle) signiert (aud=Auth-Host, scope=signature impersonation), gegen /oauth/token getauscht; Access-Token wird gecacht. Der private Schlüssel ist PKCS#8 (PKCS#1 wird explizit abgelehnt — WebCrypto importKey('pkcs8', …)).
  • Envelope-Flow: anfordern lädt die Dokument-Bytes aus der Ablage (via signatur-service.ts, R4→R3), base64-kodiert sie in einen Envelope (status:'sent', Signer = Mandanten-E-Mail/-Name, signHere-Tab), hängt eine eventNotification (Connect-Webhook-URL) an. status(envelopeId) fragt den Envelope ab und lädt bei Abschluss die kombinierte signierte Fassung (/documents/combined) für den Write-back.
  • Connect-Webhook (Push statt Pull): Route POST /oeffentlich/signatur/docusign-webhook (api/app.ts, öffentlich = kein Access-Login, aber HMAC-verifiziert): X-DocuSign-Signature-1 wird gegen DOCUSIGN_WEBHOOK_HMAC per HMAC-SHA256 konstant-zeit geprüft (fail-closed ohne Key → 401), dann envelopeId→interner Vorgang→abgleich. Der bestehende Pull-Abgleich (RISK-6) bleibt als Fallback für verpasste Webhooks.
  • QES→AES-Herabstufung mit Hinweis (Dev-Account-Grenze): ein QES-Dokumenttyp wird über den DocuSign-Dev-Account als AES versendet mit sichtbarem Hinweis — echte QES braucht einen eIDAS-QES-CSP-Vertrag (offen, s. u.). Bewusst festgehalten, nicht still herabgestuft.
  • Sicherheitsriegel bleibt: DocuSign hat kein abschliessenDemo → vorOrtAbschluss liefert 409; echte Vorgänge sind nie fälschbar (MED-D-198).
  • Dormant ohne Secret: docuSignKonfigAusEnv gibt null zurück, wenn ein Pflicht-Secret fehlt → Provider fällt auf fake zurück / API 503; das Deployment bleibt ohne Secret deploy-sicher (G-5). Secrets: DOCUSIGN_INTEGRATION_KEY, DOCUSIGN_USER_ID, DOCUSIGN_ACCOUNT_ID, DOCUSIGN_PRIVATE_KEY (PKCS#8-PEM), DOCUSIGN_WEBHOOK_HMAC + SIGNATUR_PROVIDER=docusign (s. docs/architektur/Deploy.md).

Offene Punkte​

  • OP-SIGN-1 (Rest): PandaDoc-Adapter als Alternative/Fallback + QES-CSP-Anbindung (echte QES statt AES-mit-Hinweis) + Datenresidenz/AVV (US-Transfer, s. Compliance.md). Bei DocuSign bleiben die Prod-Umschaltung für echte Rechtswirkung und das Durchklicken der eingebetteten Vor-Ort-Strecke offen. Abstraktion, Niveau-Matrix und der DocuSign-Adapter stehen; der DocuSign-Kern ist live verifiziert. Schritt-für-Schritt-Runbook (Scharfschalten + Live-Smoke-Test 1–7): docs/architektur/Deploy.md §7d inkl. "7d-Live-Verifikation". Kern live verifiziert (MED-D-238 Demo-E2E, MED-D-239 Webhook-Write-back in Produktion); offen bleibt die Prod-Umschaltung für echte Rechtswirkung + AVV (OP-SIGN-1) und das Durchklicken der eingebetteten Vor-Ort-Strecke. Unit-Tests: signatur/docusign.test.ts gegen gemocktes fetch.