2
2

Secretlintでリポジトリに対して共通的な制限を設ける

Posted at

はじめに

本手順で紹介しているコードは、azu さんが作成したコードから Notion や 1password の利用を取り除いただけのコードです。
本記事を投稿するにあたって、このような利用方法があると視野を広げてくれた azu さんに感謝の言葉を送ります。

Secretlint とは

  • Scanner: プロジェクト内の credentials 情報が見つけ報告
  • Project Friendly: 簡単にプロジェクトに導入でき、CI サービスにも利用可能
  • Pre-Commit Hook: credentials 情報のコミットを防止
  • Pluggable: カスタムルールで柔軟な構成の作成が可能
  • Documentation: ルールの検出理由を説明

Demo

簡単なデモがありますのでこちらをご覧ください。

導入手順

前提

Secretlint には 2 つの導入手順があります。
一つは Docker を利用する方法です。もう一つは、Node.js を利用する方法です。

Docker を利用する場合、コミットする度にコンテナを起動することになるのでリソースも取られたりとメリットを感じられなかったので Node.js の利用を選びました。Node.js を入れていなかったりこの辺りわからない人であれば、Docker の方が良いかもしれません。

Node.js の場合、現在で必要とされているバージョンは 18+ です。

公式のドキュメントには「グローバルインストールすると、個々のリポジトリに対するカスタマイズができなくなるのでおすすめしない」とありますが、私としてはグローバルに全ての認証情報は弾いて欲しいのでグローバルインストールしたいと思います。

ただプロジェクトによっては nodenv などでバージョンを変えますし、その度 global となる package を認識させるのは手間ですので、特定のディレクトリを作成し、その中に secretlint をインストールし実行させる手法を取りたいと思います。

githooks について

git には githooks という機能が備わっています。core.hooksPathにデフォルトで $GIT_DIR/hooks が入ってます。これを任意のディレクトリに書き換えれば、グローバルに githooks を動かせるのですがそれをするとリポジトリ内に定義している githooks を呼び出すことができません。

手順

  1. hooks を置く特定のディレクトリを作成する
  2. 作成したディレクトリにて package.json を作成し、secretlint をインストールする
  3. secretlint の設定をする
  4. hooks させるコードを展開する
  5. gitconfig コマンドで hooks させるディレクトリへのパスを指定する
  6. 動作確認

hooks を置く特定のディレクトリを作成する

ディレクトリを作成してください。

mkdir /path/to/git-hooks

作成したディレクトリにて package.json を作成し、secretlint をインストールする

npm initして適当なpackage.jsonを生成します。
生成できたら、secretlint をインストールします。secretlint 自体には rules が内包されていないためこちらも合わせてインストールします。

npm install secretlint @secretlint/secretlint-rule-preset-recommend

secretlint の設定をする

secretlint に使用するルールを適用するために、.secretlintrc.jsonを作成し、コードを適用します。

{
  "rules": [
    {
      "id": "@secretlint/secretlint-rule-preset-recommend"
    }
  ]
}

hooks させるコードを展開する

hooks ディレクトリを作成し、ファイルを生成します。

mkdir hooks
cd hooks
touch _local-hook-exec  applypatch-msg  commit-msg  post-commit  post-update  pre-applypatch  pre-commit  pre-merge-commit  pre-push  pre-rebase  pre-receive  prepare-commit-msg  update

_local-hook-execに以下をペースト

#!/bin/bash
declare GIT_ROOT=$(git rev-parse --show-superproject-working-tree --show-toplevel | head -1)
declare HOOK_NAME=$(basename "$0")
declare LOCAL_HOOK="${GIT_ROOT}/.git/hooks/${HOOK_NAME}"
declare LOCAL_HOOK_ALT="${GIT_ROOT}/.githooks/${HOOK_NAME}"
# Prefer project's hook than global hooks
if [ -e "$LOCAL_HOOK" ]; then
    $LOCAL_HOOK
    export LOCAL_HOOK_IS_CALLED=1
fi
if [ -e "$LOCAL_HOOK_ALT" ]; then
    $LOCAL_HOOK_ALT
    export LOCAL_HOOK_IS_CALLED=1
fi

pre-commitに以下をペースト

#!/bin/bash
source $(dirname "${0}")/_local-hook-exec
declare scriptDir=$(cd $(dirname $0) || exit;pwd)
declare parentDir="$(dirname "${scriptDir}")"
declare HAS_NOT_NODE;
# if "NO_SECRET" is defined, skip secretlint
if [[ -n "${NO_SECRET}" ]]; then
  exit 0
fi
HAS_NOT_NODE=$(command -v node || echo "not found")
if [[ "${HAS_NOT_NODE}" == "not found" ]]; then
  exit 0
