mirror of
https://github.com/hanzoai/papers.git
synced 2026-10-29 07:34:31 +00:00
92 lines
3.7 KiB
TeX
92 lines
3.7 KiB
TeX
\section{Key Management}
|
|
|
|
|
|
\subsection{Key Hierarchy}
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\begin{tikzpicture}[
|
|
node distance=1.2cm,
|
|
box/.style={rectangle, draw, minimum width=3cm, minimum height=0.7cm,
|
|
align=center, font=\footnotesize},
|
|
arrow/.style={->, thick}
|
|
]
|
|
\node[box] (master) {Master Key\\(Hanzo KMS)};
|
|
\node[box, below left=1.2cm and 0.5cm of master] (iam-key) {IAM Identity\\(age)};
|
|
\node[box, below=1.2cm of master] (ats-key) {ATS Identity\\(age)};
|
|
\node[box, below right=1.2cm and 0.5cm of master] (kms-key) {KMS Identity\\(age)};
|
|
\node[box, below=1.2cm of iam-key] (iam-recip) {IAM Recipients};
|
|
\node[box, below=1.2cm of ats-key] (ats-recip) {ATS Recipients};
|
|
\node[box, below=1.2cm of kms-key] (kms-recip) {KMS Recipients};
|
|
|
|
\draw[arrow] (master) -- (iam-key) node[midway,left,font=\scriptsize] {HKDF};
|
|
\draw[arrow] (master) -- (ats-key) node[midway,left,font=\scriptsize] {HKDF};
|
|
\draw[arrow] (master) -- (kms-key) node[midway,right,font=\scriptsize] {HKDF};
|
|
\draw[arrow] (iam-key) -- (iam-recip);
|
|
\draw[arrow] (ats-key) -- (ats-recip);
|
|
\draw[arrow] (kms-key) -- (kms-recip);
|
|
\end{tikzpicture}
|
|
\caption{Key derivation hierarchy. Per-service age identities are derived
|
|
from the master key via HKDF.}
|
|
\label{fig:keys}
|
|
\end{figure}
|
|
|
|
\begin{enumerate}[nosep]
|
|
\item \textbf{Master encryption key.} Stored in Hanzo KMS (HIP-0027).
|
|
This is the root of trust for all replicate encryption. It is a 256-bit
|
|
symmetric key used as HKDF input keying material.
|
|
|
|
\item \textbf{Per-service age keypairs.} Derived from the master key via
|
|
HKDF with the service name as the info parameter:
|
|
\texttt{HKDF-SHA256(master, salt="hanzo-replicate", info=service\_name)}.
|
|
The derived 32 bytes are used as the X25519 private key (age identity).
|
|
The corresponding public key is the age recipient.
|
|
|
|
\item \textbf{Recipients file.} Contains the public keys (recipients) of
|
|
all parties authorized to decrypt the replica. For normal operation, this
|
|
is the service's own recipient. For disaster recovery, this includes a
|
|
recovery recipient held offline.
|
|
\end{enumerate}
|
|
|
|
\subsection{Key Rotation}
|
|
|
|
Key rotation proceeds without downtime:
|
|
|
|
\begin{enumerate}[nosep]
|
|
\item Generate a new age keypair (derived from a new HKDF info or a
|
|
rotated master key).
|
|
\item Add the new recipient to the recipients file. The old recipient
|
|
remains.
|
|
\item Restart the \texttt{replicate} sidecar. New WAL segments and
|
|
snapshots are encrypted to both old and new recipients.
|
|
\item After the retention period expires (72 hours for WAL, 30 days for
|
|
snapshots), all surviving replicas are encrypted to the new recipient.
|
|
\item Remove the old recipient from the recipients file.
|
|
\item The old identity is retained in KMS for historical reads. It is
|
|
marked as \texttt{rotated} but never deleted.
|
|
\end{enumerate}
|
|
|
|
\subsection{Emergency Recovery}
|
|
|
|
Full restore requires two keys: the master key from Hanzo KMS and the
|
|
per-service age identity derived from it. The recovery procedure:
|
|
|
|
\begin{enumerate}[nosep]
|
|
\item Retrieve the master key from KMS (requires KMS admin
|
|
authentication).
|
|
\item Derive the service identity:
|
|
\texttt{age-keygen -o identity.txt} from the HKDF output.
|
|
\item Run \texttt{replicate restore -config replicate.yml
|
|
/data/base/data.db}.
|
|
\item The restored database is encrypted with sqlcipher. The sqlcipher key
|
|
is also in KMS.
|
|
\end{enumerate}
|
|
|
|
If KMS itself is unavailable (catastrophic failure), the KMS database is
|
|
restored first using the offline recovery identity (stored in a physical
|
|
safe or HSM).
|
|
|
|
% ============================================================================
|
|
% 6. DEPLOYMENT
|
|
% ============================================================================
|