シークレットを入れ替える
tegata v0.3.1 の文書
シークレットを、それを使うサービスを止めずに新しい値に替える方法です。手順は、古い値と新しい値が同時に使えるかどうかで変わります。previous と settle が要る値と要らない値がある理由は、例とともにシークレットに previous が要るときにあります。
| 値 | 例 | 手順 |
|---|---|---|
| 自分のサービスが確かめていて、2 つの値を受け付けられる | セッションの鍵、署名の鍵、Webhook のシークレット(previous を付けた random) |
rotate → render → settle → render → prune |
| ほかのサービスが発行していて、古い方を消すまでは新旧どちらも使える | cloudflare/api_token、tailscale/auth_key、aws/ses_smtp_credentials |
rotate → render → prune |
| 値が 1 つしかなく、新しく作るとすぐに古い方が使えなくなる | gcp/sql_user、cloudflare/tunnel_token |
rotate(先に聞く)→ すぐに render → prune |
| 手で入れる | manual |
set → render → prune |
「render」は、そのシークレットを使うすべてのサーバーで tegata render を流し、ファイルを読むサービスを再起動(または設定を読み直し)することです。tegata render をタイマーで --on-change 付きで動かしていれば、サーバーが数分のうちに自分でやります(サーバーで動かす)。GitHub Actions の secrets(届け先)には何も要りません。rotate、settle、set のときに tegata が新しい値を書き、ワークフローは次の実行からそれを使います。
tegata status で、各リソースがどこまで進んでいるかが分かります。generation 2 (+1 to prune) は、入れ替えのあとの片付けがまだ済んでいないという意味です。
自分のサービスが確かめる鍵:rotate、settle、prune
Section titled “自分のサービスが確かめる鍵:rotate、settle、prune”リソースに previous のシークレットを付け、サービスが、どちらかに合う値を受け付けるようにします。
resources: session_key: provider: random stores: main: - { name: SESSION_KEY, readers: [app] } previous: { name: PREVIOUS_SESSION_KEY } # read by the readers of SESSION_KEYSESSION_KEY=__SESSION_KEY__PREVIOUS_SESSION_KEY=__PREVIOUS_SESSION_KEY__サービスは SESSION_KEY で署名し、両方を受け付けます。
tegata rotate session_key # SESSION_KEY: new; PREVIOUS_SESSION_KEY: the old value# render and restart: services sign with the new key, and still accept the old onetegata settle session_key # PREVIOUS_SESSION_KEY: the new value too# render and restart: the old value is no longer acceptedtegata prune session_key # disable the old versions in the storerotate と settle の間は、古い鍵で署名した値を有効にしておく必要がある間(セッションの鍵なら、セッションの有効期間)だけ待ちます。
並べて使えるトークン:rotate、prune
Section titled “並べて使えるトークン:rotate、prune”プロバイダーが、1 つ目のトークンの隣に 2 つ目を作ります。prune が古い方を消すまでは、どちらも使えます。
tegata rotate releases_read # a second token exists; the old one still works# render and restart on every server that uses ittegata prune releases_read # delete the old token on the provider, disable the old versionsprune は、すべてのサーバーが新しい値を使うようになってから流してください。古いトークンのままのサービスは、それが消されると動かなくなります。aws/ses_smtp_credentials は、IAM ユーザーが持てるアクセスキーが 2 つまでなので、もう一度入れ替える前に prune してください。
すぐに置き換わる値:rotate、すぐに render、prune
Section titled “すぐに置き換わる値:rotate、すぐに render、prune”Cloud SQL のユーザーのパスワードは 1 つ、Cloudflare Tunnel のシークレットも 1 つです。新しく作ると、古い方はすぐに使えなくなります。開いている接続は残りますが、新しい接続は、サーバーが新しい値を持つまで失敗します。apply と rotate は、何が止まるかと誰が読んでいるかを示し、yes と打つように求めます(スクリプトでは --yes で聞かずに進み、--dry-run は示すだけです)。
tegata rotate --dry-run db_password # see what would changetegata rotate db_password # type yes# render and restart at once on every server that uses ittegata prune db_password # disable the old versionscloudflare/tunnel_token では、prune は、入れ替えの前に起動したコネクターがまだつながっていないかを確かめ、すべての cloudflared が新しいトークンで再起動するまでは(コネクターの名前を挙げて)断ります。gcp/sql_user では、prune は Cloud SQL の上で何も消しません。古いパスワードはもう使えなくなっているためです。
手で入れる値:set
Section titled “手で入れる値:set”tegata set admin_password # hidden input; or pipe it on standard input# render and restarttegata prune admin_passwordリソースに previous があれば、set は rotate と同じように、先に今の値をそこに写します。そのあとは最初の節の手順になります。
うまくいかないとき
Section titled “うまくいかないとき”- サーバーが新しい値を読めない。
renderは__NAME__をファイルに残し、その名前を挙げます。サーバーのアイデンティティがそのシークレットのreadersに入っているか、足したあとにtegata applyを流したかを確かめてください(読み手はtegata statusで分かります。tegata check <identity> <templates>で、雛形とアイデンティティが読めるものを比べられます)。 - サーバーが新しい値を持つ前に prune してしまった。 新しい値はもう保存先にあります。そのサーバーで render して再起動してください。古い版は消さずに無効にしてあるだけなので、Secret Manager で有効に戻せば読めます。ただし、プロバイダーの側で消したトークンは戻せません。
- 古い値が漏れた。 間を置かずに、rotate、render、prune を続けて流してください。