---
title: "Ротация на главен и подписващ ключ и авариен достъп"
description: "Ротирайте главния ключ, който защитава съхранените идентификационни данни, и използвайте авариен достъп."
image: "https://docs.quirelms.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.quirelms.com/bg/llms.txt
> Use this file to discover all available pages before exploring further.

# Ротация на главен и подписващ ключ и авариен достъп

<span id="master-key-and-signing-key-rotation-and-break-glass-access"></span>

Контролите от раздел 14 на 21-compliance.md, които одиторът изисква по име.
Тази страница описва процедурата; записите, които тя създава, са доказателствата.

## Ключове <!--quire:the-keys-->

Всеки съхранен идентификационен ключ се запечатва с нов ключ за криптиране на данни (DEK). DEK се обвива с главния ключ (KEK), а препратката към главния ключ се съхранява до него (`key_ref` или препратката в пакетирана стойност). Ротацията на главния ключ обвива DEK-овете наново. Тя никога не декриптира или криптира отново идентификационни данни.

| Настройка | Значение |
| --- | --- |
| `QUIRE_MASTER_KEY` | Текущият главен ключ: 32 байта, base64. Всеки нов секрет се обвива с него |
| `QUIRE_MASTER_KEY_VERSION` | Етикетът на версията му. По подразбиране `v1`. Увеличавайте го при всяка смяна на ключа |
| `QUIRE_MASTER_KEY_RETIRED` | По-стари ключове, с които може да са запечатани съхранените тайни, във формат `v1=<base64>,v0=<base64>`. Използват се за четене, никога за запис |

Уеб слоят, worker и командата `bun run kek:rotate` четат едни и същи три
настройки. Стойностите им трябва да съвпадат, иначе някой от процесите няма да може да отвори данни, запечатани от друг.

Без `QUIRE_MASTER_KEY` всяка подсистема запазва ключа, който извежда от
`QUIRE_SECRET_KEY`. Това работи, страницата „Системно състояние“ го показва като влошено състояние и данните остават достъпни след задаване на главен ключ; така първата ротация премества всичко от стария ключ. Всеки, който може да чете средата на процеса, може да декриптира всички съхранени идентификационни данни, затова производствената инсталация трябва да има главен ключ, съхраняван в тайно хранилище, отделно от резервното копие на базата данни.

## Ротация <!--quire:rotating-->

Възрастта на ключа се показва в конзолата Platform, в Security, Master key, както и чрез метриката
`quire.secrets.master_key.age` (дни). Ежедневната задача `platform.key_age` (03:41 UTC)
добавя напомняне във веригата за одит на платформата, когато ключът достигне 365
дни, а после на всеки 30 дни, докато не бъде сменен. Изпълнете ротация при напомняне и всеки път, когато е възможно изтичане на ключ.

1. Създайте новия ключ: `openssl rand -base64 32`.
2. Задайте `QUIRE_MASTER_KEY` на новия ключ, а `QUIRE_MASTER_KEY_VERSION` — на следващия етикет
   (`v2`). Преместете стария ключ в `QUIRE_MASTER_KEY_RETIRED` като `v1=<old base64>`.
   Съхранете копие и от двата ключа извън този хост.
3. Разгърнете уеб слоя и worker с новите настройки. Новите тайни вече се
   обвиват като `env:QUIRE_MASTER_KEY:v2`; старите остават достъпни чрез оттегления ключ.
4. Заявете ротация с причина, която ще остане в одитния журнал:
   - в конзолата: Security, Master key, Rotate the master key; или
   - в обвивка със същата среда: `bun run kek:rotate request --reason "Annual rotation, ticket SEC-114"`.
5. Worker преобвива част от данните всяка минута (задачата на scheduler `platform.key_rotation`) и продължава след рестартиране. За да завършите наведнъж: `bun run kek:rotate run`. Следете чрез `bun run kek:rotate status`.
6. Когато записът покаже завършена ротация с **нула неразрешени и нула неуспешни** стойности, премахнете оттегления ключ от `QUIRE_MASTER_KEY_RETIRED` и разгърнете отново.
   Дотогава го запазете: стойност, която не е преместена, все още е обвита със стария ключ.

### Какво обработва задачата <!--quire:what-the-job-walks-->

Всеки склад, който съдържа обвит DEK: елементите в `SEALED_STORES`
(`apps/worker/src/key-rotation.ts`). Складовете на управляващата база се обработват там; складовете на организации — по една организация наведнъж съгласно
row-level security, в базата, където се намира организацията. Затова организация, фиксирана към отделна база, се ротира именно в нея. Тест не минава, ако към схемата се добави обвита колона за ключ, която не е в списъка; друг тест проверява, че в списъка са всички запечатани колони, посочени при прегледа на идентификационните данни.

### Записът <!--quire:the-record-->

- `ops.key_rotation`: ред за всяка ротация с причина, заявител, състояние и общи стойности (преобвити, вече актуални, неразрешени, неуспешни).
- `ops.key_rotation_progress`: ред за всяко обработено хранилище и обхват с препратките към ключове, които не са могли да бъдат прочетени, и броя стойности за всяка. При продължаване на ротация тези записи се прескачат.
- Верига за одит на платформата: `platform/key_rotation_request` (с причината), по един `platform/key_rotation_store` за всеки склад с броевете и `platform/key_rotation_complete` или `platform/key_rotation_fail`; `platform/key_age_reminder` за напомнянето.
- Метрики: `quire.secrets.master_key.age` и `quire.secrets.rewrap.outstanding` (стойности, които последната ротация не е успяла да премести).

