シークレットの拡散:412個の漏洩トークンをどのように解決したか
3月3日の午前2時13分、CIパイプラインが失敗しました。調査の結果、37のリポジトリにわたって412個のAPIトークンが漏洩していることが判明しました。このエラーにより、潜在的な侵害コストとして120万ドルがリスクにさらされました。
ほとんどのチームは、Vaultがあればすべて解決すると考えています。しかし実際には、Vaultはレイテンシにおける単一障害点(single point of failure)になり得ます。トークンがVaultの外にある場合、ハードコードされた値や環境変数を使用することになります。これらのフォールバックは監査ログに表示されません。
私たちのメトリクスはこの拡散によるコストを示しています:
- 通常のシークレット取得:リクエストあたり48 ms
- 漏洩発生時:リクエストあたり187 ms
ビルドエージェントは、遠隔地にあるVaultクラスターから1ジョブあたり12個のトークンを取得していました。これがタイムアウトを引き起こし、開発者は手動で変更をロールバックせざるを得なくなりました。レイテンシは単なるプロセスの遅延ではありません。それはクラウド料金を膨らませ、開発者のスピードを低下させるコストセンターなのです。
ステージングリポジトリ内の1つの漏洩したAWSキーが攻撃者に悪用された場合、1時間あたり120ドルのコストがかかる可能性があります。わずか1時間の悪用が、四半期ごとのセキュリティ監査よりも高いコストをもたらすのです。
静的スキャナーは役に立ちませんでした。トークンの78%を見逃していたのです。なぜでしょうか? それらのトークンは、ソースコードではなく、ビルドアーティファクト内でオンザフライ(実行時)に生成されていたからです。あるGitHub Actionsのステップが、トークンをDockerレイヤーに書き込んでいました。スキャナーには何も映りませんでしたが、そのトークンは数週間にわたってレジストリ内に残り続けていました。
静的な検査だけでなく、ランタイムの可視性が必要です。
私たちはこれを解決するためにLambdaエンジンを構築しました。これはCloudTrailを監視して新しいシークレットを検出し、Vaultと比較します。新しいワークフローは以下の通りです:
- Webhook経由でシークレットを検出。
- Vaultに対してメタデータを照会。
- プロバイダーのAPI経由でトークンを無効化。
- ファイルからシークレットを削除するためのPRを作成。
- CIを通過すれば、PRを自動的にマージ。
このエンジンは、27分間で412個のトークンを99.97%の成功率でローテーションしました。
現在、私たちはシークレットの有効期間(age)を追跡しています。トークンが30日以上経過している場合、ビルドは失敗します。このシンプルなルールにより、1四半期で新しい漏洩が62%減少しました。また、isolation-forestモデルを使用して、異常な使用パターンをフラグ立てしています。新しいIPからトークンが使用された場合、システムは即座にそれをローテーションします。
トークンをファイルのように扱うのはやめましょう。シークレットの有効期間と取得レイテンシを重要なメトリクスとして扱うのです。そうすれば、拡散は収束に向かうはずです。
Optional learning community: https://t.me/GyaanSetuAi
