Duplicity Detection
Duplicity occurs when the same AID signs conflicting events, creating a fork in the Key Event Log. This is the primary attack KERI is designed to detect and handle. This article explains how DTF’s architecture detects, reports, and resolves duplicity.
What is Duplicity?
In normal operation, a KEL is a linear chain of events. Duplicity creates two branches:
Legitimate: Inception → Event 1 → Event 2 → Rotation A → Event 3
Attacker: Inception → Event 1 → Event 2 → Rotation B → Event 3'
↑
Fork pointThis happens when an attacker compromises private keys and rotates them to their own key pair while the legitimate controller also rotates. Two valid but conflicting branches now exist.
Three-Layer Detection
DTF uses a defense-in-depth approach with three watcher layers, each monitoring at different trust levels.
Layer 1: Local Watcher
Runs inside the Keria microservice. Validates your own KEL for internal consistency:
- Sequence continuity — Events must be sequential (0, 1, 2…)
- Signature validity — All signatures must cryptographically verify
- Digest chain — Each event must chain to the previous event’s digest
- Key state validity — Signing keys must match the current key state
Scope: Single controller’s local data.
Layer 2: Witness-Level Watcher
Co-located with witnesses. Monitors witness KELs and validates receipts:
- Cross-witness consistency — Same AID must have identical KELs at all witnesses
- Receipt threshold — Enough witness signatures must exist
- Receipt validity — Witness signatures must verify
- Propagation timing — Events received in correct order
Detection process:
- Query all witnesses for the same AID’s KEL
- Compare responses
- If all match: no duplicity
- If any differ: duplicity detected
Layer 3: External Watcher
Independent service providing network-wide monitoring:
- Network-wide fork detection — Any AID with conflicting KELs anywhere
- Historical consistency — KEL history matches across all sources
- Multi-source verification — Cross-verify with multiple independent sources
Reporting
When duplicity is detected, the system preserves cryptographic evidence and alerts through multiple channels.
Evidence Preservation
- Both branches of the fork (complete event data with signatures)
- Sequence numbers where the fork occurred
- Timestamps: when each branch was first observed, when events were created
- Which witnesses reported which version
- All stored in an immutable, publicly verifiable log
Alert Channels
- WebSocket notifications — Real-time alerts to subscribed controllers
- Webhook callbacks — HTTP POST to registered endpoints with structured payloads
- REST API — Query duplicity events and AID status on demand
Resolution
When duplicity is detected, the system takes immediate protective action:
- Alert the controller — Notify with evidence of conflicting events
- Mark identifier as compromised — Flag the AID as potentially untrustworthy
- Block operations — Prevent new events, credential issuances, and key rotations
- Publish evidence — Make duplicity publicly verifiable
Recovery Path
If the legitimate controller can prove ownership (via pre-committed recovery keys):
- Controller publishes a recovery event with proof
- Witnesses validate the recovery proof
- If witness threshold is met (e.g., 2-of-3 accept), recovery succeeds
- Forked branch is invalidated, legitimate branch is restored
Permanent Invalidation
If recovery is impossible (no recovery keys, controller unresponsive):
- AID is permanently marked as compromised
- All credentials issued by this AID become untrustworthy
- Verifiers reject any credentials from this AID
- Status is propagated network-wide
For government credentials (e.g., SEDI), this process includes due process considerations: minimum response windows, legal review requirements, and appeal processes.
Security Properties
- Byzantine fault tolerance — Threshold signatures prevent single-witness compromise from causing duplicity
- Non-repudiation — Duplicity is cryptographically provable and publicly verifiable
- Defense in depth — Multiple independent watcher types catch different attack vectors
- Availability — Distributed witnesses ensure KELs remain accessible during partial failures
Current Status
DTF currently operates in self-witnessed mode — the Keria microservice manages KELs locally without external witnesses or watchers.
Operational today:
- KEL/TEL generation
- ACDC credential issuance
- Self-witnessed mode (basic functionality)
Planned:
- External witness network (geographically distributed)
- Watcher infrastructure (local, witness-level, external)
- Cross-witness consistency checking
- Network-wide monitoring via super watchers