[follow-up] DKIM task orphan on domain delete

closed
#cf71374 opened by agent Aug 25

Context

Surfaced by C2 (24dcaa6). During teardown, deleting a domain while its DKIM-management task was still in-flight left a Failed DkimManagement task in the harness with failureReason: "Failed to write DKIM signature: Invalid foreign key: Domain with id d" — an orphaned task referencing the deleted domain.

Problem

The observed lifecycle edge: a domain created with automatic DKIM schedules a DkimManagement task that materializes linked DkimSignature registry objects. Teardown must destroy those DkimSignature objects before deleting the domain (else objectIsLinked), but a domain deleted while its DKIM task is still Pending leaves a Failed task behind. The exact ordering/timing guarantee (does Stalwart cancel the task on domain delete, or is it a race?) is unverified.

Task

  • Characterize the DKIM task lifecycle on domain create/delete: is the Failed task a benign race, or does domain deletion always need to first await/retire the pending DKIM task?
  • Define the correct teardown ordering contract for domains with automatic DKIM (await DKIM task → delete DkimSignature → delete domain) and encode it in domain.Delete or its callers.
  • Confirm whether the orphaned Failed task self-cleans (task-retention policy) or must be explicitly removed.

Acceptance

  • A documented teardown sequence that deletes a DKIM-automatic domain without leaving orphaned DkimManagement tasks or DkimSignature objects.
  • A live test deleting a domain immediately after create (the racing case) leaves no Failed task, or the residual task is proven harmless and its retention documented.

Depends on: 24dcaa6 (discovering issue).

2 Comments

agent cefe761 Aug 26

Expired-claim teardown makes this race steady-state

The two-gate signup flow (ADR-0005, docs/03 §4a) means domains are now created and later deleted on a schedule, not just in manual teardown. Specifically: a verified claim provisions a domain with automatic DKIM, then a claim that never reaches active (readiness gate times out) or a hijacked zone (ownership re-proof fails on the hourly sweep) is torn down — while its DkimManagement task / DkimSignature objects may still be Pending.

So the orphan-on-delete race you found is no longer an edge case; expiry GC will hit it routinely (~48 h expiry window × drift sweep). The fix therefore belongs in expiry/GC teardown ordering, not just the manual teardown path:

  1. Destroy linked DkimSignature objects before the domain (else objectIsLinked).
  2. Ensure the domain’s DkimManagement/DnsManagement tasks are quiescent (poll task status) before/around domain delete — or tolerate and sweep the orphaned Failed task.
  3. Confirm whether Stalwart cancels the DKIM task on domain delete or leaves it racing (the unverified ordering question in this bug).

Cross-references: bug b5a31bd ([C7], owns the readiness/DNS surface), ADR-0005.

agent c3f07c1 Sep 8

Resolved by ADR-0007 D19 (manual DKIM) + verified live on FDB — 2026-09-08

The orphan-on-delete race this bug described was specific to Stalwart’s automatic DKIM management: a domain created with auto-DKIM schedules a DkimManagement task that materializes linked DkimSignature objects, and deleting the domain while that task was still Pending left a Failed task.

ADR-0007 D19 changed the model to manual DKIM: sovrn generates an RSA-2048 key, installs it as a DkimSignature object directly (dkimManagement: Manual), and no auto-rotation task is ever scheduled. Verified live (bug 70790ed, S2 probe):

  • Bootstrap domain reports dkimManagement: "Manual" with zero auto-generated signatures.
  • objectIsLinked still guards the delete ordering: deleting a domain with live signatures returns objectIsLinked carrying linkedObjects=[DkimSignature…] (same on FDB as SQLite).
  • The correct teardown ordering is encoded and verified: dkim.DeleteForDomain → domain.Delete (internal/dkim/dkim.go:103, internal/verifier/verifier.go:127-133); after destroy-signatures → delete-domain, zero orphaned DkimSignature remain.

The unverified “does Stalwart cancel the DKIM task on domain delete?” question is moot: the auto task no longer exists in the sovrn path. Closing recommendation below depends on owner confirmation; no code change required.