Aug 21 - Fernet key rotation
This commit is contained in:
+22
-1
@@ -95,6 +95,10 @@ class Tenant(ControlBase):
|
||||
db_name = Column(String(64), unique=True, nullable=False)
|
||||
db_user = Column(String(64), nullable=False)
|
||||
db_password_enc = Column(Text, nullable=True) # Fernet token
|
||||
# MT-23: which Fernet key version db_password_enc was written under, so
|
||||
# rotation progress is queryable rather than assumed:
|
||||
# SELECT COUNT(*) FROM tenants WHERE key_version < <current>;
|
||||
key_version = Column(Integer, nullable=False, default=1, server_default='1')
|
||||
alembic_head = Column(String(64), nullable=True) # last tenant-schema rev applied
|
||||
|
||||
created_at = Column(DateTime, nullable=False, default=now_eastern)
|
||||
@@ -124,8 +128,25 @@ class Tenant(ControlBase):
|
||||
|
||||
# ── Encrypted credential handling ──────────────────────────────────────
|
||||
def set_db_password(self, plaintext):
|
||||
"""Store an encrypted tenant DB password."""
|
||||
"""Store an encrypted tenant DB password, stamped with the key version."""
|
||||
self.db_password_enc = crypto.encrypt(plaintext)
|
||||
self.key_version = crypto.current_key_version()
|
||||
|
||||
def rotate_db_password_key(self):
|
||||
"""MT-23: re-encrypt the stored credential under the primary key.
|
||||
|
||||
Returns True when the row was rewritten, False when there was nothing
|
||||
stored. The plaintext is never materialized here — MultiFernet.rotate
|
||||
decrypts and re-encrypts internally.
|
||||
"""
|
||||
if not self.db_password_enc:
|
||||
# Nothing to re-encrypt, but stamp the version so the row stops
|
||||
# showing up as outstanding in rotation progress queries.
|
||||
self.key_version = crypto.current_key_version()
|
||||
return False
|
||||
self.db_password_enc = crypto.rotate(self.db_password_enc)
|
||||
self.key_version = crypto.current_key_version()
|
||||
return True
|
||||
|
||||
@property
|
||||
def db_password(self):
|
||||
|
||||
Reference in New Issue
Block a user