設定ファイルをAIへ渡す前に秘密情報を **** へ自動マスクするBashスクリプト

Linux・CLI・DevOpsカテゴリを表すパンダのイラスト Linux・CLI・DevOps

この記事について
この記事は、生成AIを活用しながら公式情報と一次情報を確認して整理しています。

検証ステータス:🧪 構文・ロジック確認済み
Linux / GNU Bash環境で、ダミーの秘密情報を使った構文・変換テストを実施しています。実際の設定ファイルへ適用する前に、自分の環境でも確認してください。

設定ファイルをAIへ渡す前に、秘密情報を機械的にマスクする工程を入れておくと、手作業だけに頼るより消し忘れを減らせます。ただし、自動マスクは「最後の確認を不要にする仕組み」ではありません。機械処理と人間の目視を組み合わせる前提で使います。 、元ファイルを変更せず、マスク済みの別ファイルを作るBashスクリプトを作ります。

このスクリプトで守りたいこと

対象にするのは、設定ファイルに入りやすい次のような値です。

  • password / passwd

  • token

  • api_key / api-key

  • secret / client_secret

  • access_key

  • URL内の user:password@

  • PEM形式の PRIVATE KEY 本文

一方で、独自のキー名や複雑なJSON/YAMLまで完全に判定できるとは考えません。

flowchart LR
    A[元の設定ファイル] -->|読み取り| B[mask-secrets.sh]
    B --> C{秘密情報らしいか}
    C -->|Yes| D[値を **** に置換]
    C -->|No| E[そのまま出力]
    D --> F[.masked ファイル]
    E --> F
    F --> G[機械チェック]
    G --> H[人間が目視]
    H --> I[AIへ渡す]

元ファイルを上書きしない

安全側に倒すため、このサンプルは入力ファイルを書き換えません。

app.conf
  ↓ 読み取り
mask-secrets.sh
  ↓
app.conf.masked

マスク処理にバグがあっても、元の設定ファイルまで壊さないためです。また、同名の .masked が存在する場合も上書きせず停止します。

Bashスクリプト

mask-secrets.sh として保存します。

#!/usr/bin/env bash

set -euo pipefail

if [[ $# -ne 1 ]]; then
  echo "Usage: $0 <config-file>" >&2
  exit 2
fi

input=$1
if [[ ! -f "$input" ]]; then
  echo "ERROR: file not found: $input" >&2
  exit 2
fi

output="${input}.masked"
if [[ -e "$output" ]]; then
  echo "ERROR: output already exists: $output" >&2
  exit 3
fi

umask 077
tmp=$(mktemp "${output}.tmp.XXXXXX")
trap 'rm -f "$tmp"' EXIT

awk '
BEGIN { in_private_key = 0 }
{
  line = $0

  if (line ~ /-----BEGIN ([A-Z0-9 ]+ )?PRIVATE KEY-----/) {
    print line
    print "****"
    in_private_key = 1
    next
  }

  if (in_private_key) {
    if (line ~ /-----END ([A-Z0-9 ]+ )?PRIVATE KEY-----/) {
      print line
      in_private_key = 0
    }
    next
  }

  gsub(/:\/\/[^\/:@[:space:]]+:[^@\/[:space:]]+@/, "://****:****@", line)

  lower = tolower(line)
  if (lower ~ /^[[:space:]]*(export[[:space:]]+)?[a-z0-9_.-]*(password|passwd|token|api[_-]?key|secret|client[_-]?secret|access[_-]?key)[a-z0-9_.-]*[[:space:]]*[:=]/) {
    eq = index(line, "=")
    co = index(line, ":")

    if (eq == 0) sep = co
    else if (co == 0) sep = eq
    else if (eq < co) sep = eq
    else sep = co

    print substr(line, 1, sep) " ****"
    next
  }

  print line
}
' "$input" > "$tmp"

chmod 600 "$tmp"
mv "$tmp" "$output"
trap - EXIT

printf 'Created: %s\n' "$output"

umask 077 を設定してから一時ファイルを作り、最後に chmod 600 を適用しています。目的は、マスク途中のファイルを他ユーザーから読まれにくい状態で扱うことです。

ダミーデータで確認する

本物のパスワードやAPIキーは使わず、テスト専用の値で確認します。

cat > demo.conf <<'EOF'
host=localhost
password = dummy-password
API_KEY: dummy-api-key
export ACCESS_TOKEN=dummy-token
url=https://alice:dummy-pass@example.com/api
note=keep-this-line
-----BEGIN PRIVATE KEY-----
DUMMY-PRIVATE-KEY-BODY
-----END PRIVATE KEY-----
EOF

chmod +x mask-secrets.sh
bash -n mask-secrets.sh
./mask-secrets.sh demo.conf
cat demo.conf.masked

想定される出力です。

host=localhost
password = ****
API_KEY: ****
export ACCESS_TOKEN= ****
url=https://****:****@example.com/api
note=keep-this-line
-----BEGIN PRIVATE KEY-----
****
-----END PRIVATE KEY-----

既知のダミー値が残っていないかも確認できます。

grep -En 'dummy-password|dummy-api-key|dummy-token|dummy-pass|DUMMY-PRIVATE-KEY-BODY' demo.conf.masked

何も表示されなければ、今回用意したダミー秘密文字列は残っていません。ただし、未知の秘密情報まで存在しないことを証明したわけではありません。

自動マスクだけでは足りない理由

秘密情報の名前はシステムごとに異なります。たとえば credential、bearer、private_token、独自の変数名などは、このサンプルの正規表現では漏れる可能性があります。

flowchart TB
    A[自動マスク] --> B[既知の秘密文字列をgrep]
    B --> C[差分と本文を目視]
    C --> D{怪しい値が残る?}
    D -->|Yes| E[ルールを追加して再実行]
    E --> A
    D -->|No| F[必要な範囲だけAIへ渡す]

JSONやYAMLなど構造が重要な形式では、単純な行処理ではなく jq や yq など専用パーサーを使う方が安全な場合があります。

AIへ渡す情報自体を減らす

マスクと同じくらい重要なのが「必要な部分だけ渡す」ことです。設定ファイル全体を送る必要がないなら、問題の再現に必要なセクションだけ切り出します。

安全性は次のような多層構造で考えます。

flowchart LR
    A[必要範囲だけ抽出] --> B[秘密情報をマスク]
    B --> C[機械チェック]
    C --> D[人間が確認]
    D --> E[AIへ送信]

まとめ

  • 元ファイルを変更せず、マスク済みコピーを作る

  • 一時ファイルの権限も作成時から制限する

  • 自動検出を100%とは考えず、既知値のチェックと目視を残す

  • 複雑な構造化データは専用パーサーを検討する

  • AIへ渡す情報量そのものも必要最小限にする

公式情報・一次情報

GNU Bash Reference Manual
https://www.gnu.org/software/bash/manual/bash.html

GNU Awk User’s Guide
https://www.gnu.org/software/gawk/manual/gawk.html

OWASP Secrets Management Cheat Sheet
https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。

コメント

タイトルとURLをコピーしました