### Неразрешени стойности <!--quire:when-values-are-unresolved-->

Неразрешената стойност е обвита с препратка към ключ, която тази инсталация няма, или не е в обещания от колоната формат. Записът за напредъка посочва препратката (например `env:QUIRE_MASTER_KEY:v0 (unreadable)`). Върнете този ключ в `QUIRE_MASTER_KEY_RETIRED` и изпълнете нова ротация или, ако ключът е загубен завинаги, помолете администратора на организацията да въведе отново идентификационните данни: те ще бъдат запечатани с текущия ключ. Неуспешните ротации показват грешката в записа; отстранете причината и подайте нова заявка.

## Ключове за подписване <!--quire:signing-keys-->

Отделно от главния ключ: всяка организация подписва собствените си OpenID Connect токени
и LTI съобщения с RSA ключ, публикуван на `/.well-known/jwks.json`.
Тук не се изисква намеса на оператор. Ежечасната задача `platform.signing_keys`
публикува следващ ключ седем дни преди да изтекат деветдесетте дни на текущия ключ; седмица по-късно следващият започва да подписва, а старият преминава в състояние на оттегляне; след още деветдесет дни старият ключ се изтрива от набора. Всяка стъпка се записва като `platform/signing_key_advance` във веригата за одит на платформата.

За да смените ключа на организацията по-рано, например след изтичане:

- в конзолата: Security, Master key, Publish a new signing key (изисква
  `platform/keys_manage`); или
- в обвивка със средата на worker: `bun run kek:rotate signing-keys rotate
  --tenant <slug or id> --reason "Key exposed, INC-3310"`. `bun run kek:rotate
  signing-keys status` показва етапа на ключовете на всяка организация.

Новият ключ се публикува веднага и започва да подписва след седем дни, когато текущият ключ бъде оттеглен. Едноседмичният период е умишлен: доверените страни кешират набора от ключове и по-кратко припокриване ще откаже всички инструменти едновременно. Оттегленият ключ остава в набора още деветдесет дни, за да продължат да се проверяват токените, които вече е подписал. Ако изтичането означава, че доверието в него трябва да бъде прекратено по-рано, изтриването на реда е промяна чрез собствен достъп на оператора до базата и със собствен запис за промяна (аварийният достъп е само за четене); тогава подписаните с него токени вече няма да минават проверка. Принудителната ротация се записва като `platform/signing_key_rotate` във веригата за одит, заедно с причината. Worker се нуждае от същите настройки `QUIRE_MASTER_KEY` като уеб слоя, за да обвие новия ключ; командата `bun run kek:rotate` за главния ключ преобвива ключовете за подписване заедно с останалите (`oauth_signing_key` е в `SEALED_STORES`).

## Аварийен производствен достъп <!--quire:break-glass-production-access-->

Никой няма постоянен достъп до производствената среда. Когато нещо не може да чака, собственик издава аварийно разрешение: Platform console, Security, Break-glass access.

- Разрешението има обхват (една организация или регистър на платформата), причина от поне 20 знака, в която е посочен инцидентът или заявката, и срок от 5 до 240 минути. То изтича автоматично: проверява се спрямо часовника при всяка команда.
- Може да се издаде на собственика, който го заявява, или на друг собственик (процедура с двама души). Само получателят може да го използва. Издаването изисква `platform/break_glass_issue`, използването — `platform/break_glass_use`; по подразбиране и двете права са само за собственици.
- Командите минават през шлюза, а не чрез вход в базата: само за четене, една наведнъж, ограничени до организацията или регистъра за управление, с петсекундно ограничение и максимум 500 реда. Двоичните стойности се показват с размера си.
- Веригата за одит на платформата записва издаването (с причината), отмяната, всяка команда преди изпълнение (`platform/break_glass_statement`, отказаните с резултат `denied`) и всеки резултат (`platform/break_glass_result`). `ops.break_glass_statement` пази идентификаторите на одитните записи, така че записът за издаване може да се свърже с тях.
- Запис не се предлага. Промяна, която не може да чака издание, се прави чрез собствения достъп на оператора до базата и със собствен запис за промяна, извън този продукт; записът трябва да посочва използваната тук препратка към инцидента.

Защо не се издават данни за вход в базата: входът в Postgres надживява сесията, която го е поискала, заобикаля row-level security, на която разчита приложението, и не може да пише във веригата за одит на продукта. Така командите му биха се одитирали само доколкото се доставят журнали на сървъра. Шлюзът прави одитната следа свойство на достъпа, а не практика около него.

За да отговорите на одитна заявка: избройте разрешенията за периода (Break-glass access), отворете историята на дадено разрешение, за да видите командите и идентификаторите на одитните записи, и прочетете ги във веригата за одит на платформата (`bun run audit:verify --platform` доказва целостта на веригата).

Source: https://docs.quirelms.com/bg/ops/key-rotation/index.mdx
