File size: 1,045 Bytes
8f1b6ce
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
"""Re-encrypt provider credentials with the first ENCRYPTION_KEYS key.

Keep old keys in ENCRYPTION_KEYS until all rows are rotated and every old replica is replaced.
"""

import asyncio
from sqlalchemy import select
from app.config import Settings
from app.db import create_database
from app.models import Provider
from app.security import Vault


async def main() -> None:
    config = Settings()
    factory = create_database(config.database_url)
    vault = Vault(config.encryption_keys)
    total = 0
    async with factory() as db:
        rows = await db.stream_scalars(
            select(Provider).execution_options(yield_per=200)
        )
        async for row in rows:
            row.encrypted_credentials = vault.cipher.rotate(
                row.encrypted_credentials.encode()
            ).decode()
            total += 1
        await db.commit()
    await factory.kw["bind"].dispose()
    print(f"Rotated {total} encrypted provider credentials. No plaintext was written.")


if __name__ == "__main__":
    asyncio.run(main())