---
title: "Rotasi kunci utama dan kunci penandatanganan, serta akses darurat"
description: "Rotasikan kunci utama yang melindungi kredensial tersimpan dan gunakan akses darurat."
image: "https://docs.quirelms.com/og.png"
---

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

# Rotasi kunci utama dan kunci penandatanganan, serta akses darurat

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

Kontrol dalam bagian 14 dari 21-compliance.md yang diminta auditor secara spesifik.
Halaman ini menjelaskan prosedurnya; catatan yang dihasilkannya menjadi buktinya.

## Kunci <!--quire:the-keys-->

Setiap kredensial tersimpan disegel dengan kunci enkripsi data (DEK) yang baru.
DEK dibungkus oleh kunci utama (KEK), dan referensi kunci utama disimpan di
sebelahnya (`key_ref`, atau referensi di dalam nilai yang dipaketkan). Rotasi
kunci utama membungkus ulang DEK. Rotasi ini tidak pernah mendekripsi atau
mengenkripsi ulang kredensial.

| Pengaturan | Arti |
| --- | --- |
| `QUIRE_MASTER_KEY` | Kunci utama saat ini: 32 byte, base64. Setiap rahasia baru dibungkus dengannya |
| `QUIRE_MASTER_KEY_VERSION` | Label versinya. `v1` jika tidak disetel. Naikkan nilainya setiap kali Anda mengganti kunci |
| `QUIRE_MASTER_KEY_RETIRED` | Kunci sebelumnya yang mungkin masih digunakan untuk menyimpan rahasia, dalam format `v1=<base64>,v0=<base64>`. Hanya dibaca, tidak pernah ditulis |

Tingkat web, worker, dan perintah `bun run kek:rotate` membaca ketiga pengaturan
yang sama. Nilainya harus sama di semuanya, jika tidak salah satunya tidak dapat
membuka nilai yang disegel oleh yang lain.

Tanpa `QUIRE_MASTER_KEY`, setiap subsistem menyimpan kunci yang diturunkannya
dari `QUIRE_SECRET_KEY`. Cara ini berfungsi; halaman Kesehatan Sistem akan
menunjukkan status terdegradasi, dan data tetap dapat dibaca setelah Anda
menetapkan kunci utama. Dengan cara inilah rotasi pertama memindahkan semuanya
dari kunci tersebut. Siapa pun yang dapat membaca lingkungan proses bisa
mendekripsi setiap kredensial tersimpan, jadi instalasi produksi sebaiknya
memiliki kunci utama yang disimpan di penyimpanan rahasia, bukan di cadangan yang
sama dengan basis data.

## Rotasi <!--quire:rotating-->

Usia kunci ditampilkan di konsol Platform, Keamanan, Kunci utama, dan sebagai
metrik `quire.secrets.master_key.age` (hari). Jadwal harian `platform.key_age`
(03:41 UTC) menulis pengingat ke rantai audit platform saat kunci mencapai usia
365 hari, lalu setiap 30 hari sampai kunci dirotasikan. Lakukan rotasi saat ada
pengingat, serta setiap kali kunci mungkin telah terpapar.

1. Buat kunci baru: `openssl rand -base64 32`.
2. Setel `QUIRE_MASTER_KEY` ke nilai tersebut dan `QUIRE_MASTER_KEY_VERSION` ke
   label berikutnya (`v2`). Pindahkan kunci lama ke `QUIRE_MASTER_KEY_RETIRED`
   sebagai `v1=<old base64>`. Simpan salinan keduanya di tempat selain host ini.
3. Terapkan tingkat web dan worker dengan pengaturan baru. Rahasia baru kini
   dibungkus dengan `env:QUIRE_MASTER_KEY:v2`; rahasia lama tetap bisa dibuka
   melalui kunci pensiun.
4. Minta rotasi dengan alasan yang akan tercatat di jejak audit:
   - di konsol: Keamanan, Kunci utama, Rotasikan kunci utama; atau
   - di shell dengan lingkungan yang sama: `bun run kek:rotate request --reason "Annual rotation, ticket SEC-114"`.
5. Worker membungkus ulang sebagian data setiap menit (jadwal penjadwal
   `platform.key_rotation`) dan melanjutkan setelah dimulai ulang. Untuk
   menyelesaikannya sekaligus: `bun run kek:rotate run`. Pantau dengan
   `bun run kek:rotate status`.
