Recovery Dashboard Specifications
This document provides detailed specifications for the in-app recovery management dashboard used by organisation owners and platform administrators.
Overview
The Recovery Dashboard is an administrative interface for managing encryption key recovery requests. It provides:
- Real-time view of pending recovery requests
- Identity verification document review
- Dual authorization workflow management
- Time delay monitoring
- Complete audit trail viewing
- Recovery rate monitoring and alerting
- SIEM integration status
Recovery flows recover the survey's private key (the per-survey X25519 keypair whose public key encrypts every response at submission time). The private key is escrowed using the same Vault mechanisms and audit trails as before; recovering it grants the ability to decrypt all responses encrypted with the survey's public key. Participants never provide any key material, and the server itself cannot decrypt responses without a recovered private key.
User Roles and Access
| Role | Dashboard Access | Capabilities |
|---|---|---|
| Team Member | None | Cannot access dashboard |
| Team Admin | Limited | View own team's recoveries (read-only) |
| Organisation Owner | Full (org scope) | Manage all org recovery requests |
| Platform Admin | Full (all) | Manage all recovery requests + system settings |
Dashboard Views
1. Recovery Requests Overview
URL: /admin/recovery/
Purpose: Main dashboard showing all recovery requests
Layout
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Recovery Dashboard [Export] [Refresh]β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββββ β
β β 2 β β 1 β β 3 β β 5 β β 0.3% β β
β β Pending β β Awaiting β β In Time β β Completedβ β Recovery β β
β β Requests β β Approval β β Delay β β (30 days)β β Rate β β
β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Filters: [Status βΌ] [Date Range βΌ] [User βΌ] [Team βΌ] [Search...] β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β π‘ AWAITING SECONDARY APPROVAL β β
β β Dr. Sarah Jones (s.jones@nhs.uk) β β
β β Survey: Diabetes Audit 2025 β β
β β Submitted: 30 Nov 2025, 14:30 β’ Request ID: ABC-123-XYZ β β
β β β β
β β Verification: β
Photo ID β
Video Call β
Security Questions β β
β β Primary Approval: admin1@org.uk (30 Nov 16:00) β β
β β β β
β β [View Details] [Approve as Secondary] [Reject] β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β π IDENTITY VERIFICATION IN PROGRESS β β
β β Dr. Michael Brown (m.brown@hospital.uk) β β
β β Survey: Patient Feedback Q4 β β
β β Submitted: 30 Nov 2025, 10:15 β’ Request ID: DEF-456-UVW β β
β β β β
β β Verification: β
Photo ID β³ Video Call (scheduled 1 Dec 10:00) β β
β β β β
β β [View Details] [View Documents] [Schedule/Reschedule Call] β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β π’ IN TIME DELAY β β
β β Dr. Emma Wilson (e.wilson@clinic.uk) β β
β β Survey: Research Study 2025 β β
β β Approved: 29 Nov 2025, 16:30 β’ Request ID: GHI-789-RST β β
β β β β
β β β±οΈ Time Remaining: 18h 45m β β
β β Recovery Available: 1 Dec 2025, 16:30 β β
β β β β
β β [View Details] [View Audit Trail] β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Status Indicators
| Status | Color | Icon | Description |
|---|---|---|---|
| Pending Verification | Orange | π | Identity verification in progress |
| Awaiting Primary | Yellow | π‘ | Needs first admin approval |
| Awaiting Secondary | Yellow | π‘ | Needs second admin approval |
| In Time Delay | Green | π’ | Approved, waiting period active |
| Ready for Execution | Blue | π΅ | Time delay complete, ready to execute |
| Completed | Gray | β | Recovery finished |
| Rejected | Red | β | Request rejected |
| Cancelled | Red | β | Cancelled by user or admin |
2. Request Detail View
URL: /admin/recovery/<request_id>/
Purpose: Full details of a single recovery request
Layout
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Back to Dashboard β
β β
β Recovery Request: ABC-123-XYZ β
β Status: π‘ AWAITING SECONDARY APPROVAL β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β USER INFORMATION β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Name: Dr. Sarah Jones ββ
β β Email: s.jones@nhs.uk ββ
β β Account: Created 15 Jan 2024 ββ
β β Tier: Individual ββ
β β Organisation: NHS Trust West (if applicable) ββ
β β Last Login: 28 Nov 2025, 09:15 ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β SURVEY INFORMATION β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Survey: Diabetes Audit 2025 ββ
β β Created: 10 Oct 2025 ββ
β β Last Access: 25 Nov 2025, 14:00 ββ
β β Records: 156 patient records ββ
β β Encryption: Hybrid X25519 + AES-256-GCM (per-survey keypair) ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β IDENTITY VERIFICATION β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β
Photo ID ββ
β β Document: UK Driving Licence ββ
β β Submitted: 30 Nov 2025, 14:45 ββ
β β Verified by: admin1@org.uk (30 Nov 15:00) ββ
β β [View Document] ββ
β β ββ
β β β
Video Verification Call ββ
β β Completed: 30 Nov 2025, 15:30 ββ
β β Duration: 12 minutes ββ
β β Conducted by: admin1@org.uk ββ
β β Notes: "Face matches ID. Confirmed employment details." ββ
β β [View Recording] (if enabled) ββ
β β ββ
β β β
Security Questions ββ
β β Answered: 30 Nov 2025, 14:50 ββ
β β Result: 3/3 correct ββ
β β [View Questions & Answers] ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β AUTHORIZATION STATUS β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β
Primary Authorization ββ
β β Approved by: admin1@org.uk ββ
β β Date: 30 Nov 2025, 16:00 ββ
β β Reason: "Identity verified via video call. User confirmed ββ
β β they forgot both password and recovery phrase." ββ
β β ββ
β β β³ Secondary Authorization ββ
β β Status: Awaiting approval ββ
β β Eligible approvers: admin2@org.uk, admin3@org.uk ββ
β β ββ
β β [Approve as Secondary] [Reject with Reason] ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β TIME DELAY β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Status: Not yet started (awaiting secondary approval) ββ
β β Configured delay: 48 hours ββ
β β User tier: Individual ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β AUDIT TRAIL β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β 30 Nov 16:00 β admin1@org.uk β Primary approval granted ββ
β β 30 Nov 15:30 β admin1@org.uk β Video call completed ββ
β β 30 Nov 15:00 β admin1@org.uk β Photo ID verified ββ
β β 30 Nov 14:50 β SYSTEM β Security questions answered (3/3) ββ
β β 30 Nov 14:45 β s.jones@nhs.ukβ Photo ID uploaded ββ
β β 30 Nov 14:30 β s.jones@nhs.ukβ Recovery request submitted ββ
β β [Load More...] ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
3. Identity Verification Review
URL: /admin/recovery/<request_id>/verification/
Purpose: Review submitted identity documents
Document Viewer
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Identity Document Review β
β Request: ABC-123-XYZ β’ User: Dr. Sarah Jones β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββββ β
β β β β VERIFICATION CHECKLIST β β
β β [Photo ID Image] β β β β
β β β β β‘ Document is government-issued β β
β β UK Driving Licence β β β‘ Document is not expired β β
β β β β β‘ Photo matches account holder β β
β β [Zoom] [Rotate] β β β‘ Name matches account name β β
β β β β β‘ No signs of tampering β β
β βββββββββββββββββββββββββββββββ β β‘ Document is clearly legible β β
β β β β
β Submitted: 30 Nov 2025, 14:45 β Notes: β β
β File: driving_licence.jpg β βββββββββββββββββββββββββββββββ β β
β Size: 2.4 MB β β β β β
β β β β β β
β β βββββββββββββββββββββββββββββββ β β
β β β β
β β [Mark as Verified] [Request β β
β β New Document] [Flag Issue] β β
β βββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β οΈ SECURITY: Document images are encrypted at rest and automatically β
β deleted 30 days after request completion. β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
4. Video Verification Interface
URL: /admin/recovery/<request_id>/video-call/
Purpose: Conduct or review video verification calls
Video Call Interface
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Video Verification Call β
β Request: ABC-123-XYZ β’ User: Dr. Sarah Jones β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β [Video Call Window] β β
β β β β
β β User's video feed here β β
β β β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β [π€ Mute] [πΉ Camera] [π± Screen Share] [βΊοΈ Record] [π End Call] β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β VERIFICATION CHECKLIST β
β β
β β‘ User's face matches photo ID β
β β‘ User can display photo ID on camera β
β β‘ User confirms they initiated the recovery request β
β β‘ User can answer security questions verbally β
β β‘ User confirms current employment (if applicable) β
β β
β Notes: β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Type verification notes here... ββ
β β ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β [Complete Verification - PASS] [Complete Verification - FAIL] β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
5. Dual Authorization Workflow
URL: /admin/recovery/<request_id>/authorize/
Purpose: Approve or reject recovery requests
Authorization Form
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Authorization Required β
β Request: ABC-123-XYZ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β You are authorizing as: SECONDARY APPROVER β
β β
β Primary approver: admin1@org.uk (30 Nov 2025, 16:00) β
β Primary reason: "Identity verified via video call..." β
β β
β β οΈ IMPORTANT: You must independently verify this request. β
β Do not rely solely on the primary approver's assessment. β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β VERIFICATION SUMMARY β
β β
Photo ID: UK Driving Licence (verified by admin1@org.uk) β
β β
Video Call: 12 minutes (conducted by admin1@org.uk) β
β β
Security Questions: 3/3 correct β
β β
β [Review Photo ID] [View Video Recording] [View Q&A] β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β YOUR DECISION β
β β
β β APPROVE - I have independently verified this request β
β β REJECT - I have concerns about this request β
β β
β Reason (required): β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Enter your reason for approval or rejection... ββ
β β ββ
β β ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β β‘ I confirm I am not the primary approver β
β β‘ I confirm I have reviewed the verification evidence β
β β‘ I understand this action will be logged β
β β
β [Cancel] [Submit Decision] β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
6. Time Delay Monitor
URL: /admin/recovery/time-delays/
Purpose: Monitor all requests in time delay period
Time Delay Overview
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Time Delay Monitor [Refresh] β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Requests Currently in Time Delay: 3 β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Progress β User β Survey β Time Remaining ββ
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€β
β β ββββββββββ Dr. Emma Wilson β Research Study β 18h 45m ββ
β β ββββββββββ Dr. James Smith β Clinic Survey β 32h 15m ββ
β β ββββββββββ Dr. Lisa Chen β Patient Records β 44h 30m ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β READY FOR EXECUTION: 1 β
READY FOR EXECUTION: 1
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β π΅ Dr. Robert Taylor β Annual Audit β Time delay complete ββ
β β [View Details] [Show CLI Instructions] ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Execution is CLI-only. The web dashboard does not execute recovery. When a request is
Ready for Execution, the detail page shows theexecute_platform_recoverymanagement command (with the request code pre-filled) for the operator to run on a secure terminal with 3 of 4 custodian shares. See F6 indocs/compliance/security-review-august-2026.md.
7. Audit Trail Viewer
URL: /admin/recovery/audit/
Purpose: View complete audit trail across all requests
Audit Log View
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Audit Trail [Export CSV] β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Filters: [Date Range βΌ] [Event Type βΌ] [User βΌ] [Admin βΌ] [Search...] β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Timestamp β Event β Actor β Details β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β
β β 30 Nov 16:31:05 β recovery_completed β admin1 β ABC-123 β β
β β 30 Nov 16:31:00 β custodian_accessed β admin1 β ABC-123 β β
β β 30 Nov 16:30:00 β time_delay_complete β SYSTEM β ABC-123 β β
β β 28 Nov 16:30:00 β time_delay_started β SYSTEM β ABC-123 β β
β β 28 Nov 16:30:00 β secondary_approval β admin2 β ABC-123 β β
β β 28 Nov 16:00:00 β primary_approval β admin1 β ABC-123 β β
β β 28 Nov 15:30:00 β video_call_complete β admin1 β ABC-123 β β
β β 28 Nov 15:00:00 β photo_id_verified β admin1 β ABC-123 β β
β β 28 Nov 14:50:00 β questions_answered β user β ABC-123 β β
β β 28 Nov 14:45:00 β photo_id_uploaded β user β ABC-123 β β
β β 28 Nov 14:30:00 β request_submitted β user β ABC-123 β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Showing 1-11 of 156 entries [Previous] [1] [2] [Next]β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
8. Recovery Rate Monitor
URL: /admin/recovery/monitoring/
Purpose: Monitor recovery rates and detect anomalies
Monitoring Dashboard
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Recovery Rate Monitoring β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β CURRENT STATUS: β
NORMAL β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Metric β Current β Threshold β Status ββ
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€β
β β Requests (24h) β 2 β β οΈ 5 / π΄ 10 β β
Normal ββ
β β Recovery Rate (%) β 0.3% β β οΈ 1% / π΄ 2% β β
Normal ββ
β β Failed Verifications (24h)β 0 β β οΈ 3 / π΄ 5 β β
Normal ββ
β β User Objections (30d) β 0 β β οΈ 1 / π΄ 2 β β
Normal ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β TREND (30 DAYS) β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Requests ββ
β β 5β ββ
β β 4β β ββ
β β 3β β β ββ
β β 2β β β β β β ββ
β β 1β β β β β β β β β β β β β β β ββ
β β 0β β β β β β β β β β β β β β β β β β ββ
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β 1 5 10 15 20 25 30 ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β ALERTS β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β No active alerts ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β [Configure Thresholds] [View Alert History] [Test Alert] β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
9. SIEM Integration Status
URL: /admin/recovery/siem/
Purpose: Monitor SIEM connection and log forwarding
SIEM Status Panel
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SIEM Integration Status β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β CONNECTION STATUS: β
CONNECTED β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β SIEM Type: Elasticsearch (self-hosted) ββ
β β Endpoint: https://elasticsearch.internal:9200 ββ
β β Index Pattern: checktick-audit-* ββ
β β Last Sync: 2 minutes ago ββ
β β Events Today: 1,234 ββ
β β Queue Depth: 0 (real-time) ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β RECENT SYNC HISTORY β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Time β Events β Status β Latency ββ
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€β
β β 14:28:00 β 15 β β
β 45ms ββ
β β 14:27:00 β 8 β β
β 38ms ββ
β β 14:26:00 β 12 β β
β 52ms ββ
β β 14:25:00 β 6 β β
β 41ms ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β [Test Connection] [View Logs] [Configure] β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Data Models
RecoveryRequest Model
class RecoveryRequest(models.Model):
"""Model for tracking recovery requests."""
STATUS_CHOICES = [
('pending_verification', 'Pending Identity Verification'),
('verification_in_progress', 'Identity Verification In Progress'),
('awaiting_primary', 'Awaiting Primary Authorization'),
('awaiting_secondary', 'Awaiting Secondary Authorization'),
('in_time_delay', 'In Time Delay Period'),
('ready_for_execution', 'Ready for Execution'),
('completed', 'Completed'),
('rejected', 'Rejected'),
('cancelled', 'Cancelled'),
]
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
user = models.ForeignKey(User, on_delete=models.CASCADE)
survey = models.ForeignKey(Survey, on_delete=models.CASCADE)
status = models.CharField(max_length=50, choices=STATUS_CHOICES)
# Timestamps
submitted_at = models.DateTimeField(auto_now_add=True)
verification_completed_at = models.DateTimeField(null=True)
approved_at = models.DateTimeField(null=True)
time_delay_until = models.DateTimeField(null=True)
completed_at = models.DateTimeField(null=True)
# Authorization
primary_approver = models.ForeignKey(User, related_name='primary_approvals', null=True)
primary_approved_at = models.DateTimeField(null=True)
primary_reason = models.TextField(null=True)
secondary_approver = models.ForeignKey(User, related_name='secondary_approvals', null=True)
secondary_approved_at = models.DateTimeField(null=True)
secondary_reason = models.TextField(null=True)
# Rejection/cancellation
rejected_by = models.ForeignKey(User, related_name='rejections', null=True)
rejected_at = models.DateTimeField(null=True)
rejection_reason = models.TextField(null=True)
cancelled_by = models.ForeignKey(User, related_name='cancellations', null=True)
cancelled_at = models.DateTimeField(null=True)
cancellation_reason = models.TextField(null=True)
# Execution
executed_by = models.ForeignKey(User, related_name='executions', null=True)
custodian_component_used = models.BooleanField(default=False)
class IdentityVerification(models.Model):
"""Model for identity verification documents and results."""
VERIFICATION_TYPES = [
('photo_id', 'Photo ID'),
('video_call', 'Video Verification Call'),
('security_questions', 'Security Questions'),
('employment_verification', 'Employment Verification'),
]
STATUS_CHOICES = [
('pending', 'Pending'),
('submitted', 'Submitted'),
('verified', 'Verified'),
('rejected', 'Rejected'),
]
recovery_request = models.ForeignKey(RecoveryRequest, on_delete=models.CASCADE)
verification_type = models.CharField(max_length=50, choices=VERIFICATION_TYPES)
status = models.CharField(max_length=20, choices=STATUS_CHOICES)
# Document storage (encrypted)
document_path = models.CharField(max_length=500, null=True)
# Verification details
submitted_at = models.DateTimeField(null=True)
verified_by = models.ForeignKey(User, null=True)
verified_at = models.DateTimeField(null=True)
verification_notes = models.TextField(null=True)
# For security questions
questions_asked = models.JSONField(null=True)
correct_answers = models.IntegerField(null=True)
total_questions = models.IntegerField(null=True)
class RecoveryAuditEntry(models.Model):
"""Immutable audit trail for recovery actions."""
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
recovery_request = models.ForeignKey(RecoveryRequest, on_delete=models.CASCADE)
timestamp = models.DateTimeField(auto_now_add=True)
event_type = models.CharField(max_length=100)
severity = models.CharField(max_length=20)
actor_type = models.CharField(max_length=20) # user, admin, system
actor_id = models.IntegerField(null=True)
actor_email = models.EmailField(null=True)
actor_ip = models.GenericIPAddressField(null=True)
details = models.JSONField()
# Hash for tamper detection
entry_hash = models.CharField(max_length=64)
previous_hash = models.CharField(max_length=64, null=True)
class Meta:
ordering = ['-timestamp']
# Prevent deletion
managed = True
API Endpoints
Recovery Request Endpoints
# GET /api/admin/recovery/
# List all recovery requests (filtered by user's scope)
# GET /api/admin/recovery/<request_id>/
# Get single recovery request details
# POST /api/admin/recovery/<request_id>/verify/
# Submit verification result (photo_id, video_call, etc.)
# POST /api/admin/recovery/<request_id>/authorize/
# Submit authorization decision (approve/reject)
# Note: There is no web/HTTP execution endpoint. Recovery is executed
# exclusively via the `execute_platform_recovery` management command on a
# secure terminal, which reconstructs the custodian component from 3 of 4
# Shamir shares supplied on the command line. See F6 in
# docs/compliance/security-review-august-2026.md.
# DELETE /api/admin/recovery/<request_id>/
# Cancel recovery request
# GET /api/admin/recovery/<request_id>/audit/
# Get audit trail for request
# GET /api/admin/recovery/monitoring/
# Get recovery rate monitoring data
# GET /api/admin/recovery/siem/status/
# Get SIEM integration status
Security Considerations
Recovered Key Scope
A completed recovery grants the survey private key, which allows decryption of all responses encrypted with the survey's public key (including demographics, which are encrypted inside the same response payload). Legacy symmetric-KEK-encrypted responses remain readable via the same recovery flows. All recovery actions are recorded in the immutable audit trail.
Document Storage
- All identity documents encrypted at rest (AES-256-GCM)
- Documents stored in separate encrypted storage (not database)
- Automatic deletion 30 days after request completion
- Access logged to audit trail
Video Call Recording
- Recording optional (configurable per organisation)
- If enabled, recordings encrypted and stored separately
- Automatic deletion 90 days after request completion
- Access requires explicit admin action + logging
Session Security
- Admin sessions require MFA for recovery actions
- Session timeout: 15 minutes for recovery dashboard
- Re-authentication required for authorization decisions
- All actions logged with full context
Rate Limiting
- Max 3 recovery requests per user per 30 days
- Max 10 authorization actions per admin per hour
- Automatic lockout after 5 failed verification attempts
Implementation Checklist
- Recovery request model and migrations
- Identity verification model and migrations
- Audit entry model (append-only)
- Dashboard views (list, detail, verification, authorization)
- API endpoints
- Email notification integration
- SIEM forwarding
- Document storage service
- Video call integration (optional)
- Rate limiting middleware
- Admin permissions
- Unit tests
- Integration tests
- Security review
Related Documentation
- Key Management for Administrators - Admin procedures
- Audit Logging and Notifications - Logging requirements
- Vault Integration - Developer API
- Business Continuity - Disaster recovery