fi
# Secretlint
declare FILES
FILES=$(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g' | sed 's|\[|\\\\[|g' | sed 's|\]|\\\\]|g')
[ -z "$FILES" ] && exit 0
echo "  ▶ Check credentials by secretlint"
if [ -f "$PWD/.secretlintignore" ]; then
    echo "$FILES" | xargs "${parentDir}/node_modules/.bin/secretlint" --secretlintignore "$PWD/.secretlintignore" --secretlintrc "${parentDir}/.secretlintrc.json"
else
    echo "$FILES" | xargs "${parentDir}/node_modules/.bin/secretlint" --secretlintrc "${parentDir}/.secretlintrc.json"
fi
RET=$?
if [ $RET -eq 0 ] ;then
    exit 0
else
    exit 1
fi

その他全ては下記を書き込みます。

#!/bin/bash

source $(dirname ${0})/_local-hook-exec

が、hooks ディレクトリ内にinit.shなど任意のファイル名で作成し、以下のコードを実行すると手間がなく良いかと思います。

#!/bin/bash

# 書き込む内容
content="#!/bin/bash

source \$(dirname \${0})/_local-hook-exec"

# 書き込むファイルのリスト
files=("applypatch-msg" "commit-msg" "post-commit" "post-update" "pre-applypatch" "pre-merge-commit" "pre-push" "pre-rebase" "pre-receive" "prepare-commit-msg" "update" )

# 各ファイルに内容を書き込む
for file in "${files[@]}"
do
  echo "$content" > "$file"
done
pwd # /path/to/git-hooks/hooks
sh init.sh

権限を付与する

hooks に権限を付与しましょう

pwd # /path/to/git-hooks
chmod -R +x $(pwd)/hooks

gitconfig コマンドで hooks させるディレクトリへのパスを指定する

あらかじめリポジトリのパスに入っておくと設定が楽です。

pwd # /path/to/git-hooks
git config --global core.hooksPath $(pwd)/hooks

.gitconfigに設定されてるか確認しましょう。

git config --global core.hooksPath
# /path/to/git-hooks/hooks

cat ~/.gitconfig
# [core]
#     hooksPath = /path/to/git-hooks/hooks

動作確認

secretlint のデモにもあるこちらをテキストとして保存してコミットしようとしてみてください。
エラーが表示されれば動作しています。

# Secretlint Demo

URL: https://user:pass@example.com

GitHub Token: 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

SendGrid: "SG.APhb3zgjtx3hajdas1TjBB.H7Sgbba3afgKSDyB442aDK0kpGO3SD332313-L5528Kewhere"

AWS_SECRET_ACCESS_KEY = wJalrXUtnFEMI/K7MDENG/bPxRfiCYSECRETSKEY

Slack:
xoxa-23984754863-2348975623103
xoxb-23984754863-2348975623103
xoxo-23984754863-2348975623103

Private Key:

-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCYdGaf5uYMsilGHfnx/zxXtihdGFr3hCWwebHGhgEAVn0xlsTd
1QwoKi+rpI1O6hzyVOuoQtboODsONGRlHbNl6yJ936Yhmr8PiNwpA5qIxZAdmFv2
tqEllWr0dGPPm3B/2NbjuMpSiJNAcBQa46X++doG5yNMY8NCgTsjBZIBKwIDAQAB
AoGAN+Pkg5aIm/rsurHeoeMqYhV7srVtE/S0RIA4tkkGMPOELhvRzGmAbXEZzNkk
nNujBQww4JywYK3MqKZ4b8F1tMG3infs1w8V7INAYY/c8HzfrT3f+MVxijoKV2Fl
JlUXCclztoZhxAxhCR+WC1Upe1wIrWNwad+JA0Vws/mwrEECQQDxiT/Q0lK+gYaa
+riFeZmOaqwhlFlYNSK2hCnLz0vbnvnZE5ITQoV+yiy2+BhpMktNFsYNCfb0pdKN
D87x+jr7AkEAoZWITvqErh1RbMCXd26QXZEfZyrvVZMpYf8BmWFaBXIbrVGme0/Q
d7amI6B8Vrowyt+qgcUk7rYYaA39jYB7kQJAdaX2sY5gw25v1Dlfe5Q5WYdYBJsv
0alAGUrS2PVF69nJtRS1SDBUuedcVFsP+N2IlCoNmfhKk+vZXOBgWrkZ1QJAGJlE
FAntUvhhofW72VG6ppPmPPV7VALARQvmOWxpoPSbJAqPFqyy5tamejv/UdCshuX/
9huGINUV6BlhJT6PEQJAF/aqQTwZqJdwwJqYEQArSmyOW7UDAlQMmKMofjBbeBvd
H4PSJT5bvaEhxRj7QCwonoX4ZpV0beTnzloS55Z65g==
-----END RSA PRIVATE KEY-----

お疲れ様でした。これで認証コードをコミットする前に防げますね。
しかしこれで万全というわけではないので、随時アップデートするようにしましょう。

出典

https://github.com/secretlint/secretlint

https://github.com/azu/git-hooks

global な git-hooks を設定して、すべてのリポジトリで共有の hooks を使う - Qiita

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2