6. Setelah catatan menunjukkan rotasi selesai dengan **nol belum terselesaikan
   dan nol gagal**, hapus kunci pensiun dari `QUIRE_MASTER_KEY_RETIRED` lalu
   terapkan ulang. Sampai saat itu, simpan kunci tersebut: nilai yang tidak dapat
   dipindahkannya masih dibungkus dengan kunci lama.

### Data yang diproses oleh tugas <!--quire:what-the-job-walks-->

Setiap penyimpanan yang menampung DEK terbungkus: yang tercantum dalam
`SEALED_STORES` (`apps/worker/src/key-rotation.ts`). Penyimpanan basis data
kontrol diproses di basis data kontrol; penyimpanan organisasi diproses satu
organisasi pada satu waktu di bawah keamanan tingkat baris, di basis data mana
pun yang menampung organisasi tersebut. Dengan demikian, penyewa yang
ditempatkan pada basis data khusus akan dirotasikan di basis data itu. Sebuah tes
akan gagal jika skema menambahkan kolom berkunci terbungkus yang tidak tercantum
di daftar, dan tes lain akan gagal jika tinjauan kredensial mengklasifikasikan
kolom tersegel yang terlewat dari daftar.

### Catatan <!--quire:the-record-->

- `ops.key_rotation`: satu baris untuk setiap rotasi, beserta alasannya, peminta,
  status, dan jumlahnya (dibungkus ulang, sudah terkini, belum terselesaikan,
  gagal).
- `ops.key_rotation_progress`: satu baris untuk setiap penyimpanan dan cakupan
  setelah diproses, beserta referensi kunci yang tidak dapat dibaca dan jumlah
  nilai di bawah tiap referensi. Rotasi yang dilanjutkan akan melewati data ini.
- Rantai audit Platform: `platform/key_rotation_request` (dengan alasannya),
  satu `platform/key_rotation_store` untuk setiap penyimpanan beserta jumlahnya,
  dan `platform/key_rotation_complete` atau `platform/key_rotation_fail`;
  `platform/key_age_reminder` untuk pengingat.
- Metrik: `quire.secrets.master_key.age` dan `quire.secrets.rewrap.outstanding`
  (nilai yang tidak dapat dipindahkan oleh rotasi terakhir).

### Jika nilai belum terselesaikan <!--quire:when-values-are-unresolved-->

Nilai yang belum terselesaikan dibungkus dengan referensi kunci yang tidak
dimiliki instalasi ini, atau bentuknya tidak sesuai dengan yang dijanjikan
kolomnya. Catatan progres menyebut referensinya (misalnya
`env:QUIRE_MASTER_KEY:v0 (unreadable)`). Pulihkan kunci itu ke
`QUIRE_MASTER_KEY_RETIRED` lalu jalankan rotasi lagi; atau, jika kuncinya hilang
selamanya, minta administrator organisasi memasukkan kembali kredensial tersebut:
kredensial itu kemudian disegel dengan kunci saat ini. Rotasi yang gagal
menampilkan kesalahannya di catatan; perbaiki penyebabnya lalu ajukan permintaan
lagi.

## Kunci penandatanganan <!--quire:signing-keys-->

Terpisah dari kunci utama: setiap organisasi menandatangani token OpenID Connect
dan pesan LTI dengan kunci RSA miliknya sendiri, yang dipublikasikan di
`/.well-known/jwks.json`. Operator tidak perlu melakukan apa pun di sini. Jadwal
per jam `platform.signing_keys` memublikasikan kunci penerus tujuh hari sebelum
masa berlaku kunci saat ini yang 90 hari berakhir. Seminggu kemudian, kunci
penerus mulai menandatangani dan kunci lama memasuki masa pensiun. Sembilan puluh
hari setelah itu, kunci lama dihapus dan dikeluarkan dari kumpulan kunci. Setiap
langkah dicatat sebagai entri `platform/signing_key_advance` di rantai audit
platform.

Untuk mengganti kunci organisasi lebih awal, misalnya setelah terjadi paparan:

- di konsol: Keamanan, Kunci utama, Publikasikan kunci penandatanganan baru
  (memerlukan `platform/keys_manage`); atau
