ローカル開発のシークレット設定を自動化する ── Go × AWS Secrets Manager

LayerX Tech Advent Calendar 2025の9日目の記事です。
バクラク事業部 ソフトウェアエンジニアの @upamune です。
今日は、ローカル開発のシークレット設定をいい感じにした話をします。
ローカル開発環境のシークレット設定、手動でやっていませんか?
「シークレットは1Passwordにあるので設定してください」
開発環境のセットアップでこのようなことを言った・聞いたことがある人も多いのではないでしょうか。APIキーなど、ローカル開発でシークレットの設定が必要なことがあります。
この記事では、AWS Secrets Manager と Go の struct tags を組み合わせて、ローカル開発時のシークレット設定を自動化した仕組みを紹介します。シークレットを手動で設定する手間をなくし、開発体験を向上させることが目的です。
背景・課題
私たちのチームでは、バックエンドサービスを Go で開発しています。マイクロサービス的な構成で多くのサービスがあり、インフラは AWS を利用しています。ローカル開発でも aws sso login で認証する開発フローになっています。
ローカル開発でシークレットを扱う方法はいくつかあります。よくあるのは以下のようなパターンです。
- 1Passwordなどのパスワードマネージャーからコピペして環境変数や
.envに設定する - 1Password CLI の inject 機能を使う
これらの方式はどれも動くのですが、運用していると課題が出てきます。
コピペ方式では、新しいメンバーが入るたびに「1Passwordの〇〇を見てね」という説明が必要です。シークレットが増えるたびにドキュメントの更新も必要になります。そして、シークレットを更新した場合は再度コピペしてもらう必要があります。普段は使わないけど必要なときに動かしたいサービス、例えば Slack 通知やメール送信を担当するサービスは、いざ動かそうとするとシークレットの設定が必要で面倒です。
1Password CLI の inject は便利ですが、起動するたびに例えば MacBook Pro だと TouchID を求められます。起動するたびではなくどこかに一度書き込んでおく場合は、キーが追加・更新されたときに再 inject が必要ですが、そのタイミングが自明ではありません。結果として「シークレットが古くて動作しない」→「再 inject する」という流れが残ります。
最近 1Password には .env ファイルを直接扱えるベータ機能があり、これを使えば再 inject のタイミング問題は解決します。ただ、認証プロンプトが出る点は変わりません。セキュリティ上は正しい挙動ですが、開発時に毎回プロンプトが出るのは避けたかったので、別の方法を模索しました。
AWS Secrets Manager + Go struct tags による自動シークレット注入
これらの課題を解決するため、社内向けに Go パッケージを作りました。アプリケーション起動時に AWS Secrets Manager から自動でシークレットを取得して設定するというものです。既に aws sso login で認証する開発フローになっているので、この認証情報を使って AWS Secrets Manager にアクセスします。
ポイントは以下の4つです。
- Go の struct tags で宣言的にシークレットを指定する
- 環境変数が未設定の場合のみ自動取得する(既存の設定を上書きしない)
- ローカル環境でのみ動作する(本番環境では何もしない)
- シークレットはメモリ上にのみ保持し、ファイルには書き出さない
意識したのは、既存の開発フローを変えずに自動的に便利になることです。開発者は今まで通りアプリケーションを起動するだけ。
使う側は何も意識する必要がなく、 aws sso login で認証さえしていれば、アプリケーションを起動するだけでシークレットが設定されます。共通で設定されているシークレットではなく、特定の値で上書きしたい場合は、従来通り環境変数に値を入れておけばそちらが優先されます。
シークレットを宣言的に取得する
設定の struct に localsecret タグを追加するだけです。環境変数からの設定読み込みには kelseyhightower/envconfig ライブラリを使用しており、envconfig タグと併用します。
type Config struct {
DatabaseURL string `envconfig:"DATABASE_URL"`
SendGridAPIKey string `envconfig:"SENDGRID_API_KEY" localsecret:"my-service-sendgrid-api-key-local"`
}
アプリケーションの初期化時に InjectLocalSecret を呼び出します。
var config Config
// 1. envconfig を利用して Config 構造体の値を埋める
envconfig.Process("", &config)
// 2. localsecret タグが設定されていて空文字のシークレットだけAWS Secret Managerから注入する
InjectLocalSecret("my-service", &config)
動作の流れ
-
InjectLocalSecretは struct のフィールドを走査し、localsecretタグを探す - タグが見つかったら、そのフィールドが空かどうかをチェック
- 空の場合のみ、AWS Secrets Manager から値を取得して設定
- 既に値が設定されている場合はスキップ(環境変数の設定を優先)
仕組み自体はシンプルなので、Claude Code を使って簡単に実装しました。社内固有の前提に依存した部分があるため、OSS としては公開していません。
エラーハンドリング
この仕組みは開発体験の向上が目的なので、エラーが発生してもアプリケーションの起動をブロックしません。
- AWS の認証情報がない場合 → 警告ログを出力してスキップ
- シークレットが見つからない場合 → 警告ログを出力してスキップ
起動時のログを見れば、どのシークレットが AWS Secrets Manager から取得されたか確認できます。
[localsecret] [my-service] info: injected local secret for SENDGRID_API_KEY (secret: my-service-sendgrid-api-key-local) from AWS Secrets Manager
シークレットを登録する
1. AWS Secrets Manager にシークレットを登録する
新しいシークレットは、AWS Secrets Manager に登録します。
共通のタグを付けたり、シークレットの命名規約を守って設定してもらうのが大変なので、AWS Secrets Manager にシークレットをインタラクティブに設定できる社内向け CLI も作成しました。junegunn/fzf で AWS Secrets Manager にシークレットを設定したい対象のサービスを選択し、サフィックスを入力するだけで命名規約に沿った Secret ID が自動生成されます。これにより、間違った名前が設定されることを防げます。この CLI も Claude Code と charmbracelet/huh を使って実装しました。
2. struct に localsecret タグを追加する
設定の struct の該当フィールドに localsecret タグを追加します。
SendGridAPIKey string `envconfig:"SENDGRID_API_KEY" localsecret:"my-service-sendgrid-api-key-local"`
これで、次回以降は起動時に自動でシークレットが設定されるようになります。
既存のシークレットを localsecret 対応する
新規にシークレットを追加する場合は上記の手順で問題ありませんが、既存のシークレットを localsecret 対応させたい場合は、少し面倒です。対象の struct フィールドを探して、AWS Secrets Manager にシークレットを登録して、localsecret タグを追加する、という流れになります。
この作業を楽にするため、Claude Code の Custom Slash Command を用意しました。
チーム内では Claude Code を開発に使っているので、/localsecret-register というコマンドを叩くとインタラクティブに設定できるようにしています。コマンドを実行すると、Claude Code が以下の流れでサポートしてくれます。
- どのサービス・どの設定フィールドを対応させたいか聞いてくる
- リポジトリ内を検索して、該当する struct とフィールドを特定
- 登録用のCLIを利用して、AWS Secrets Manager への登録手順を案内
- 登録後に生成された Secret ID を元に、struct フィールドに
localsecretタグを追加
「SendGrid の API キーを localsecret 対応したい」と伝えると、Claude Code が該当のファイルを探し、CLI の操作手順を教え、最後にコードの修正までやってくれます。自分で grep したり、どのファイルを編集すればいいか探す必要がありません。
Claude Code の Custom Slash Command は、プロジェクト固有の定型作業を自動化するのに便利です。今回のような「リポジトリを検索 → 確認を挟む → 外部ツール操作のガイド → コード修正」という一連の流れをコマンド一発で実行できるようになります。
まとめ
この仕組みを導入してから、「シークレットは1Passwordから〜」という説明が不要になり、新メンバーのオンボーディングがスムーズになりました。久しぶりに使うサービスでもシークレットの設定を気にせず動かせますし、シークレットが更新されても自動で反映されます。一度誰かが AWS Secrets Manager に登録しておけば、以降は全員が恩恵を受けられます。
シークレット管理は地味ですが、開発体験に直結する部分です。今回は Go で実装しましたが、同じ考え方は他の言語やフレームワークでも応用できるはずです。ローカル環境での開発も便利かつセキュアにしていきましょう。

Discussion