暗号化キー
Semaphore は、保存するデータの中で最も機密性の高いもの — アクセスキーのシークレット (SSH 秘密鍵、ログイン/パスワードのペア、シークレット文字列) と JWT 署名 キー — を AES‑256‑GCM で暗号化します。このページでは、これらのキーの設定方法、 ローテーションの仕組み、および安全に運用する方法について説明します。
| キー | 保護対象 | アクティブポインター |
|---|---|---|
| シークレットキー | データベースに保存されたアクセスキーのシークレット | active.secret_key |
| オプションキー | 暗号化された DB オプション (JWT 署名キー) | active.option_key |
オプションキーが設定されてい ない場合、オプションはシークレットキーにフォールバックします。
クイックスタート
最も簡単な構成は、メイン設定で 1 つのキーを指定する方法です。
encryption:
keys_file: /etc/semaphore/encryption-keys.yml
keys:
key1: { value: "REPLACE_WITH_openssl_rand_-base64_32" }
active:
secret_key: key1
キーは次のコマンドで生成します。
openssl rand -base64 32
これだけです — Semaphore は key1 でシークレットを暗号化するようになります。同じキーが
JWT 署名キーにも使用されます (オプションはシークレットキーにフォールバックします)。
インラインの value: よりも file: 参照または keys_folder (下記参照) を
優先し、キー素材が設定ファイルではなくマウントされたシークレットに置かれるようにしてください。
キーの識別方法
各キーには、キー素材そのものから導出されたキー ID — フィンガープリント
base64url(sha256(key))[:8] — があります。暗号化された各値と一緒に保存されるのは
(キーではなく) この ID なので、復号は書き込みに使われたまさにそのキーの直接的なルックアップになります。
これは次のことを意味します。
- ラベルは自由に変更できます。
key1、secrets_key_primary.txt— これらは 人間のためのものです。データベースにはフィンガープリントだけが保存され、ラベルは保存されません。 - キーが誤って参照されることはありません。 キーのバイト列を変更すると新しい ID になり、古いデータは古い ID を参照し続けます。
- キーを削除すると明示的に失敗します。静かに失敗することはありません — 見つからないキー ID は明示的な エラーになり、不正な出力が返されることはありません。
ID を手動で設定することはありません。Semaphore が計算します。
キーファイル
encryption.keys_file は、キーのレジストリと用途ごとのアクティブなキーへの
ポインターを内容とするファイルを指します。ファイル拡張子に関係なく、YAML または JSON
として解析されます。
レジストリを指定する方法は 2 つあります — インラインマップ、ファイルのフォルダー、または その両方の組み合わせです。
インラインマップ
keys:
key1: { value: "2hmxtfgK6LkJfJK9ZNZ9GUMmEwTQwHIFamijclUem48=" } # inline (dev)
key2: { file: /run/secrets/secret_key } # from a file (prod)
active:
secret_key: key1
option_key: key2
各エントリは KeySource です。value (インラインの base64) または
file (base64 キーを含むファイルへのパス) のいずれかで、両方を指定することはできません。
キーファイルのフォルダー
keys_folder でディレクトリを指定すると、すべての通常ファイルが 1 つのキーとして、
ファイル名をラベルにして扱われます。マウントされた Docker/Kubernetes シークレットに最適です。
keys_folder: /run/secrets/enc-keys
active:
secret_key_file: secrets_key_primary.txt # filename in keys_folder (relative)
option_key_file: options_key_primary.txt
secrets_key_primary.txt # one base64 key per file
secrets_key_old.txt # retired keys stay as files
options_key_primary.txt
keys_folder はドットで始まるエントリ (..data、..2024_*) をスキップし、
シンボリックリンクをたどるため、Kubernetes が Secret/ConfigMap ボリュームをマウントする
方式でそのまま動作します。
組み合わせ
keys と keys_folder は 1 つのレジストリにマージされます。active はラベル
またはファイル名で指定できます。
keys:
inline1: { value: "..." }
keys_folder: /run/secrets/enc-keys
active:
secret_key: inline1
option_key_file: options_key_primary.txt
ローテーション (ダウンタイムなし)
アクティブなキーは新しい書き込みを暗号化し、レジストリ内の他のすべてのキーは引き続き 古いデータを復号できます。したがってローテーションは、キーを追加し、ポインターを切り替え、 バックグラウンドで再暗号化し、その後古いキーを削除する、という手順になります。
# 1. Add a new key to the registry (a file in keys_folder, or a keys: entry)
# and point the active pointer at it:
# active.secret_key: key2 # (or secret_key_file: ...)
# 2. Apply it without a restart — within keys_poll_interval (default 15s),
# or immediately:
kill -HUP $(pidof semaphore)
# 3. Re-encrypt existing data to the new key:
semaphore vault rekey --config /etc/semaphore/config.yml
# 4. Confirm nothing still uses the old key:
semaphore vault check --config /etc/semaphore/config.yml
# 5. When the old key shows "0 rows", remove it from the registry.
どの手順でもプロセスの再起動は不要です。
再起動なしでの変更の適用
Semaphore はキーファイル (およびそこから参照されるキーファイル) を再読み込みし、 メモリ上のキーをアトミックに入れ替えます。トリガーは 2 つあります。
| トリガー | 動作 |
|---|---|
| ファイルウォッチャー | encryption.keys_poll_interval (デフォルト 15s) ごとにポーリングします。"0" に設定すると無効になります。 |
SIGHUP | kill -HUP <pid> で即時の再読み込みを強制します (Unix のみ)。 |
Windows には SIGHUP がありません。ポーラー (デフォルト) を利用するか — すべての
プラットフォームで動作します — サービスを再起動してください。
再読み込みではまず新しいキーが検証され、エラーがあれば実行中のキーは そのまま維持されます。
CLI コマンド
vault check
読み取り専用です。キー ID ごとに、そのキーで暗号化されている保存済みシークレットの数を報告するため、 アクティブなキーにあるものと安全に削除できるものを確認できます。
semaphore vault check --config /etc/semaphore/config.yml
Access keys: 12 total
IFTi6Ipik8Q: 12 rows — active
rcGGC2AQfKo: 0 rows — retired, SAFE TO REMOVE
JWT signing key: active:IFTi6Ipik8Q
ステータス: active、retired, rekey pending、retired, SAFE TO REMOVE、
legacy (no id)、および MISSING KEY (参照されているキーが存在しない — 終了コード 1)。
vault rekey
保存されているすべてのシークレット (および JWT 署名キー) をアクティブなキーで再暗号化します。
semaphore vault rekey --config /etc/semaphore/config.yml
# Snapshot ciphertexts before re-encrypting, and roll back if needed:
semaphore vault rekey --backup /var/backups/vault.jsonl --config ...
semaphore vault rekey --rollback /var/backups/vault.jsonl --config ...
# Legacy: decrypt pre-existing un-prefixed data with an explicit old key:
semaphore vault rekey --old-key <base64-old-key> --config ...