GitLab Stack Secrets Manager について
GitLab stack プロジェクトのシークレット管理と Docker secrets への統合を支援するセキュリティ重視のスキルです。作成、移行、検証、監査、ローテーション、漏えい確認を扱い、.env や docker-compose.yml への値の記載を避けます。
主な機能
- 01シークレットファイルの作成と生成
- 02環境変数から Docker secrets への移行
- 03権限、所有者、Git 除外の確認
- 04使用状況と漏えい可能性の監査
- 05既存シークレットのローテーションや削除
- 06必要に応じたエントリーポイントスクリプトの生成
活用シーン
- 01.env の機密値を移行
- 02Docker secrets 設定の検証
- 03リポジトリ内のシークレット漏えい調査
- 04未使用または保護不備のシークレット監査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ rknall/ claude-skills --skill gitlab-stack-secrets-managerインストール後、Claude Code で/gitlab-stack-secrets-managerを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdmigration-guide.mdsecrets-patterns.md詳細
GitLab Stack Secret Manager
このスキルは、GitLab Stack プロジェクトのシークレットを管理し、シークレットが安全に保存され、設定ファイルで公開されず、Docker secrets と適切に統合されるようにします。
このスキルを使用するタイミング
ユーザーから次の依頼があった場合、このスキルを有効にします:
- Docker secrets を作成または管理する
- 環境変数を Docker secrets に移行する
- シークレットの設定と権限を検証する
- シークレットの使用状況を監査し、漏洩を検出する
- シークレットが .env や docker-compose.yml に含まれていないことを確認する
- シークレットが git で公開されているか確認する
- 安全なランダムシークレットを生成する
- 既存のシークレットをローテーションする
- シークレット関連のセキュリティ問題を修正する
セキュリティの基本原則
重要なルール — 決して違反してはいけません:
- .env にシークレットを含めない:シークレットを .env ファイルに含めてはいけません
- docker-compose.yml にシークレットを含めない:環境変数にプレーンテキストのシークレットを含めてはいけません
- ./secrets ディレクトリ:すべてのシークレットを権限 700 の ./secrets に保存します
- シークレットファイル:個別のファイルを権限 600 で保存します
- Git の保護:./secrets/* を .gitignore に追加し、決してコミットしません
- 適切な所有者:すべてのファイルの所有者を Docker ユーザーにします(root ではありません)
- Docker secrets のみ:Docker secrets の仕組みだけを使用します
シークレット管理ワークフロー
フェーズ 1:ユーザーの意図を把握する
ステップ 1:操作を特定する
ユーザーが何をしようとしているか確認します:
- 新しいシークレットを作成する?
- 既存の環境変数をシークレットに移行する?
- 現在のシークレット設定を検証する?
- シークレットを監査して、漏洩や問題がないか確認する?
- 既存のシークレットを更新またはローテーションする?
- シークレットを削除する?
ステップ 2:状況を把握する
-
現在のプロジェクトの状態を確認します:
- ./secrets ディレクトリは存在するか?
- docker-compose.yml は存在するか?
- .env ファイルは存在するか?
- これは stack-validator の検出結果に関連しているか?
-
docker-compose.yml を確認します:
- すでに定義されているシークレットはあるか?
- シークレットのように見える環境変数はあるか?
- どのサービスにシークレットが必要か?
-
セキュリティ上の問題をスキャンします:
- .env にシークレットがあるか?
- docker-compose.yml の環境変数にシークレットがあるか?
- git で追跡されているシークレットはあるか?
フェーズ 2:シークレットの作成
タイミング:ユーザーが新しいシークレットの作成を希望する場合
ステップ 1:前提条件を検証する
- ./secrets ディレクトリが存在するか確認します:
ls -ld ./secrets - 存在しない場合は、適切な権限で作成します:
mkdir -p ./secrets chmod 700 ./secrets
ステップ 2:シークレットの詳細を決定する
ユーザーに確認する(または状況から推測する)項目:
- シークレット名(例:db_password、api_key)
- 生成方法:
- ユーザーが値を指定する
- ランダムな値を生成する
- パターンから生成する
- 書式要件(英数字、16 進数、base64 など)
- 長さの要件
ステップ 3:シークレットファイルを作成する
- シークレット値を生成するか、受け取ります
- ./secrets にファイルを作成します:
echo -n "secret-value" > ./secrets/secret_name - 適切な権限を設定します:
chmod 600 ./secrets/secret_name - 所有者を確認します(root 以外である必要があります)
ステップ 4:docker-compose.yml を更新する
-
トップレベルの secrets セクションに追加します:
secrets: secret_name: file: ./secrets/secret_name -
該当するサービスに追加します:
services: myservice: secrets: - secret_name
ステップ 5:.gitignore を確認する
./secrets が除外されていることを確認します:
/secrets/
/secrets/*
!secrets/.gitkeep
フェーズ 3:シークレットの検証
タイミング:ユーザーがシークレットの設定を検証したい場合、またはほかの操作の一環として
ステップ 1:ディレクトリ構造の検証
-
./secrets が存在することを確認します:
[ -d ./secrets ] && echo "exists" || echo "missing" -
権限を確認します(700 である必要があります):
stat -c "%a" ./secrets # Linux stat -f "%OLp" ./secrets # macOS -
所有者を確認します(root ではないこと):
ls -ld ./secrets
ステップ 2:シークレットファイルの検証
-
すべてのシークレットファイルを一覧表示します:
find ./secrets -type f ! -name .gitkeep -
各ファイルについて、以下を確認します:
- 権限(600 である必要があります)
- 所有者(root ではないこと)
- 空ではないこと
- 読み取り可能であること
ステップ 3:docker-compose.yml の検証
-
secrets セクションを解析します:
- 定義されているすべてのシークレットを一覧表示します
- 各シークレットのファイルが存在することを確認します
-
サービスのシークレット参照を確認します:
- 参照されているすべてのシークレットが定義されていること
- サービスが環境変数ではなく
secrets:キーを使用していること
-
重大:環境変数に含まれるシークレットをスキャンします:
- PASSWORD、SECRET、KEY、TOKEN、API のパターンを検索します
- シークレットと思われるものをすべて警告します
- これらは必ず移行する必要があります
ステップ 4:.env ファイルの検証
-
重大:.env 内のシークレットをスキャンします:
- パターンマッチング:PASSWORD、SECRET、KEY、TOKEN、API
- 長く、ランダムに見える文字列
- Base64 エンコードされた値
- シークレットであるべきすべての値
-
.env 内にシークレットが見つかった場合:
- 重大なセキュリティ上の問題です
- 検出されたすべてのシークレットを一覧表示します
- 直ちに移行することを推奨します
ステップ 5:Git の安全性確認
-
.gitignore で ./secrets が除外されていることを確認します:
grep -q "secrets" .gitignore -
ステージングされたシークレットがないか確認します:
git status --porcelain | grep secrets/ -
(要求された場合)シークレットが Git の履歴にないか確認します:
git log --all --full-history -- ./secrets/
ステップ 6:検証レポートの生成
🔐 Secrets Validation Report
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📁 Directory Structure
✅ ./secrets exists with 700 permissions
✅ Owned by user (1000:1000)
✅ ./secrets in .gitignore
📄 Secret Files (3)
✅ db_password - 600 permissions, 32 bytes
✅ api_key - 600 permissions, 64 bytes
⚠️ jwt_secret - 644 permissions (should be 600)
🐳 Docker Integration
✅ 3 secrets defined in docker-compose.yml
✅ All secret files exist
⚠️ Service 'worker' uses docker-entrypoint.sh
❌ CRITICAL SECURITY ISSUES
❌ .env contains secrets:
* DB_PASSWORD=supersecret123
* API_KEY=sk_live_abc123
** IMMEDIATE ACTION REQUIRED **
❌ docker-compose.yml environment variables contain secrets:
* Service 'app' - JWT_SECRET in environment
** MUST MIGRATE TO DOCKER SECRETS **
✅ Git Safety
✅ No secrets in git staging
✅ .gitignore properly configured
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Status: FAILED (2 critical issues)
🔧 IMMEDIATE ACTIONS REQUIRED
1. Migrate secrets from .env to Docker secrets
2. Remove secrets from docker-compose.yml environment
3. Fix permissions on jwt_secret file
フェーズ 4:シークレットの移行
タイミング:.env または docker-compose.yml の環境変数内にシークレットが見つかった場合
重大:これは修正が必要なセキュリティ上の問題です
ステップ 1:移行するシークレットを特定する
-
.env をスキャンしてシークレットのパターンを探します:
grep -E "(PASSWORD|SECRET|KEY|TOKEN|API)" .env -
docker-compose.yml の environment セクションをスキャンします:
# Look for patterns in environment variables -
検出したすべてのシークレットについて、以下を一覧表示します:
- 変数名
- 現在の場所(.env または compose)
- 現在の値(移行用)
- 推奨するシークレット名
ステップ 2:ユーザーに確認する
検出内容を提示し、以下を確認します:
- どの変数を移行するか
- シークレット名の確認
- .env/compose から削除しても安全かどうかの確認
ステップ 3:シークレットファイルを作成する
移行する各シークレットについて:
- 現在の値を抽出します
- シークレットファイルを作成します:
echo -n "$value" > ./secrets/secret_name chmod 600 ./secrets/secret_name - docker-compose.yml の secrets セクションに追加します
ステップ 4:サービス設定を更新する
シークレットを使用する各サービスについて:
- サービスの secrets リストに追加します
- 環境変数から削除します
- コンテナが
_FILEサフィックスをサポートしている場合:environment: DB_PASSWORD_FILE: /run/secrets/db_password - コンテナがネイティブのシークレットをサポートしていない場合:
- docker-entrypoint.sh を作成または更新します
- この要件を文書化します
ステップ 5:クリーンアップ
- .env からシークレットを削除します:
- 行を削除するか、
- 移行に関する注記を付けてコメントアウトします
- docker-compose.yml の environment から削除します
- .env.example にシークレットの値が含まれていないことを確認します
ステップ 6:検証
- サービスが正しく起動することをテストします
- サービスがシークレットにアクセスできることを確認します
- .env または compose にシークレットが残っていないことを確認します
- 検証を実行して確認します
フェーズ 5:シークレットの生成
タイミング:安全なランダムシークレットを生成する必要がある場合
ステップ 1:形式の要件を判断する
一般的な形式:
- 英数字:英字と数字(デフォルト)
- 16 進数:16 進数(0-9、a-f)
- Base64:Base64 エンコード
- 数字のみ:数字のみ
- UUID:UUID v4 形式
ステップ 2:長さを判断する
標準的な長さ:
- データベースのパスワード:32~64 文字
- API キー:32~64 文字
- JWT シークレット:64 文字(または 32 バイトの Base64)
- セッションシークレット:32 文字
- 暗号化キー:32 バイト(256 ビット)
ステップ 3:シークレットを生成する
暗号学的に安全な方法を使用します:
# Alphanumeric (32 chars)
openssl rand -base64 32 | tr -d '/+=' | head -c 32
# Hex (64 chars)
openssl rand -hex 32
# Base64 (32 bytes)
openssl rand -base64 32
# UUID
uuidgen
# Custom (e.g., 16 alphanumeric)
LC_ALL=C tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 16
ステップ 4:安全に保存する
- ファイルに書き込みます(末尾に改行を付けない):
echo -n "$secret" > ./secrets/secret_name - 権限を設定します:
chmod 600 ./secrets/secret_name
フェーズ 6:シークレットの監査
タイミング:シークレットの使用状況を監査したい場合、漏えいを調べたい場合、またはセキュリティを確認したい場合
ステップ 1:シークレットの一覧
すべてのシークレットについて、詳細を一覧にします:
- 名前
- ファイルパス
- ファイルサイズ
- 権限
- 所有者
- 作成日(確認できる場合)
- 最終更新日時
ステップ 2:使用状況の分析
各シークレットについて:
- docker-compose.yml で定義されているか確認します
- 使用しているサービスを一覧にします
- ファイルが存在するか確認します
- 実際に使用されているか確認します
ステップ 3:未使用のシークレットの特定
- 定義されているものの、どのサービスでも使用されていないシークレット
- docker-compose.yml に記載されていないシークレットファイル
- 削除または文書化を提案します
ステップ 4:漏えいの検出
一般的な漏えい場所を確認します:
-
.env ファイル(重大):
grep -E "(PASSWORD|SECRET|KEY|TOKEN)" .env -
docker-compose.yml の environment(重大):
- すべての environment セクションをスキャンします
- シークレットを検出して警告します
-
設定ファイル:
grep -r "password\|secret\|key" ./config/ -
Git の履歴:
git log -p --all -S "secret-pattern" -
Docker のログ:
- 最近のログにシークレットが露出していないか確認します
ステップ 5:権限の監査
-
./secrets 内のすべてのファイルを確認します:
find ./secrets -type f -not -perm 600 -
ディレクトリの権限を確認します:
[ "$(stat -c '%a' ./secrets)" = "700" ] -
所有権を確認します:
find ./secrets -user root
ステップ 6:監査レポートの生成
以下を含めます:
- シークレットの総数
- 使用状況の統計
- 検出されたセキュリティ上の問題
- 推奨事項
- リスク評価
フェーズ 7:docker-entrypoint.sh の生成
タイミング:コンテナが Docker シークレットをネイティブでサポートしていない場合
ステップ 1:必要性の判断
コンテナがシークレットをサポートしているか確認します:
- PostgreSQL、MySQL、MariaDB:
_FILE接尾辞をサポート ✅ - Redis:シークレットをネイティブでサポート ✅
- MongoDB:シークレットをネイティブでサポート ✅
- ほとんどの最新コンテナ:ドキュメントを確認します
以下の場合に限り、エントリーポイントを作成します:
- コンテナが環境変数のみを想定している
_FILE接尾辞をサポートしていない- /run/secrets/ からの読み込みをネイティブでサポートしていない
ステップ 2:必要なシークレットの特定
読み込む必要があるシークレットを一覧にします:
- シークレット名(./secrets/ 内)
- 環境変数名
- サービス名
ステップ 3:エントリーポイントスクリプトの生成
#!/bin/bash
set -e
# Function to load secrets from docker secrets into environment
load_secret() {
local secret_name=$1
local env_var=$2
local secret_file="/run/secrets/${secret_name}"
if [ -f "$secret_file" ]; then
export "${env_var}=$(cat "$secret_file")"
echo "Loaded secret: $secret_name -> $env_var"
else
echo "ERROR: Secret file $secret_file not found!" >&2
exit 1
fi
}
# Load all required secrets
load_secret "db_password" "DB_PASSWORD"
load_secret "api_key" "API_KEY"
load_secret "jwt_secret" "JWT_SECRET"
# Execute the main command
exec "$@"
ステップ 4:権限の設定
chmod +x docker-entrypoint.sh
ステップ 5:docker-compose.yml の更新
services:
myservice:
entrypoint: /docker-entrypoint.sh
command: ["original-command"]
volumes:
- ./docker-entrypoint.sh:/docker-entrypoint.sh:ro
secrets:
- db_password
- api_key
ステップ 6:文書化
エントリーポイントが必要な理由を説明するコメントを追加します:
# docker-entrypoint.sh required because this container
# doesn't support Docker secrets natively
コミュニケーションスタイル
シークレットを管理する際は:
- セキュリティを重視する:あらゆる手順でセキュリティを重視します
- リスクを明確に伝える:.env や compose ファイルにシークレットを記載することが危険な理由を説明します
- 重大な問題には緊急性を持って対応する:セキュリティ上の問題を軽視しません
- 役立つ情報を提供する:問題の修正に必要な正確なコマンドを提示します
- 徹底的に確認する:漏えいの可能性がある場所をすべて確認します
- 理解を促す:Docker シークレットが優れている理由を説明します
- シークレットの値を決して表示しない:「[REDACTED]」に置き換えて表示します
重要な検証項目
以下は必ず満たす必要のあるセキュリティ基準です:
- ✅ .env ファイルにシークレットがない
- ✅ docker-compose.yml の環境変数にシークレットがない
- ✅ ./secrets ディレクトリが存在し、権限が 700 である
- ✅ すべてのシークレットファイルの権限が 600 である
- ✅ .gitignore に ./secrets/* が記載されている
- ✅ Git で追跡されているシークレットがない
- ✅ root 所有のシークレットファイルがない
- ✅ 参照されているすべてのシークレットが存在する
- ✅ docker-entrypoint.sh は本当に必要な場合に限って使用する
関連スキルとの連携
stack-validator
- stack-validator はシークレットの検証にこのスキルを呼び出します
- シークレットが適切なパターンに従っているか検証します
- .env ファイルや compose ファイル内のシークレットを検出します
stack-creator
- 適切に設定された ./secrets ディレクトリを作成します
- .gitkeep ファイルを生成します
- .gitignore を適切に設定します
- 初期シークレットのプレースホルダーを作成します
config-generator
- 設定ファイルにシークレットが含まれていないことを確認します
- シークレットを適切に参照します
- シークレット以外にのみ環境変数を使用します
重要な注意事項
- シークレットは読み取り専用:実際のシークレット値をユーザーに決して表示しません
- セキュリティを最優先:利便性よりも常にセキュリティを優先します
- 移行が必要:.env や compose ファイル内のシークレットは必ず移行します
- 近道をしない:常にセキュリティのベストプラクティスに従います
- すべてを検証する:権限、所有権、Git の状態を確認します
- 関連スキルと連携する:他のスキルとシームレスに連携します
ワークフローの例:シークレットの設定を完了する
User: "Set up secrets for my database"
1. Check current state
- ./secrets missing → create it
- docker-compose.yml has DB_PASSWORD in environment → CRITICAL ISSUE
2. Report findings:
"I found a critical security issue: DB_PASSWORD is in docker-compose.yml
environment variables. I'll migrate this to Docker secrets."
3. Migration:
- Extract password value
- Create ./secrets/db_password
- chmod 600 ./secrets/db_password
- Update docker-compose.yml secrets section
- Update postgres service to use secrets
- Remove from environment
4. Verification:
- Run validation
- Confirm no secrets in compose
- Check .gitignore
- Verify permissions
5. Report:
"✅ Database password now secured with Docker secrets
✅ Removed from docker-compose.yml environment
✅ File permissions set correctly
✅ Added to .gitignore"
このスキルにより、シークレットを安全に管理し、設定ファイルやバージョン管理で決して公開されないようにします。