- di shell dengan lingkungan worker:
  `bun run kek:rotate signing-keys rotate
  --tenant <slug or id> --reason "Key exposed, INC-3310"`. Perintah
  `bun run kek:rotate signing-keys status` mencantumkan kunci setiap organisasi
  berdasarkan tahapnya.

Kunci baru langsung dipublikasikan dan mulai menandatangani setelah tujuh hari,
saat kunci saat ini memasuki masa pensiun. Jeda satu minggu ini disengaja:
pihak yang mengandalkan layanan menyimpan salinan kumpulan kunci dalam cache,
dan tumpang tindih yang lebih singkat akan membuat semua alat gagal sekaligus.
Kunci pensiun tetap ada di kumpulan kunci selama 90 hari lagi agar token yang
telah ditandatanganinya tetap bisa diverifikasi. Jika paparan mengharuskan
kunci itu berhenti dipercaya lebih awal, menghapus barisnya merupakan perubahan
yang dilakukan dengan akses basis data milik operator sendiri di bawah catatan
perubahan (akses darurat hanya baca). Setelah itu token yang ditandatangani
dengannya akan gagal diverifikasi. Rotasi paksa dicatat sebagai
`platform/signing_key_rotate` di rantai audit, beserta alasannya. Worker
memerlukan pengaturan `QUIRE_MASTER_KEY` yang sama dengan tingkat web untuk
membungkus kunci baru; perintah `bun run kek:rotate` untuk kunci utama membungkus
ulang kunci penandatanganan bersama data lainnya (`oauth_signing_key` tercantum
di `SEALED_STORES`).

## Akses darurat produksi <!--quire:break-glass-production-access-->

Tidak seorang pun memiliki akses tetap ke produksi. Jika sesuatu tidak bisa
menunggu, pemilik menerbitkan izin akses darurat: konsol Platform, Keamanan,
Akses darurat.

- Izin memiliki cakupan (satu organisasi atau registri platform), alasan minimal
  20 karakter yang menyebut insiden atau tiket, serta jangka waktu 5 hingga 240
  menit. Izin kedaluwarsa sendiri: masa berlakunya diperiksa terhadap waktu pada
  setiap pernyataan.
- Izin dapat diterbitkan untuk pemilik yang menerbitkannya sendiri atau untuk
  pemilik lain (mekanisme dua orang). Hanya orang yang dituju izin tersebut yang
  dapat menggunakannya. Penerbitan memerlukan `platform/break_glass_issue` dan
  penggunaan memerlukan `platform/break_glass_use`; secara bawaan keduanya hanya
  untuk pemilik.
- Pernyataan dijalankan melalui gateway, bukan melalui login basis data: hanya
  baca, satu per satu, terbatas pada organisasi atau registri kontrol, dengan
  batas waktu lima detik dan paling banyak 500 baris. Nilai biner ditampilkan
  berdasarkan ukurannya.
- Rantai audit platform mencatat penerbitan (beserta alasannya), pencabutan,
  setiap pernyataan sebelum dijalankan (`platform/break_glass_statement`, yang
  ditolak dengan hasil `denied`), serta setiap hasil (`platform/break_glass_result`).
  `ops.break_glass_statement` menyimpan ID entri audit sehingga catatan
  penerbitan dapat ditautkan ke entri auditnya.
- Penulisan tidak tersedia. Perubahan yang tidak bisa menunggu rilis menggunakan
  akses basis data milik operator sendiri di bawah catatan perubahan tersendiri,
  di luar produk ini, dan catatan tersebut sebaiknya mencantumkan referensi
  insiden yang digunakan di sini.

Mengapa tidak menerbitkan kredensial basis data: login Postgres tetap aktif
setelah sesi yang memintanya berakhir, melewati keamanan tingkat baris yang
digunakan aplikasi, serta tidak dapat menulis ke rantai audit produk ini.
Akibatnya, pernyataannya hanya akan diaudit sejauh seseorang mengirim log server.
Gateway menjadikan jejak audit sebagai bagian dari akses itu sendiri, bukan
sekadar praktik di sekitarnya.

Untuk menjawab permintaan audit: tampilkan daftar izin dalam periode tersebut
(Akses darurat), buka riwayat izin untuk melihat pernyataan dan ID entri
auditnya, lalu baca entri tersebut di rantai audit platform
(`bun run audit:verify --platform` membuktikan rantainya utuh).

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