Šifrování a klíče
Jak jsou chráněné klíče jednotlivých workspaců, která data se šifrují a jak provést rotaci klíče instalace.
Obálka
Každý workspace vlastní 32bajtový datový šifrovací klíč AES-256-GCM (DEK). Řídicí databáze ho ukládá jen v zabalené podobě, zašifrovaný klíčem instalace pro šifrování klíčů (KEK), spolu s id poskytovatele, který ho zabalil. Rozbalení probíhá v procesu serveru při otevření workspace; rozbalený DEK se tam drží v paměti a nezapisuje se do databáze nájemce, do úložiště blobů ani do logu.
KEK se načítá z VITRINKA_KEK jako 64 hexadecimálních znaků. Pokud není nastavený, server použije VITRINKA_MASTER_KEY. Neplatná hodnota VITRINKA_KEK zabrání spuštění serveru. S VITRINKA_KEYS_PROVIDER=openbao KEK v prostředí vůbec není — zůstává uvnitř transit enginu a server mu posílá jen zabalené klíče — viz Úložiště klíčů.
Co je zapečetěné
| Data | Formát | Vázáno na |
|---|---|---|
| Citlivé sloupce nájemce — zachycené události nahraných sessions a hlášení chyb, zprávy ve vláknech anotací a zadání revizí, dokumenty stránek a jejich historie úprav, paměť projektu, zmrazené snímky sdílení, textové mapy snímků obrazovky a souborů, záznamy pracovního času, úlohy a zpětná vazba hodnocení review | enc2 — verze, id klíče, 12bajtový nonce, AES-256-GCM | id workspace + druh obsahu |
| Každý blob — nahrané soubory, snímky obrazovky, nahrávky, zdroje náhledů | enc2 s druhem blob | id workspace + blob |
| Archivy záloh a další operátorské artefakty | enc2f — čerstvý zabalený DEK, pak rámované 4 MiB bloky AES-256-GCM | index rámce + typ rámce |
Šifrování váže obsah na workspace a jeho typ. Přesunutí šifrované hodnoty do jiného workspace nebo jiného typu sloupce proto způsobí chybu ověření. U archivů se ověřuje také pořadí a typ bloků; poškozený nebo neúplný archiv se nepovažuje za úspěšně obnovený.
Co tabulka nevyjmenovává, se ukládá tak, jak je, a chrání to šifrování svazku a řízení přístupu: zbytek nástěnky (karty kromě stránek, jejich pozice a popisky), úkoly, fulltextové indexy — které drží text odvozený ze zapečetěného obsahu — a identifikátory a časové údaje. Datový svazek hostované služby používá šifrování LUKS2; vlastní instalace si šifrování svazku zajišťuje sama.
Objektové úložiště
S BLOB_BACKEND=s3 server po bucketu chce i šifrování na straně serveru: VITRINKA_S3_SSE je ve výchozím stavu aes256, kms:<key id> pro klíč spravovaný zákazníkem, nebo off. Backend, který hlavičku odmítne, degraduje na off s jedním řádkem v logu při startu; důvěrnost stojí tak jako tak na pečetění enc2 na straně klienta, takže bucket odmítající SSE drží pořád jen šifrovaný text.
Průchozí cache před S3 (BLOB_CACHE_MAX_GB) ukládá stejný šifrovaný text, jaký drží bucket. Ukradený adresář cache nevydá nic, co by nevydal ukradený bucket.
Přísný režim a pečeticí průchod
Starší instalace mohou obsahovat data zapsaná před zavedením šifrování. Server je ve výchozím režimu umí přečíst. VITRINKA_SEAL_STRICT=on čtení takových dat odmítne, proto tento režim zapněte až po jejich zašifrování a úspěšném ověření.
vitrinka seal-existing -data /data # sčítání nanečisto, nic nezapíše
vitrinka seal-existing -data /data -manifest /root/seal.json -execute # zapečetí každý řádek a objekt v prostém textu na místě
vitrinka seal-existing -data /data -verify # brána: nula nezapečetěných položek, každý zbytek pojmenovanýPříkaz před každou aktualizací ověří zašifrování a zpětné dešifrování hodnoty. Zápis provede jen tehdy, pokud se mezitím původní hodnota nezměnila. -verify skončí chybou, pokud zbývají nezašifrované položky nebo pokud neměl co ověřit.
VITRINKA_SEAL_STRICT=on přepínejte až poté, co nefiltrovaný běh -verify vypíše svůj řádek o průchodu. Přísný režim se zbylým prostým textem promění ty položky v chyby čtení, záměrně.
Rotace klíče instalace
Rotace KEK nikdy nepřešifrovává data: rozbalí DEK každého workspace pod starým KEK a znovu ho zabalí pod novým, jedna transakce na řádek. Bajty DEK se nemění, takže nic pod nimi zapečetěného se nedotkne, a běh přerušený v půlce dokončíte tím, že ho spustíte znovu.
vitrinka rewrap-deks -data /data -old-kek <hex> -new-kek <hex> # nanečisto
vitrinka rewrap-deks -data /data -old-kek <hex> -new-kek <hex> -executeKlíče můžou přijít z VITRINKA_REWRAP_OLD_KEK a VITRINKA_REWRAP_NEW_KEK místo přepínačů, aby se nedostaly do ps a historie shellu. Spouštějte se zastaveným serverem: živý proces pořád drží starý KEK a kontrola klíče při startu potvrdí nový, než se obsluha obnoví. Zavedení vyhrazeného VITRINKA_KEK na instalaci, která běžela na záložním master klíči, je samo o sobě rotací — starý KEK je hodnota master klíče.
Úložiště klíčů
VITRINKA_KEYS_PROVIDER rozhoduje, kdo drží KEK. Výchozí env je obálka popsaná výše: KEK sedí v prostředí serveru a nic ohledně klíčů neopouští hostitele. openbao přesune KEK do transit klíče v OpenBao. Server ten klíč nikdy nevidí: každý zabalený DEK pošle transit enginu k dešifrování a dostane zpět DEK, takže kopie disků datového hostitele vydá zabalené klíče a žádný klíč, který by je otevřel. Běžící server drží DEK workspace v paměti jen po dobu, kdy je workspace otevřený, a každé rozbalení je řádek v auditu. Transit klíč se zakládá jako neexportovatelný, takže ani výpis klíčového serveru KEK nevydá, a jeho rotace v OpenBao je průchod přebalením, přesně jako rotace VITRINKA_KEK.
K této topologii hostovaná služba přechází: transit engine žije na vyhrazeném klíčovém serveru, který hostí jen úložiště tajemství, dostupném přes privátní síť WireGuard, a každý z obou serverů se při startu odemyká materiálem drženým na tom druhém. Který stav produkce právě provozuje, uvádí bezpečnostní přehled. Vlastní instalace zůstává na env, pokud se její provozovatel nerozhodne jinak; pod env server kvůli klíčům nedělá žádné odchozí volání, takže odpojené instalace se tato sekce netýká.
| Proměnná | Výchozí | Poznámky |
|---|---|---|
VITRINKA_KEYS_PROVIDER | env | env nebo openbao. |
VITRINKA_OPENBAO_ADDR | — | URL transit enginu, jen v privátní síti. Povinné pro openbao. |
VITRINKA_OPENBAO_MOUNT | transit | Cesta transit mountu. |
VITRINKA_OPENBAO_KEY | vitrinka-kek | Název transit klíče; každý zabalený DEK nese id poskytovatele openbao:<key>. |
VITRINKA_OPENBAO_ROLE_ID VITRINKA_OPENBAO_SECRET_ID | — | Přihlášení AppRole. Na straně OpenBao roli navažte na privátní adresu datového hostitele. Tajné. |
VITRINKA_OPENBAO_TOKEN | — | Statický token místo AppRole — jen pro vývoj. Tajné. |
VITRINKA_OPENBAO_CA | systémové kořeny | Balík CA pro privátní certifikát na transit endpointu — cesta k PEM souboru, nebo přímo text PEM (hodnota začínající -----BEGIN; doslovné sekvence \n se rozbalí) tam, kde kontejner nepřipojuje žádný soubor hostitele. |
VITRINKA_DEK_REVERIFY | 15m | Jak často se DEK každého otevřeného workspace znovu ověřuje proti úložišti klíčů. |
Kontrola při startu
Při startu server přes poskytovatele rozbalí master klíč a pak spustí stejnou kontrolu klíčů jako env: každý uložený zabalený DEK se jednou dešifruje přes transit a každé dešifrování přistane jako řádek workspace.dek_unwrap v auditní stopě s důvodem verify. Jakékoli selhání — nedostupný engine, odmítnutá AppRole, DEK, který už nejde dešifrovat — spuštění odmítne s pojmenovanou nápravou, přesně jako neplatný VITRINKA_KEK. Server nikdy neobsluhuje nad úložištěm klíčů, které nedokázal prověřit.
Opakované ověřování
Otevření workspace rozbalí jeho DEK přes transit (důvod open) a drží ho v paměti. Každých VITRINKA_DEK_REVERIFY pool nájemců znovu dešifruje zabalený DEK každého otevřeného workspace (důvod reverify); neshoda nebo odmítnutí workspace z poolu vyřadí a výsledek zaznamená jako zamítnutý. Klíč odvolaný nebo odrotovaný v OpenBao tak přestane obsluhovat do jednoho intervalu, bez restartu. Smyčka nikdy nedrží zámek poolu přes síťové volání, takže pomalý klíčový server zdrží opakované ověření, ne požadavek. Rotace zapisuje důvod rewrap; kryptografické smazání nic nerozbaluje a zapisuje se na vlastní řádek workspace.dek.shred, který nově uvádí i poskytovatele. Klíčový server vede vlastní auditní zařízení jako nezávislý záznam týchž volání.
Přesun do úložiště klíčů a zpět
rewrap-deks je migrační dveře v obou směrech. -to openbao přebalí každý DEK z KEK v prostředí do transit klíče, jedna transakce na řádek, a k každému otiskne nové id poskytovatele; právě id poskytovatele na řádku dovoluje řádkům env a openbao uprostřed běhu koexistovat, takže přerušený průchod dokončíte tím, že ho spustíte znovu. Master klíč se stěhuje s ním: pod openbao je uložený zabalený v řídicí databázi a rozbalený jednou při startu, takže prostředí drží jen přihlašovací údaje AppRole a žádný dlouhodobý klíčový materiál.
vitrinka rewrap-deks -data /data -old-kek <hex> -to openbao # nanečisto: spočítá řádky per poskytovatel, nic nezapíše
vitrinka rewrap-deks -data /data -old-kek <hex> -to openbao -execute
vitrinka rewrap-deks -data /data -to env -new-kek <hex> -execute # návrat: znovu přebalí pod KEK z prostředíSpouštějte se zastaveným serverem, s nastavenými proměnnými OpenBao pro stranu openbao a s KEK z prostředí (přepínač nebo VITRINKA_REWRAP_OLD_KEK / VITRINKA_REWRAP_NEW_KEK) pro stranu env; kontrola klíčů při dalším startu prověří cíl, než se obsluha obnoví.
Opuštění úložiště klíčů je záměrný sestup: po -to env je KEK zpátky v prostředí a stopa rozbalování končí na hostiteli. Dělejte to jen kvůli vyřazení klíčového serveru, který nahrazujete, a napřed přebalte do jeho nástupce.
Když je úložiště klíčů nedostupné
Start selže uzavřeně. Běžící server degraduje po jednom workspace: už otevřené workspace obsluhují dál, dokud jim neselže další opakované ověření, neotevřený workspace otevřít nejde a jeho požadavky odpovídají 503 s pojmenovaným úložištěm klíčů. Neúspěšné opakované ověření se zapíše do logu a započítá do vitrinka_tenant_dek_reverify_failures_total, který vydává listener VITRINKA_METRICS_ADDR — výstrahu na něj nastavte ve svém monitoringu. Krátký výpadek sítě nic nestojí; dlouhý výpadek ukončí obsluhu do jednoho intervalu VITRINKA_DEK_REVERIFY, ne naráz. Obnovte klíčový server a další otevření uspěje bez restartu.
Export auditu
Auditní stopa opouští hostitele jako hashem řetězené dávky podepsané vlastním klíčem instalace; proměnné, cíle a postup s audit-verify najdete v Auditní stopě.