Aug 26 - Enhance security 4
CI / Python lint (flake8) (push) Has been cancelled
CI / Python syntax check (push) Has been cancelled
CI / Alembic migration chain (push) Has been cancelled
CI / JavaScript syntax check (push) Has been cancelled
CI / Pytest (push) Has been cancelled
CI / Build extension zip (push) Has been cancelled

This commit is contained in:
2026-08-26 14:19:25 -04:00
parent cc216b0d98
commit b84a6d9245
11 changed files with 546 additions and 33 deletions
+14
View File
@@ -16,6 +16,10 @@ class EmergencyAccess(db.Model):
pending → grantor calls /deny → ready (reset, grantee can request again)
pending (wait_days elapsed) → grantable (grantee fetches vault)
Retrieval does not change `status`: the grant stays 'pending' so the grantor
keeps seeing it as active and can revoke it. What retrieval does change is
vault_retrieved_at / vault_retrieval_count, which the grantor's UI surfaces.
Zero-knowledge: enc_vault is a JSON array of vault items re-encrypted by the grantor
using the ECDH shared secret (grantor private key + grantee public key).
"""
@@ -40,6 +44,12 @@ class EmergencyAccess(db.Model):
# JSON string: [{ id, name, item_type, enc_data, iv }, ...]
enc_vault = db.Column(db.Text, nullable=True)
created_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc).replace(tzinfo=None), nullable=False)
# Retrieval tracking — makes grantee access to the snapshot visible to the
# grantor. Retrieval is not blocked after the first time (the grantor may be
# unable to re-provision, which is the entire premise of emergency access);
# the wait period is the gate, and these make use of it auditable.
vault_retrieved_at = db.Column(db.DateTime, nullable=True)
vault_retrieval_count = db.Column(db.Integer, default=0, nullable=False, server_default='0')
@property
def wait_elapsed(self):
@@ -62,6 +72,10 @@ class EmergencyAccess(db.Model):
self.request_initiated_at.isoformat() if self.request_initiated_at else None
),
'created_at': self.created_at.isoformat() if self.created_at else None,
'vault_retrieved_at': (
self.vault_retrieved_at.isoformat() if self.vault_retrieved_at else None
),
'vault_retrieval_count': self.vault_retrieval_count or 0,
# True when enc_vault contains items in the old format (has a plaintext
# 'name' field instead of enc_name/iv_name). Grantor should re-provision.
'enc_vault_is_legacy': self._enc_vault_is_legacy(),