1. はじめに
Qiitaや技術ブログの投稿等の情報発信を推奨している組織は多いと思いますが、そういった発信を行うことはセキュリティ事故のリスクと隣り合わせでもあります。新サービスを触ってみた系の記事なら問題になることは少ないと思いますが、「価値のある情報を発信したい」と思うと、自分の経験に基づいた内容となり、機微な情報が含まれるリスクが高まります。
AWSを例に挙げると、リソース構成を見せようとコンソール画面のスクリーンショットを投稿した際、アカウントIDやAccessKeyが写り込んでしまったケースです。当然これは、クラウドだけでなくアプリケーションのコード、IPアドレス、顧客固有の識別子などは、外部公開してはいけない情報です。せっかくの発信が事故に繋がると目も当てられません。
こうなると、投稿前に「慎重なレビュー」が必要になりますが、投稿までのプロセスを縛ると以下のような問題が発生して、発信者のモチベーションを削ぎ、「情報発信をやりたがらなくなる」というのはよく聞く失敗例です。
- 書きたいものが書けない
- レビュー待ちのリードタイムが長い
これを踏まえると、情報発信を成功させる鍵は「エンジニアが自由に発信できる」ことで、そのためには「投稿フローの負荷やリードタイムは減らしたい。でも、セキュリティは絶対に担保したい。」という矛盾を解決しなければなりません。
私なりにこの矛盾を解決方法を考えた結果、人によるチェックではなく、簡単にチェック出来る「仕組み」作りが必要だと考えました。今回、「エンジニアの自由度を落とさずに事故を防ぐことを実現し、執筆者の心理的ハードルを下げる」を目的に、AWSを使って「Qiita投稿前チェックツール」を作りました。本記事では、そのツールの内容をご紹介します。
2. 機能概要
ツールの機能は極めてシンプルです。利用者は以下のステップでチェックを行います。
- URLの入力:公開前(限定共有状態)のQiita記事URLを入力します
- オプション設定:ホワイトリスト(除外設定)やプロジェクト固有の「カスタム検出文字列」を入力出来ます
- ツールを実行:記事本文と画像を自動取得し、機微な情報が含まれていないかをチェックします
- 結果表示:結果を画面に表示します、必要に応じて、エビデンス用のPDFダウンロードやメール通知も可能です
あくまでも「ガチガチの検閲」ではなく、投稿前の「機械的なセルフチェック」という立ち位置です。執筆者が心理的な負担を感じず、気軽にサクッと使えるシンプルさを追及しました。
3. システム構成
ツール自体がセキュリティホールになっては本末転倒なため、「閉じたネットワークで、必要最小限の機能だけを提供する」ことを設計の基本方針としました。
AWSを利用して構成するにあたり、特に以下の3点を重視しました。
- アクセス制限:社外IPからのアクセスを完全に遮断する
- 情報の保護:ツールそのものが情報漏洩の入口にならない構成にする
- コスト管理: 大量実行による予期せぬ高額請求を防止する(レート制限の導入)
3.1. 各レイヤーの詳細
フロントエンド (S3)
- HTML/JavaScript/CSSで構成されたシンプルなWebページを配置
- あえて「静的Webサイトホスティング」機能は使わず、S3の標準オブジェクトURLを利用することで、CloudFrontを置かずにHTTPS通信を利用
- バケットポリシーで以下の制御を実施し、堅牢性を確保
- HTTPS通信のみを許可
- 自社指定のパブリックIPアドレスのみアクセスを許可
APIレイヤー (API Gateway)
- 認証基盤(Cognito等)は介さず、APIキーによるアクセス制御を採用
- リソースポリシーを用いて、ここでも自社指定のパブリックIPアドレス以外からのリクエストを拒否
- 使用計画(レート制限・スロットリング)を設定し、過剰なAPI呼び出しによる高額請求リスクを排除
ロジックレイヤー (Lambda + Rekognition)
- リソースベースポリシーを用いて、API Gatewayからのアクセスのみ許可
- 記事取得: 指定されたQiita記事からテキストデータを抽出
- 画像OCR: Rekognitionを呼び出し、記事内の画像からテキストを抽出
- ダブルチェック: 「記事本文」と「画像内の文字」の両方に対して、正規表現を用いてマルチクラウド(AWS/Azure/GCP)の認証情報やプライベートIP、機密キーワードを検知
通知レイヤー (SES)
- チェック完了後、任意で結果をメール通知
4. AI Agentとの「仕様駆動開発」
今回はアプリケーション開発の効率化と、最新のAI Agentによるコーディング体験を兼ねて、フロントエンドからLambdaの実装までGitHub Copilotをフル活用しました。今流行りの「仕様を伝えればコードが出力される」仕様駆動開発の実践です。
最初は、構成案を伝えて仕様を検討するところからスタートしました。仕様が固まるとAIに設計案を起こしてもらい、それを元にコーディングを進めます。AIの生産性は凄まじく、みるみるうちに機能が実装されていきました。
一方で、途中から「コードの増殖スピードに人間のレビューが追いつかない」という、昨今様々なところで聞く悩みに直面しました。
これは個人の反省ですが、仕様駆動開発を意識し切れておらず、機能を細かく分割せずに複数の機能を一気に実装させてしまったことが原因だったと考えています。本来の「仕様駆動」であれば機能を細分化して段階的に実装すべきところを、どんどんコードが出来るのが楽しくなり、「いけるだろう」と複数機能をまとめて依頼した結果、以下のような事象が発生しました。
- コードが増えるにつれ、全体のロジックを人間が把握しきれなくなる
- 意図しない「豪華すぎる(不要な)機能」が勝手に実装される
- 小さな修正のつもりが、AIの提案によって思わぬ方向へロジックが書き換わる
「機能単位で実装してレビュー」というフローを愚直に繰り返していれば、コード量も把握しやすく、レビューも回せたはずです。元々インフラ経験が中心の私にとって、アプリ開発の勉強も兼ねた取り組みでしたが、AI Agentという「超高速な道具」を使いこなす匙加減の難しさを痛感しました。
今回の経験からも、AI Agentは「全自動の実装機」ではなく「優秀だが指示が必要な部下」として扱うべきと感じました。次回はこの教訓を活かし、より「対話」を重視した開発に挑みたいと思います。
5. チェック内容
Lambdaでのチェックロジックは、主に正規表現を用いて実装しています。「万が一にも漏らしてはいけない情報」を中心に、主要な3大クラウド(AWS/Azure/GCP)の認証情報や、組織固有の機密情報をカバーするようにしました。
スキャン対象となる主な項目は以下の通りです。
| カテゴリ | チェック項目 |
|---|---|
| AWS | アカウントID、ARN、AccessKey、SecretAccessKey、セッショントークン、各種エンドポイント |
| Azure | サブスクリプションID、テナントID(GUID形式)、クライアントシークレット、ストレージキー(AccountKey)、SASトークン、Key Vault URI、Storage Account URL、マネージドID |
| GCP | プロジェクトID、サービスアカウント(メールアドレス形式)、Cloud Storage URL(gs://...) |
| その他 | IPアドレス、カスタム文字列(顧客名やプレフィックス等) |
なお、正規表現ベースのチェックという性質上、以下の点を運用の前提としています。
- 誤検知への許容
文脈によっては機密情報ではない文字列を検知してしまう場合もありますが、本ツールは「自動で投稿を止める」ものではなく、あくまで「投稿前に本人が気づくためのセーフティネット」として位置づけています。 - 柔軟なカスタマイズ
2章の「オプション設定」で触れた通り、プロジェクトごとに異なる「出してはいけないキーワード」を動的に追加できるようにし、検知精度と利便性のバランスを取っています。
6. 導入後の反響と反省点
Amazon Inspectorによるコードスキャンやテストを経てツールを組織に展開したところ、非常にポジティブな反響を得ることができました。
「このツールがあるおかげで安心して投稿できる」、「Qiita投稿前のセルフチェックとして標準ルールにしよう」と言った意見を頂き、当初の狙い通り「レビューのためのツール」ではなく「情報発信を後押しする補助ツール」として受け入れて貰えたことに安心しました。
具体的には、以下の3点が刺さったようです。
- 低負荷: URLを入力するだけなので、執筆者の作業を邪魔しない
- 自由度の維持: 機械的なチェックに留めることで、記事の内容(書き味)に干渉しない
- 即時性: レビュー待ちの時間をゼロにし、書きたい熱量が冷めないうちに結果が出る
一方で、今回の実装ではやりたかったのに実装出来なかった点もあります。当初は正規表現だけでなく、Amazon Bedrockを使ったLLMによる文脈チェックの実装も計画していましたが、今回はこのツールを実装していたアカウントの制約等により見送りとなりました。
正規表現によるチェックは高速ですが、やはり「文脈」を読み取るには限界があります。誤検知をさらに減らし、より高度な機密検知を実現するためには、生成AIによるダブルチェックが不可欠だと考えています。
今後、Amazon Bedrockの利用環境が整い次第、ツールをアップデートする予定です。これからも「エンジニアが安心して、より自由に知見を発信できる仕組み」を、作っていきたいと思います。
We Are Hiring!
