OpenClawのビジネス向け環境構築で考える、AIエージェントの倫理とセキュリティ。そしてクローズドループへ
必見の記事

OpenClawのビジネス向け環境構築で考える、AIエージェントの倫理とセキュリティ。そしてクローズドループへ

2026.02.11

OpenClawのビジネス向け環境構築で考える、AIエージェントの倫理とセキュリティ。そしてクローズドループへ

はじめに

OpenClawを仕事で使いたいという思いから、AIアシスタントが常駐する環境を構築しました。その実験と実践の記録です。

自宅のMac miniでDiscordをインターフェースに、音声通話、電話応答、ワークフロー自動化、クラウドインフラ管理まで一通りの機能を持たせています。

基本構築は約3日間、セキュリティ強化は継続的に追加しています。構築過程をテーマ別に整理してまとめます。

主な技術スタックは、OpenClaw、Claude Code、ElevenLabs、Whisper、Twilio、n8n、Terraform、Tailscaleなど。個人開発ですがセキュリティやIaCも手を抜いていません。

動作環境はMac mini(Apple Silicon)、macOS 26.2です。


第1章 導入編

OpenClawとは

OpenClawは、LLMをエージェントとして常駐させるためのフレームワークです。Discordをフロントエンドにして、ファイル操作、シェル実行、Web検索、ブラウザ操作などを統合的に扱えます。

セットアップ手順

まずHomebrewを入れます。

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
echo 'eval "$(/opt/homebrew/bin/brew shellenv zsh)"' >> ~/.zprofile
source ~/.zprofile

次にClaude Codeをインストールします。

npm install -g @anthropic-ai/claude-code
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc

OpenClawのインストール。Node.js関連の依存も全部自動で入ります。

curl -fsSL https://openclaw.ai/install.sh | bash

初回起動(onboardウィザード)

openclaw onboard

聞かれるのは以下の3点です。

  • AIモデルの選択 → anthropic/claude-opus-4-6 を選択
  • 認証 → Claudeにログインしてトークンを取得
  • アシスタントの名前 → 「クロウ」(以降、フロントエンドとなるDiscord/Telegram上のBotをこう呼びます)

claude-opus-4-6 を選んだ理由は、その時点で最も新しく、最も賢いモデルだったからです。深く考えるような仕事にはぴったりのモデルです。

ウィザードが完了するとGatewayデーモンが起動し、SOUL.mdUSER.mdIDENTITY.mdMEMORY.md が自動生成されます。

Gateway started: ws://127.0.0.1:18789 (PID XXXXX)

モデル選定とレスポンス速度のチューニング

初期設定では claude-opus-4-6 を選択しましたが、即レスを求めるような場面には少し合いませんでした。Discordで話しかけてから返答が届くまでに体感で数秒から十数秒かかることがあり、日常的に使うにはもどかしい速度です。また、トークン消費が大きく、コスト面でも他のモデルを検討する必要がありました。

Sonnetならサクサクと普通の会話ができます。ファイル操作やWeb検索のような軽い処理ならHaikuでも十分です。他にもGPTやGeminiなど選択肢はありますが、自然な日本語で会話ができるのはClaudeだと感じたので、Sonnetを通常利用することにしました。深く考える仕事にはOpusを明示的に指定する運用です。

openclaw config.patch <<'EOF'
{
  "models": {
    "default": "anthropic/claude-sonnet-4-20250514"
  }
}
EOF

併せて、簡単な会話では即答するようSOUL.mdに指示を追加し、メモリファイルの読み込み頻度も最小化しました。体感速度はかなり改善しています。

4段階フォールバック設定

Anthropic APIにはレート制限があり、連続でタスクを投げるとリクエストが弾かれることがあります。特にサブエージェントを並行実行する場面で顕著です。

対策として、モデルの4段階フォールバックを設定しました。

{
  "agents": {
    "defaults": {
      "model": {
        "primary": "anthropic/claude-sonnet-4-20250514",
        "fallbacks": [
          "amazon-bedrock/anthropic.claude-sonnet-4-20250514-v1:0",
          "openai-codex/gpt-5.3-codex",
          "google/gemini-pro"
        ]
      }
    }
  },
  "models": {
    "bedrockDiscovery": {
      "enabled": true,
      "region": "us-east-1",
      "providerFilter": ["anthropic"]
    }
  }
}
  1. Sonnet(Anthropic直接API) — メインモデル。通常はこれで処理
  2. Sonnet via Bedrock(Amazon Bedrock) — Anthropic直接APIが制限にかかった場合の第2候補。同じモデルだが経路が異なるためレート制限が別枠
  3. Codex(OpenAI) — Anthropic系が両方ダメな場合の第3候補
  4. Gemini Pro(Google、設定値: google/gemini-pro) — 最終手段

Bedrockの活用がポイントです。OpenClawにはBedrockのモデルを自動検出する bedrockDiscovery 機能があり、リージョンを指定すると利用可能なモデルを自動検出します。加えて、fallbacks 配列にBedrock版モデルを明示的に追加することもできます。自動検出と手動指定の併用が可能です。Anthropicの直接APIがレート制限にかかっても、同じSonnetモデルがBedrock経由で使えるため、ユーザー体験を落とさずに処理を継続できます。

4社のAPIキーをそれぞれ設定しておく必要がありますが、一度設定すれば自動で切り替わります。実運用では、フォールバックが発動するのはサブエージェントを多用したときくらいです。

ペルソナ設定

OpenClawでは、AIの振る舞いをMarkdownファイルで定義します。

  • SOUL.md — AIの性格、話し方、判断基準を記述するファイル。名前は「クロウ」としました。口調や対応方針、やっていいこと・悪いことの境界線をここで定義します。加えて、倫理原則として「他人の名誉を傷つけない」「他人の財産を奪わない」「他人の秘密を暴露しない」「他人の身体を傷つけることに加担しない」を直接・間接を問わず守るよう明記しています。AIが文章を生成したり調査を行う際にも、この原則が判断基準として機能します。
  • USER.md — ユーザー自身の情報。好み、技術スタック、仕事の文脈などを書いておくと、AIが的確に応答できるようになります。
  • AGENTS.md — セッション開始時の行動ルール。「まずSOUL.mdを読め」「メモリファイルを確認しろ」といった手順を定義します。

これらのファイルを整備することで、毎回ゼロから文脈を説明し直す必要がなくなります。セッションが切れても、ファイルベースで記憶と人格が復元される設計です。


第2章 コミュニケーション編

Discordで喋れるようにする

Discord Developer Portalでの手動作業が必要なパートです。ここが一番時間がかかりました。

Discord Bot作成の手順

  1. Discord Developer Portalで New Application → 名前を入力
  2. 左メニュー Bot → Add Bot
  3. Privileged Gateway Intents で MESSAGE CONTENT INTENT を ON
  4. Reset Token → トークンをコピー(一度しか表示されないので注意)
  5. 左メニュー OAuth2 → URL Generator → Scopes: bot + applications.commands → Permissions: View Channels / Send Messages / Read Message History / Add Reactions
  6. 生成されたURLをブラウザで開き、自分のサーバーにBotを招待

OpenClawにトークンを設定

openclaw config.patch <<'EOF'
{
  "channels": {
    "discord": {
      "token": "YOUR_DISCORD_BOT_TOKEN"
    }
  }
}
EOF

設定を反映するにはGatewayを再起動します。

openclaw gateway restart

iPhoneとのペアリング

Discordに入ったクロウにペアリングコードを送ります。自動承認され、iPhoneからDiscord経由でAIアシスタントと会話できるようになります。

Telegramチャネルの追加

Discordだけでなく、Telegram経由でもAIアシスタントにアクセスできるようにしました。マルチチャネル対応にすることで、Discord以外のメッセンジャーからも同じクロウに話しかけられます。

Telegram Botの作成

TelegramのBotFatherで新しいBotを作成します。/newbot コマンドでBot名とユーザー名を指定するだけで、APIトークンが発行されます。

OpenClawへの設定

Telegram連携にはchannelsとpluginsの両方に設定を追加する必要があります。channelsだけ設定してもBotは動きません。

openclaw config.patch <<'EOF'
{
  "channels": {
    "telegram": {
      "enabled": true,
      "botToken": "YOUR_TELEGRAM_BOT_TOKEN",
      "dmPolicy": "pairing"
    }
  },
  "plugins": {
    "entries": {
      "telegram": { "enabled": true }
    }
  }
}
EOF

設定後、Gatewayをリロードするとbotが起動します。

ペアリング

Discordと同様に、Telegramからもペアリングが必要です。Telegram上でBotにメッセージを送ると承認コードが表示されるので、CLIで承認します。

openclaw pairing approve telegram <code>

承認後はTelegramのDMからクロウに直接話しかけられるようになります。Discord側のペアリングとは独立しているので、それぞれ個別に承認が必要です。

使い勝手

DiscordとTelegramのどちらから話しかけても、同じAIアシスタントが応答します。レスポンス速度もほぼ同じで、体感できる差はありません。ボトルネックはLLM APIの推論時間なので、チャネルの違いは誤差の範囲です。

Discordはデスクトップ作業中に、Telegramはモバイルでサッと確認したいときに、という使い分けをしています。

音声機能の実装 — TTS・文字起こし・モデル選定

ElevenLabs TTSとクローンボイス

テキスト読み上げにはElevenLabsを使っています。特徴的なのは、自分の声をクローンしている点です。ElevenLabsの音声クローン機能で自分の声を登録し、AIが応答する際にその声で読み上げるようにしました。

最初はmacOS標準の say コマンドを試しましたが、0バイトのファイルが生成される問題が発生しました。ElevenLabsのAPIに切り替えて解決しています。

openclaw config.patch <<'EOF'
{
  "messages": {
    "tts": {
      "provider": "elevenlabs",
      "elevenlabs": {
        "apiKey": "YOUR_ELEVENLABS_API_KEY"
      }
    }
  }
}
EOF

OpenClawのTTSスキルにvoiceIdを設定するだけで、すべての音声出力がクローンボイスになります。

Whisperによる音声文字起こし

音声入力の文字起こしにはOpenAIのWhisperを使っています。

brew install ffmpeg
pip3 install openai-whisper

モデル別の検証結果です。

  • base / CPU — 約1秒。精度がやや低い
  • large / CPU (FP32) — 数分。精度は高いが遅すぎる
  • large / MPS (Apple Silicon GPU) — 約14秒。短い音声で無言失敗する問題あり
  • medium / CPU (FP32) — 約5秒。精度・速度のバランスが良い

検証時点では mediumモデル + CPU がベストバランスでした。5秒程度で書き起こしが完了し、日本語の精度も実用的です。その後、MLX Whisperの導入でさらに改善しています(後述)。

OpenClawへの設定は以下の通りです。

{
  "tools": {
    "media": {
      "audio": {
        "enabled": true,
        "models": [{
          "type": "cli",
          "command": "/path/to/whisper",
          "args": ["--model", "medium", "--language", "ja",
                   "--output_format", "txt", "{{MediaPath}}"],
          "timeoutSeconds": 60
        }]
      }
    }
  }
}

設定後はDiscordで音声メッセージを送るだけで、テキストに変換された状態でAIに届きます。

MLX Whisper — Apple Silicon最適化

MLX WhisperはApple Silicon向けに最適化されたWhisper実装です。Metal GPUを活用するため、同じMac mini上でも処理速度が大幅に改善します。

large-v3モデルを使って、数十秒の音声を約3.4秒で高精度に文字起こしできています。CPUベースのWhisperでlargeモデルを動かすと数十秒かかっていたことを考えると、大幅な改善です。

導入はpipでインストールするだけです。モデルは初回実行時に自動ダウンロードされます。Apple Siliconを使っているなら、最初からMLX Whisper一択で良いと思います。

音声処理とプライバシー

WhisperもMLX Whisperも完全にローカルで動作します。音声データが外部サーバーに送信されることはありません。これはプライバシーの観点で重要なポイントです。

OpenAIが提供するWhisper APIは外部送信が伴いますが、ここで使っているのはオープンソース版のWhisperをローカル実行しているものです。音声データはMac mini内で処理され、テキスト化された結果だけがLLM APIに渡ります。

業務で音声入力を使う場合、「音声データがどこで処理されるか」は必ず確認すべき点です。外部APIに送信される構成だと、会議内容や通話録音が第三者のサーバーに渡ることになります。

電話連携 — Twilioで着信・発信を自動化する

着信フロー

Twilioで電話番号を取得し、着信時に以下の処理を自動実行するようにしました。

  1. 着信を受けてクローンボイスで応答メッセージを再生
  2. 相手の発話を録音
  3. 録音データをWhisperで文字起こし
  4. 文字起こし結果をDiscordに転送

これにより、電話に出られなくても内容がDiscordに届きます。留守番電話の完全自動化です。

発信フロー

逆方向も実装しています。Discordからメッセージを送ると、Twilioが指定番号に発信し、クローンボイスでメッセージを読み上げます。自分の声で電話をかけるAIという、やや奇妙だが実用的な仕組みです。

インフラ面の工夫

TwilioのWebhookはパブリックURLが必要です。Mac miniは自宅にあるので、cloudflaredトンネルを使ってローカルサーバーを公開しています。

運用上の課題として、cloudflaredのトンネルURLが再起動のたびに変わる問題がありました。これに対して以下の自動化を組みました。

  • LaunchAgent でcloudflaredとローカルサーバーをMac mini起動時に自動起動
  • トンネルURL取得後、Twilio APIを叩いてWebhook URLを自動更新

これで再起動しても手作業なしに電話連携が復旧します。


第3章 開発環境編

Docker環境の構築(Colima)

Docker DesktopではなくColimaを使っています。OSSで、ライセンスの心配がなく、CLIベースで扱いやすい。Mac miniのようなヘッドレス環境には向いています。

brew install colima
brew install docker docker-compose

# VM起動(Apple Silicon最適化)
colima start --cpu 2 --memory 4 --disk 20 --vm-type vz

docker-composeプラグインの設定も必要です。

mkdir -p ~/.docker
echo '{"cliPluginsExtraDirs":["/opt/homebrew/lib/docker/cli-plugins"]}' > ~/.docker/config.json

Claude Codeのコンテナ化

Claude Codeをコンテナ内で動かす方法を試行錯誤した結果、以下のパターンに落ち着きました。

  1. sleep infinityで常駐するコンテナを起動
  2. docker execでコンテナ内に入り、claude -pでタスクを実行

執筆時点では公式Dockerイメージがないため、自前でDockerfileを作成しました。

FROM node:22-bookworm-slim
RUN npm install -g @anthropic-ai/claude-code@2.1.37
ENV PATH="/usr/local/share/.config/yarn/global/node_modules/.bin:$PATH"
ENTRYPOINT ["claude"]

APIキーは .env ファイル経由で注入します。常駐コンテナにexecで入る方式は、起動コストを毎回払わなくて済む点がメリットです。

n8nによるワークフロー自動化

n8nのデプロイ

ワークフロー自動化ツールのn8nはdocker-composeでデプロイしました。永続化ボリュームを設定し、再起動してもワークフローが消えないようにしています。

# docker-compose.yml
services:
  n8n:
    image: n8nio/n8n
    ports:
      - "5678:5678"
    environment:
      - TZ=Asia/Tokyo
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER=admin
      - N8N_BASIC_AUTH_PASSWORD=${N8N_PASSWORD}
    volumes:
      - n8n_data:/home/node/.n8n

パスワードは .env ファイルで管理し、gitにはコミットしません。なお、N8N_BASIC_AUTH_* 環境変数はn8nの新しいバージョンでは非推奨となり、ビルトインのユーザー管理に置き換えられています。

n8nからDocker API経由で呼び出し

n8nのHTTPリクエストノードからDocker APIを直接叩いて、Claude Codeコンテナにタスクを投げる構成にしました。n8nのワークフロー内でコード生成やレビューを自動実行できます。

Human in the Loopワークフロー

最も実用的だったのが、Human in the Loopパターンです。

  1. n8nのワークフローがClaude Codeにコード生成を依頼
  2. 生成結果をレビューフォームとして提示
  3. 人間が内容を確認し、承認または却下
  4. 承認された場合のみ後続処理(デプロイ等)を実行

AIに全自動で任せるのではなく、重要なポイントで人間の判断を挟む設計です。

n8n REST APIとcookie認証の落とし穴

n8nのREST APIを外部から叩く際、認証でハマりました。n8nはデフォルトでcookieベースの認証を使いますが、N8N_SECURE_COOKIEが有効だとHTTPS以外では認証cookieが送信されません。

ローカル環境でHTTPアクセスしている場合は、環境変数でN8N_SECURE_COOKIE=falseを明示的に設定する必要があります。ドキュメントには書かれていない挙動で、ログにもエラーが出ないため原因特定に時間がかかりました。

開発ツール群

Claude Code — コーディングの実行部隊

Claude Codeはclaude -pの非対話モードで使っています。タスクを文字列で渡すと、ファイルの読み書き、コマンド実行まで含めて自律的に作業してくれます。

OpenClaw(クロウ)がユーザーとの会話・タスク分解・成果物レビューを担当し、Claude Codeが実際のコーディング・テスト・ビルドを担当します。「TODOアプリ作って」と言えば、クロウが要件を整理してClaude Codeに投げ、結果を確認して返してくれます。

OpenClawからの呼び出し、n8nワークフローからの呼び出し、直接CLIでの利用と、複数の経路で使い分けています。

Codex CLI — セカンドオピニオン

OpenAIのCodex CLIをセカンドオピニオンとして使っています。GPT系のモデル(GPT-5.3-Codex)でコードレビューを行い、Claude Codeの出力とクロスチェックします。Claude Codeが書いたコードを同じモデルにレビューさせても、同じバイアスが残るためです。

brew install --cask codex
codex login  # ChatGPTアカウントでログイン

diffベースでレビューできるので、「直前のコミットをレビューして」という使い方が便利です。

codex review --base HEAD~1

異なるモデルの視点を入れることで、片方が見落とすパターンを拾えます。

実際のレビュー結果

TODOアプリのソースコードをCodexにレビューさせたところ、以下の指摘がありました。

  1. タイムゾーンバグ: new Date('YYYY-MM-DD') がUTC解釈されて日付が1日ズレる可能性。parseISO に統一すべき
  2. 完了日の集計ミス: 週間完了数が updatedAt に依存しており、完了後の編集でもカウントされる。completedAt フィールドの追加が必要
  3. LocalStorageのバリデーション不足: 壊れたデータで実行時エラー。zodでスキーマ検証を入れるべき
  4. テーマ切替でクラス破壊: className = ... で全クラスを上書き。classList.toggle に修正すべき
  5. テスト不足: フィルタ・ソート・永続化にVitestでテスト追加すべき

タイムゾーンバグのような実運用で踏む問題を事前に発見できました。

運用フロー
  1. Claude Codeで成果物を作る
  2. Codexでレビュー(codex exec "レビューして" or codex review --base HEAD~1
  3. 指摘事項をClaude Codeで修正

Codex CLIによるレビュー運用

OpenAIのCodex CLIは、コードレビューの用途で導入しました。ただし、使い方によって結果が大きく変わります。

codex exec "このMarkdownをレビューして" のように全文を読ませるやり方は、長文ドキュメントだとタイムアウトして完走しません。一方、diffベースのレビューは安定して動作します。

# 直近3コミットの差分をレビュー
codex review --base HEAD~3

# 未コミットの変更をレビュー
codex review --uncommitted

実際の運用では、Opusで全体レビューを行い、Codexでdiffレビューを行うダブルチェック体制にしています。Opusは文脈を踏まえた構成・内容の指摘が得意で、Codexは差分に対する具体的な修正提案が得意です。両者の視点が異なるため、片方では見落とす問題をもう片方が拾うケースが多くあります。

実績として、ある分析レポート(3ファイル計800行超)のレビューでは、Opusが10項目、Codexが4件の修正を検出し、合計14件の改善を行いました。

PDF分析ワークフロー

PDFの分析をAIに任せるために、poppler(pdftotext)を導入しました。

brew install poppler

PDFを直接AIに渡すと、CIDフォント(日本語PDFに多い)を含むファイルはサンドボックス環境で正しく読めないことがあります。事前にテキスト抽出しておけば、この問題を回避できます。

# PDFからテキストを抽出
pdftotext input.pdf output.txt

# レイアウトを保持したい場合
pdftotext -layout input.pdf output.txt

抽出したテキストファイルをOpusのサブエージェントに渡して分析させるのが、現在の標準的なパイプラインです。CIDフォントのPDFでも、テキスト抽出後であれば問題なく分析が完了します。

gog CLI — GmailとGoogleカレンダー操作

Google Workspace CLI(gog)を導入し、AIアシスタントがメール確認やスケジュール参照に使えるようにしました。

brew install steipete/tap/gogcli

GCPでOAuthクライアントを作成し、クレデンシャルを登録します。

gog auth credentials set credentials.json
gog auth add your-email@example.com

OAuth同意画面のテストユーザー設定を忘れると403���ラーになるので注意です。

OpenClawと組み合わせれば「未読メールある?」「今日13時にMTG入れて」と言うだけで実行してくれます。

Puppeteer — スクリーンショット取得

Mac miniはヘッドレスなので、Webページの見た目を確認する手段としてpuppeteerを使っています。puppeteerでモバイルサイズのスクリーンショットを撮影し、Discordに送ることで成果物を視覚的に確認できます。

Playwright — ブラウザ自動化

OpenClawのブラウザ操作機能で内部的に使われています。スクリーンショット取得やDOM操作をヘッドレスで実行できます。

npm install @playwright/test
npx playwright install chromium

Chromiumだけ入れれば十分です。puppeteerと役割が重なりますが、OpenClawとの統合はPlaywright側で行われているため、両方入れています。

xAI Grok API — SNS検索とWeb検索

xAIのResponses APIを使い、Grok経由でX(Twitter)の投稿検索とWeb検索を実行できるようにしました。OpenClawの検索機能を補完する位置づけです。

Responses APIにはビルトインツールとして x_search(X投稿検索)と web_search(Web検索)が用意されています。APIにツール指定付きでリクエストを投げると、Grokがリアルタイムで検索を実行し、結果を要約して返します。

技術的なポイントは以下の通りです。

  • エンドポイント: https://api.x.ai/v1/responses
  • モデル: grok-4-1-fast-reasoning を使用。サーバーサイドツール(x_search、web_search)はgrok-4ファミリー以降のモデルでないと動作しない。grok-3系では非対応
  • 認証: XAI_API_KEY 環境変数でAPIキーを渡す
  • x_searchの絞り込み: allowed_x_handlesfrom_dateto_date などのパラメータで検索対象を制限できる

CLIから手軽に呼べるようにシェルスクリプトを作成しました。

curl -s "https://api.x.ai/v1/responses" \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "grok-4-1-fast-reasoning",
    "tools": [{"type": "x_search"}],
    "input": "検索クエリ"
  }'

x_searchweb_search に差し替えれば、一般的なWeb検索も同じ要領で実行できます。

実際に「OpenClawについてXの投稿を検索して要約」と投げたところ、Grokがリアルタイムで関連投稿を検索し、引用URL付きで要約を返しました。SNS上のリアルタイムな反応を拾えるのは、通常のWeb検索にはない強みです。


第4章 インフラ編

EC2とTailscaleによるゼロトラスト構成

AWSにはEC2インスタンスを1台立てています。スペックはt4g.nano。ARM(Graviton)で、月数ドルの最小構成です。

特徴的なのはセキュリティグループの設定で、インバウンドルールを完全に閉鎖しています。SSH含め、外部からのアクセスは一切許可していません。

aws ec2 revoke-security-group-ingress \
  --group-id sg-XXXXXXXXXXXXXXXXX \
  --ip-permissions '[全ルール]'

代わりにTailscaleを使って、VPN経由でのみアクセスする構成にしています。セキュリティグループが空なので、ポートスキャンされても何も見えません。

AWS CLIのセットアップ

brew install awscli
aws configure

最初はIAM Identity Center(旧SSO)を試みましたが、メンバーアカウントからのセットアップでエラーになったため、暫定的にIAMアクセスキー方式に切り替えました。IAMアクセスキーの長期利用はセキュリティ上推奨されないため、あくまで一時的な回避策です。将来的にはIAM Identity Center経由の一時認証に移行する予定です。現時点ではKeychain連携で平文ファイルを排除する対応を行っています(第5章で詳述)。

EC2にTailscaleを導入

# EC2上で実行
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

SSH接続はTailscale経由で行います。

# ~/.ssh/config
Host my-ec2
  HostName 100.x.x.x
  User ec2-user
  IdentityFile ~/.ssh/my-keypair.pem
  ProxyCommand tailscale nc %h %p

Terraform v1.5.7でIaC化

インフラはTerraformで管理しています。バージョンはv1.5.7を明示的に選んでいます。これはHashiCorpがBSLライセンスに移行する前の、最後のMPL(オープンソース)バージョンです。

# Homebrewのデフォルトでは最新のBSLライセンス版が入るため、
# tfenvでバージョンを固定してインストール
brew install tfenv
tfenv install 1.5.7
tfenv use 1.5.7

MPLライセンスを維持したい場合はこのようにバージョン指定が必要です。OpenTofuへの移行も選択肢にありますが、現時点ではv1.5.7で問題なく動いているのでそのまま使っています。

プロジェクト構成

infra/ ディレクトリに以下の構成で作成しました。

infra/
├── main.tf        # provider設定
├── variables.tf   # 変数定義
├── ec2.tf         # EC2 + セキュリティグループ
└── outputs.tf     # 出力定義

既存リソースのimport

稼働中のEC2とセキュリティグループを terraform import で取り込みました。

terraform import aws_instance.claw_dev i-XXXXXXXXXXXXXXXXX
terraform import aws_security_group.claw_dev_sg sg-XXXXXXXXXXXXXXXXX

importした直後の terraform plan では差分が出ます。2点ハマりました。

AMIの差分: Terraformが最新のAMI IDを参照しようとし、既存インスタンスのAMIと異なるためreplace(再作成)判定になりました。AMI IDを変数化し、既存のAMI IDを指定することで解決しています。

セキュリティグループのdescription: コードに書いたdescriptionと実際のdescriptionが異なるとreplace強制になります。AWS上の既存descriptionに合わせて解決しました。

# 差分ゼロを確認
terraform plan
# No changes. Your infrastructure matches the configuration.

destroy 0を確認してから terraform apply を実行しました。GitHubにはprivateリポジトリとしてpushしています。

Tailscale MagicDNSと固定ホスト名

TailscaleのMagicDNSを有効にすると、Tailnetに接続した各デバイスにDNS名が自動的に割り当てられます。ただし、デフォルトのホスト名はマシン名がそのまま使われるため、長かったり分かりにくかったりします。

固定の短いホスト名を設定しておくと便利です。

tailscale set --hostname=mac-mini

これにより、Tailnet内の他のデバイスから mac-mini という名前でアクセスできるようになります。MagicDNSが有効であれば、完全修飾名でも到達可能です。

SSH configを設定しておけば、EC2への接続もシンプルになります。

Host claw-dev
    HostName claw-dev.<tailnet-domain>.ts.net
    User ec2-user
    IdentityFile ~/.ssh/claw-key.pem
    ProxyCommand tailscale nc %h %p
ssh claw-dev

iPhoneからもTailscaleに接続していれば、ブラウザでFQDN付きのURLを入力するだけでMac mini上のn8nにアクセスできます。VPNで保護されているため、ポートを外部に公開する必要はありません。

二段構えのセキュリティスキャン

IaCのセキュリティには2つのツールを組み合わせています。

  • tfsec — Terraformコードの静的解析。デプロイ前にセキュリティリスクを検出
  • Prowler — AWSアカウントのランタイムCSPM。実際のリソース状態をスキャン

tfsecが「設計図のチェック」、Prowlerが「完成品のチェック」という関係です。両方やることで、コードと実環境のギャップを検出できます。

tfsecの実行

brew install tfsec
tfsec infra/

3件検出されました。

  • CRITICAL: egress 0.0.0.0/0(全宛先許可) → Tailscale通信に必要なためignoreコメントで明示許可
  • HIGH: IMDSv2が未強制 → metadata_options ブロック���追加
  • HIGH: EBSルートボリュームが暗号化されていない → root_block_device ブロックで暗号化を指定

修正後に再実行したところ、全パスしました。

No problems detected!

Prowlerの実行

pip3 install prowler
prowler aws

70チェックを実行し、19件FAIL(HIGH 6, MEDIUM 10, LOW 3)でした。主な対応として、EBSデフォルト暗号化を有効化しました。

aws ec2 enable-ebs-encryption-by-default --region ap-northeast-1

IMDSv2の強制やEBS暗号化はTerraformコードに追加済みです。既存インスタンスへの適用はEC2再作成時になります。

その他のハードニング

  • EBSデフォルト暗号化 — リージョン設定で有効化。新規作成されるEBSボリュームがすべて自動暗号化されます
  • IMDSv2強制 — インスタンスメタデータサービスをv2のみに制限。SSRF攻撃によるクレデンシャル窃取を防ぎます

クラウドコスト管理

AWS Cost Explorer CLIでコストを分析しました。

aws ce get-cost-and-usage \
  --time-period Start=2026-02-01,End=2026-02-10 \
  --granularity DAILY \
  --metrics BlendedCost \
  --group-by Type=DIMENSION,Key=SERVICE

合計 $9.34(月ペースで約$28)でした。内訳は以下の通りです。

  • QuickSight: $3.68
  • EC2: $2.21
  • VPC: $1.03
  • その他: $2.42

AWS Budgetsでアラート設定

月額$50を超えたら通知が飛ぶようにAWS Budgetsを設定しました。80%到達時と100%到達時の2段階でメール通知されます。


第5章 セキュリティ編

この章では、個人開発環境のセキュリティをどこまで真面目にやるか、という問いに対する実践記録をまとめます。結論から言うと、やればやるほど穴が見つかるので、フレームワークを使って体系的に潰していくのが効果的でした。

Mac miniのセキュリティ監査

常駐マシンであるMac mini自体のセキュリティも確認しました。

openclaw security audit --deep

実行したところ、FileVaultはON、Time Machineは設定済みでしたが、ファイアウォールがOFFでした。OpenClawが自動でONに設定しました。

  • FileVault — ディスク暗号化が有効であることを確認
  • ファイアウォール — macOSのアプリケーションファイアウォールを有効化
  • SIP(System Integrity Protection) — 有効であることを確認。カーネル拡張やシステムファイルの改変を防止する仕組みで、無効化は厳禁です
  • 不要なサービスの停止、共有設定の確認

Tailscale VPNによるゼロトラストネットワーク

WireGuardベースのメッシュVPNです。基本的にP2P直接接続で、多くの場合データはTailscale社のサーバーを経由しません。ポート開放が不要で、個人利用は100デバイスまで無料です。

# CLIバージョンをインストール(cask版はsudo必要)
brew install tailscale

# デーモン起動(userspace-networkingモード、root不要)
tailscaled --tun=userspace-networking \
  --state=$HOME/.tailscale/tailscaled.state \
  --socket=$HOME/.tailscale/tailscaled.sock &

# ログイン(ブラウザで認証)
tailscale --socket=$HOME/.tailscale/tailscaled.sock up

ヘッドレス環境ではcask版(GUI)がsudo必要で使えないため、CLI版 + --tun=userspace-networking の組み合わせが適しています。

Tailscaleで以下の3台をメッシュ接続しています。

  • Mac mini(自宅、AIアシスタント常駐)
  • iPhone(モバイルアクセス用)
  • EC2インスタンス(AWS)

すべてのデバイス間通信がWireGuardベースの暗号化トンネルを経由します。パブリックIPを晒す必要がないので、攻撃対象面が大幅に減ります。

ハマりポイント:ファイアウォールとの共存

Tailscale経由でdevサーバーにアクセスしたところ、レスポンスが空(HTTP 000)になりました。macOSファイアウォールがNode.jsへの着信をブロックしていたのが原因で、socketfilterfw --unblockapp で解決しています。

ただし、Node.jsの着信を常時許可しておくのはセキュリティ上望ましくありません。Node.jsに脆弱性が見つかった場合、Tailscale VPN内のデバイスが侵害されていると攻撃経路になり得ます。開発時のみ許可し、終了後はブロックに戻す運用を推奨します。

# 開発時のみ許可
sudo socketfilterfw --unblockapp $(which node)
# 終了後にブロックに戻す
sudo socketfilterfw --blockapp $(which node)

セキュリティ第一原則とAI行動ルール

運用ルールとして「セキュリティ第一原則」を策定しました。具体的には以下のような方針です。

  • 新しいサービスを追加する前にセキュリティ影響を評価する
  • 認証情報はファイルに書かず、環境変数または専用の秘密管理を使う
  • 公開エンドポイントは最小限にする
  • 判断に迷ったら安全側に倒す

AIアシスタントのSOUL.mdにもこの原則を組み込み、AIが判断する際にもセキュリティを優先するようにしています。

OpenClawではAIの行動ルールを TOOLS.mdMEMORY.md にファイルとして書きます。口頭で伝えたルールはセッションが変わると忘れますが、ファイルは永続します。

設定した鉄則は以下の通りです。

  • クレデンシャルファイルの直接読み取り禁止(CLIツール経由は可)
  • クレデンシャルの外部送信禁止(git push、API、チャット等あらゆる手段)
  • GitHubリポジトリは必ずprivate
  • パスワード・トークンは絶対にコミットしない
  • 外部アカウント作成・購入は事前確認
  • 外部システムへの書き込み・削除は事前確認
  • ファイル削除は rm 禁止、trash を使用

macOS自動アップデートの有効化

常駐マシンのOSを最新に保つことは基本中の基本です。macOSの自動アップデート設定を確認したところ、セキュリティアップデートの自動インストールが無効になっていました。

sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate AutomaticallyInstallMacOSUpdates -bool true
sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate CriticalUpdateInstall -bool true

これにより、重要なセキュリティパッチが自動適用されます。CIS Controls v8のControl 4(セキュア設定)の要件を満たすための基本対策です。

秘密情報のmacOS Keychain一元管理

セキュリティフレームワークの策定過程で、秘密情報の管理に大きな問題があることが分かりました。APIキーやトークンが ~/.zshrc に平文で書かれていたのです。シェルを開くたびにexportされる便利さはありますが、セキュリティ上は最悪の状態です。

対策として、すべての秘密情報をmacOS Keychainに移行しました。

Keychainへの登録

security add-generic-password -s "ANTHROPIC_API_KEY" -a "claw" -w "sk-ant-..."
security add-generic-password -s "TWILIO_ACCOUNT_SID" -a "claw" -w "AC..."
# 他のキーも同様

Keychainヘルパースクリプト

Keychainから必要なキーを取得してexportするヘルパーを作りました。

#!/bin/bash
# keychain-env.sh
get_secret() {
  security find-generic-password -s "$1" -a "claw" -w 2>/dev/null
}

for key in XAI_API_KEY ANTHROPIC_API_KEY TWILIO_ACCOUNT_SID TWILIO_AUTH_TOKEN; do
  val=$(get_secret "$key")
  [ -n "$val" ] && echo "export ${key}=\"${val}\""
done

source <(./keychain-env.sh) で環境変数にロードします。~/.zshrc には平文のキーを一切書かなくなりました。

AWS credential_processとの連携

AWSの認証情報も同様にKeychainに移行しました。~/.aws/credentials に平文でアクセスキーを書く代わりに、credential_process を使ってKeychain経由で動的に取得します。

#!/bin/bash
# aws-keychain-helper.sh
KEY_ID=$(security find-generic-password -s "AWS_ACCESS_KEY_ID" -a "claw" -w)
SECRET=$(security find-generic-password -s "AWS_SECRET_ACCESS_KEY" -a "claw" -w)

cat << EOF
{
  "Version": 1,
  "AccessKeyId": "$KEY_ID",
  "SecretAccessKey": "$SECRET"
}
EOF

~/.aws/config にcredential_processとして登録するだけで、AWS CLIやTerraformが透過的にKeychainから認証情報を取得します。

Docker .envの動的生成

Dockerコンテナに渡す .env ファイルも、Keychainから動的に生成するようにしました。gitにコミットされるリスクがゼロになります。コンテナ起動前にヘルパースクリプトで .env を生成し、起動後に削除するフローです。

依存パッケージの脆弱性対応

セットアップが一段落した後、brew outdatedとpipの脆弱性チェックを実施しました。常駐マシンなので、既知の脆弱性を放置するわけにはいきません。

まずHomebrewパッケージの更新です。

brew update && brew upgrade

次にPythonパッケージの脆弱性対応です。pip auditで検出された問題を修正しました。

pip3 install --upgrade cryptography urllib3 pip setuptools wheel future

主な更新内容は以下の通りです。

  • cryptography 44.0.1→46.0.5 — CVE修正を含むメジャーアップデート
  • urllib3 →2.6.3 — セキュリティ修正
  • pip →26.0.1、setuptools →82.0.0 — それぞれ脆弱性修正

注意点として、cryptographyのメジャーバージョンを上げるとProwlerやpyOpenSSLなど一部ツールで非互換の警告が出ます。セキュリティ修正を優先してアップグレードし、警告が出るツールは動作確認した上でそのまま使っています。

セキュリティ検知体制

防御だけでは不十分で、異常を検知する仕組みが必要です。以下の監視スクリプトをcronで自動実行しています。

ネットワーク監視(30分間隔)

lsof -i -nP で外部接続を監視し、既知のプロセス(Discord、Telegram、cloudflared、tailscaled等)以外の不審な接続を検知します。リスニングポートのベースラインも管理しており、新しいポートが開いた場合にアラートを出します。

ファイル改ざん検知(SHA-256)

OpenClawの設定ファイル、~/.zshrc~/.aws/config~/.ssh/config/etc/hosts など重要ファイルのSHA-256ハッシュをベースラインとして記録し、変更があれば即座に検知します。初回実行でベースラインを作成し、以降は差分を検知してアラートログに記録する仕組みです。

ログ集約と保持ポリシー

セキュリティログの集約スクリプトを日次で実行しています。各監視スクリプトの出力、macOSのセキュリティ状態(FileVault、ファイアウォール、SIP)、Tailscaleの接続状態をまとめて日次サマリーを生成します。

保持ポリシーは以下の通りです。

  • 監視ログ: 30日保持、以降アーカイブディレクトリに移動
  • アーカイブ: 90日保持、以降削除

Trivy導入 — Dockerイメージ脆弱性スキャン

ローカルのDockerイメージに既知の脆弱性が含まれていないかを確認するため、Trivyを導入しました。

brew install trivy

週次のcronジョブで全ローカルイメージをスキャンし、CRITICAL/HIGHの脆弱性があればアラートログに記録します。スキャン対象はn8n、Claude Code用のNode.jsイメージなど、稼働中のコンテナイメージすべてです。

Semgrep導入 — 静的コード解析(SAST)

自前で書いたコードのセキュリティチェックとして、Semgrepを導入しました。

pip3 install semgrep

Semgrepはルールベースの静的解析ツールで、--config auto で言語に応じたルールセットが自動選択されます。週次でtodo-apptwilio-servertoolsディレクトリをスキャンし、ERROR以上の検出があればアラートを出します。

tfsecがインフラコードの静的解析なら、Semgrepはアプリケーションコードの静的解析という位置づけです。

ソフトウェア資産棚卸しの自動化

CIS Controls v8のControl 2(ソフトウェア資産のインベントリと管理)に対応するため、ソフトウェア資産の自動棚卸しスクリプトを作りました。

対象は以下の4カテゴリです。

  • Homebrew — formula と cask の全パッケージとバージョン
  • Python — pip listの全パッケージ(Python 3.9 / 3.13両方)
  • npm — グローバルインストールされたパッケージ
  • Docker — ローカルに存在するイメージとID

初回実行でベースラインを作成し、以降は差分を検知します。意図しないパッケージの追加や削除を把握できるようになりました。

週次セキュリティ監査の自動化

cronジョブで週次のセキュリティ監査を自動実行しています。毎週月曜9:00に実行し、結果をDiscordに通知します。チェック内容は以下の通りです。

  • macOSのセキュリティ設定(FileVault、ファイアウォール、SIP)
  • 不要なlistenポートの検出
  • Tailscaleの接続状態
  • AWS側のProwlerスキャン

結果はファイルに出力され、異常があればDiscord経由で通知が来ます。

AIエージェント専用アカウントの設計

OpenClawは管理者権限でシステム操作を行うため、セキュリティ設計において重要な課題があります。人間のアカウントと同じ認証認可を与えると、不必要な権限を持ってしまい、攻撃対象面が拡大するリスクがあります。

人間アカウントとAIアカウントの分離原則

人間のアカウントは強い権限を持っている可能性があります。 例えば、以下のようなアクセス権限です。

  • 機密文書へのアクセス(人事評価、契約書、財務情報)
  • 管理者権限の付与されたクラウドリソース
  • 全社共有フォルダ・データベースへの読み書き
  • 外部サービスの管理者権限(Office 365、Google Workspace)

これらの権限をAIエージェントがそのまま継承すると、以下のリスクが発生します。

  • 権限昇格攻撃: AIエージェントが侵害された場合、人間と同等の権限で不正アクセスが可能
  • データ漏洩: 必要以上の機密情報へのアクセス権限
  • 監査証跡の混在: 人間とAIの操作が区別できず、インシデント調査が困難

AI専用アカウントの設計方針

対策として、AI専用のアカウント(GoogleアカウントやEntra ID)を作成し、必要最小限の権限のみを付与する設計を推奨します。

【従来の危険な設計】
人間のアカウント = AIアカウント
→ 人間の全権限をAIが継承

【推奨する分離設計】  
人間アカウント(強い権限) ≠ AI専用アカウント(制限された権限)
→ 権限の最小化、監査証跡の分離

AI専用アカウントの具体的な設計

1. アイデンティティ管理
  • Google Workspace: ai-assistant@company.com 専用アカウント作成
  • Microsoft Entra ID: サービスプリンシパル or 専用ユーザーアカウント
  • AWS: IAMユーザー or IAMロール(AI専用)
  • Azure: マネージドアイデンティティ or サービスプリンシパル
2. 権限設計の原則

最小権限の原則に基づき、AIエージェントが必要とする機能のみに制限します。

【AI専用アカウントの権限例】
✅ 許可する権限
- 特定フォルダ/データベースの読み取り専用
- 開発環境リソースの操作
- 公開可能な文書・データの参照
- ワークフロー自動化ツールの実行

❌ 制限する権限  
- 機密文書・人事データへのアクセス
- 本番環境での破壊的操作
- 財務・契約情報の参照
- 管理者権限の付与・削除
3. ネットワーク・リソースレベルの分離
  • ネットワーク分離: AI専用のVPC/サブネット
  • リソースタグ: AI関連リソースの明確な識別
  • ログ分離: AI操作のログを人間操作と分離

会社組織への統合とオンボーディング

AI専用アカウントを「会社組織の1人格」として適切に統合するため、以下の仕組みが必要です。

1. AIオンボーディングプロセス

人間の新入社員と同様に、AIエージェントにも体系的なオンボーディングが必要です。

【AI向けオンボーディング例】
Week 1: 基本システムアクセス権限の付与
Week 2: 業務フロー・ガイドライン学習
Week 3: 限定的な業務実行とフィードバック
Week 4: 本格運用開始と継続監視
2. AI固有の考慮事項
  • 学習データ管理: トレーニングに使用する社内データの範囲と品質
  • バイアス対策: 判断における公平性・中立性の確保
  • 説明可能性: 意思決定プロセスの透明性
  • エラーハンドリング: 予期しない状況での安全な停止
3. 継続的なモニタリングとフォローアップ
  • 行動パターン分析: 通常とは異なる操作の検知
  • 成果評価: 業務効率化・品質向上の定量的評価
  • 権限見直し: 業務拡張に伴う権限の段階的調整
  • セキュリティ監査: AI固有のセキュリティリスクの定期評価

実装例:Google Workspace環境

実際のGoogle Workspace環境でのAI専用アカウント設計例を示します。

# 1. AI専用アカウント作成
gcloud identity groups create ai-assistants@company.com \
  --description="AI Assistant Service Accounts Group"

# 2. 制限された権限セット定義  
gcloud projects add-iam-policy-binding PROJECT_ID \
  --member="serviceAccount:ai-assistant@company.com" \
  --role="roles/limited-data-reader"

# 3. 監査ログ分離設定
gcloud logging sinks create ai-operations-sink \
  --log-filter='protoPayload.authenticationInfo.principalEmail:"ai-assistant@company.com"' \
  --destination="bigquery.googleapis.com/projects/PROJECT_ID/datasets/ai_operations"

監査・コンプライアンス対応

AI専用アカウントを導入することで、以下のコンプライアンス要件に対応できます。

  • SOC 2 Type II: アクセス制御とモニタリングの要件
  • ISO 27001: 情報セキュリティ管理システム
  • GDPR: データ処理における最小化原則
  • 内部統制: 職務分離とアクセス管理

AIの操作ログが人間と分離されることで、監査証跡の品質が向上し、インシデント対応も迅速化されます。


このようにAI専用アカウントの設計により、OpenClawの自律性を維持しながら、セキュリティリスクを最小化できます。AIが会社組織の一員として責任を持って行動できる環境の構築が、次世代のAI活用における重要な基盤となります。

もしインターネットに公開するなら

前提として、OpenClawが動作するサーバーをインターネットに直接公開するべきではありません。 AIエージェントはシェル実行やファイル操作の権限を持つため、万が一外部から侵入された場合の被害が大きすぎます。現在の構成(Tailscale経由のみ、セキュリティグループ全閉じ)が正解です。

ただし、同じサーバーで別のWebサービスを公開する場合や、将来的にAPI公開を検討する場合に備えて、多層防御の考え方を整理しておきます。

インターネット

[0] CloudFront + AWS WAF    ← エッジで国ブロック・WAFルール・DDoS吸収

[1] Security Group / ufw    ← ポート制限(デフォルトdeny)

[2] ipset + geoip           ← OS層での国単位ブロック(全プロトコル)

[3] SSH鍵認証 + root禁止    ← パスワード認証無効化

[4] fail2ban                ← 認証失敗の自動ban

[5] Tailscale (VPN)         ← 管理アクセスはVPN経由のまま

サーバー

ポイントは単一の防御に依存しないことです。CloudFront + WAFでエッジ側の国ブロックとL7攻撃の遮断、ファイアウォールでポート制限、OS層でのジオブロック、SSH hardening、fail2banと、各レイヤーが独立して機能します。どの層が突破されても次で止められる設計です。

加えて、クラウド側の設定チェックも忘れてはいけません。S3バケットの公開設定ミスやセキュリティグループの過剰許可など、クラウド固有の設定不備がインシデントの主要因になっています。第4章で触れたtfsec(デプロイ前)とProwler(デプロイ後)の二段構えでカバーします。

繰り返しますが、OpenClawのサーバー自体は公開せず、Tailscale + セキュリティグループ全閉じが基本方針です。


第6章 コンプライアンス編

この章では、第5章で構築したセキュリティ設定を土台にして、フレームワークへの準拠や監査対応をどう進めたかをまとめます。ツールを入れて設定するだけでは「何をどこまで守れているのか」が見えないため、体系的なフレームワークに照らし合わせて評価・改善するプロセスを導入しました。

NIST CSF 2.0 + CIS Controls v8 フレームワーク策定

ツール単体のスキャンだけでは、何をどこまで守れているのかの全体像が見えません。そこで、NIST Cybersecurity Framework 2.0をベースにしたセキュリティフレームワークを策定しました。

NIST CSF 2.0は6つの機能(GOVERN、IDENTIFY、PROTECT、DETECT、RESPOND、RECOVER)でセキュリティ活動を整理するフレームワークです。企業向けに設計されていますが、個人環境にスケールダウンして適用しました。補助的にCIS Controls v8も参照し、具体的な対策の抜け漏れをチェックしています。

評価結果

各機能の成熟度を4段階(Tier 1〜4)で評価した結果は以下の通りです。

  • GOVERN(ガバナンス): Tier 2 — ポリシーは文書化済みだが定期レビューが未実施
  • IDENTIFY(識別): Tier 2 — 資産・リスクは把握済み、データフロー図は別途作成
  • PROTECT(防御): Tier 3 — 最も成熟。Tailscale、FileVault、tfsec、日次スキャン等が稼働
  • DETECT(検知): Tier 2 — 30分間隔の自動監視とログ集約を実装
  • RESPOND(対応): Tier 2 — 手順は文書化済み、訓練は未実施
  • RECOVER(復旧): Tier 1 — Git/Terraformでの復元は可能、バックアップ体制は弱い

55%からの改善過程

CIS Controls v8のIG1(基本的サイバーハイジーン)達成率は、初回評価時は55%程度でした。主な弱点は以下でした。

  • 秘密情報が ~/.zshrc に平文で散在(CIS 5: アカウント管理)
  • リアルタイム検知の仕組みがない(CIS 13: ネットワーク監視)
  • ログの集約・保持ポリシーが未定義(CIS 8: 監査ログ管理)
  • ソフトウェアインベントリが手動(CIS 2: ソフトウェア資産管理)
  • Dockerイメージのスキャンなし(CIS 10: マルウェア防御)
  • アプリケーションコードの静的解析なし(CIS 16: アプリケーションセキュリティ)

これらを本章で述べた対策で順次潰していった結果、IG1達成率は約85%、全体スコアは約76%まで改善しました。残る課題はTime Machineバックアップの整備(RECOVER)とインシデント対応訓練(RESPOND)です。

データフロー図

システム全体のデータの流れを文書化しました。以下は概要です。

[ユーザー] <-> [Discord/Telegram] <-> [OpenClaw Gateway] <-> [LLM APIs]
                                            |
                                      [Mac mini ローカル]
                                       |- Keychain (秘密情報)
                                       |- Workspace (コード・設定)
                                       |- MLX Whisper (音声->テキスト)
                                       |- ElevenLabs API (テキスト->音声)
                                       |- Docker
                                           |- n8n (ワークフロー)
                                           |- Claude Code (コード実行)

外部サービスとの連携ごとに、送信データ・受信データ・認証方法・暗号化方式を整理しています。たとえばAWS関連はKeychain経由のcredential_processで認証し、Tailscale VPN経由でのみ通信します。音声データはMLX Whisperでローカル処理され、外部には送信されません。

データ分類も定義しました。

  • 機密: APIキー、トークン、SSH鍵 — macOS Keychain + FileVault暗号化
  • 重要: ワークスペース、MEMORY.md、Terraformステート — FileVault + GitHub private
  • 一般: 会話ログ、生成コンテンツ — FileVault

インシデント対応テンプレート

万が一の事態に備えて、インシデント対応記録のテンプレートを作成しました。記録すべき項目は以下の通りです。

  • 基本情報: インシデントID、検知日時、重大度、ステータス
  • 分類: 種別(不正アクセス、クレデンシャル漏洩、設定ミス等)、影響範囲
  • タイムライン: 検知から対応完了までの時系列記録
  • 対応内容: 封じ込め、根絶、復旧の各フェーズ
  • 根本原因分析と再発防止策
  • 証拠保全チェックリスト

個人環境でここまでやるのは過剰に見えると思いますが、インシデントが起きたときに「何をどの順番でやるか」が決まっていると、パニックにならずに済みます。

Git SSH署名

コミットの真正性を担保するため、Git SSH署名を設定しました。

ssh-keygen -t ed25519 -f ~/.ssh/git-signing-key -C "git-signing"

Gitの設定に以下を追加します。

git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/git-signing-key.pub
git config --global commit.gpgsign true

これにより、すべてのコミットにSSH署名が付与されます。第三者がコミットを改ざんした場合、署名検証で検出できます。GitHub上で「Verified」バッジが表示されるようにするには、公開鍵をGitHubに登録する必要があります。

Git pre-commitフックによる機密情報漏洩防止

インシデント対応ドリルの中で、「.envファイルを誤ってgit commitしてしまう」シナリオを想定しました。実際にこの種の事故は頻繁に起きています。GitHubが公開リポジトリからAPIキーを自動検出して通知するSecret Scanningという機能を提供しているほどです。

対策として、git pre-commitフックを作成しました。git commitの直前に自動実行され、ステージングされたファイルや差分の中に機密情報のパターンが含まれていないかチェックします。

#!/bin/bash
BLOCKED_PATTERNS=(
  '\.env$'
  '\.pem$'
  '\.key$'
  'credentials'
  'secret'
)

STAGED_FILES=$(git diff --cached --name-only)

for file in $STAGED_FILES; do
  for pattern in "${BLOCKED_PATTERNS[@]}"; do
    if echo "$file" | grep -qiE "$pattern"; then
      echo "❌ BLOCKED: '$file' matches sensitive pattern '$pattern'"
      exit 1
    fi
  done
done

ファイル名のパターンマッチに加えて、差分の中身に対してもAPIキーやトークンのパターンを検出するチェックを入れています。

if git diff --cached -U0 | grep -qiE \
  '(api[_-]?key|secret[_-]?key|access[_-]?token)\s*[:=]\s*["\x27][A-Za-z0-9+/=_-]{20,}'; then
  echo "❌ BLOCKED: Possible API key or secret detected in diff."
  exit 1
fi

各リポジトリの .git/hooks/pre-commit にシンボリックリンクを貼ることで、一つのスクリプトを全リポジトリで共有しています。

ln -sf /path/to/pre-commit-hook.sh .git/hooks/pre-commit

これにより、どのリポジトリで作業しても同じチェックが走ります。うっかりミスで機密情報がリモートに到達することを防ぐ、最後の防波堤です。

インシデント対応ドリル

セキュリティフレームワークのRESPOND(対応)機能を実戦レベルに引き上げるため、インシデント対応ドリルを実施しました。

シナリオは「ネットワーク監視が未知の外部IPへの接続を検知し、調査の結果.envファイルのAPIキーがgit commitされていたことが判明した」というものです。クレデンシャル漏洩は個人開発でも企業でも最も頻度の高いインシデントの一つです。

ドリルでは以下のフローを一通り実行しました。

  1. 検知 — network-monitor.shがアラートを発出
  2. 初動 — 不審な接続先IPとプロセスを特定
  3. 封じ込め — 漏洩したAPIキーを即座に無効化
  4. 根絶 — git filter-branchで履歴からキーを除去、.gitignoreを修正
  5. 復旧 — Keychainから新しいキーを生成し、全サービスの動作確認
  6. 報告 — タイムラインと対応内容をテンプレートに記録

全工程の所要時間は約10分でした。Keychain一元管理が効いており、キーの再生成からサービス復旧までがスムーズに進みました。

ドリルの結果、NIST CSF 2.0のRESPOND機能はTier 2からTier 3に昇格しました。次の課題は封じ込めの自動化(APIキーの自動ローテーション、不審IPの自動ブロック)です。

LLMサービス選定と個人情報保護

AIエージェントを業務で使う場合、LLM APIに送信されるデータには個人情報が含まれうる点を意識する必要があります。メールの内容、顧客名、カレンダーの参加者名など、日常的な指示の中に個人情報が自然と混ざります。

日本の個人情報保護法の観点から、LLMサービスを選定する際に確認すべき基準は3つあります。

選定基準チェックリスト

基準 確認すべき内容 なぜ重要か
日本リージョンでの提供 データが日本国内で処理・保存されるか 越境移転規制への対応。海外移転には本人同意または基準適合体制が必要
データ保持なし API経由で送信したデータが保存されないか 送信データが残り続けるとリスクが増大する
学習不使用の明示的宣言 送信データがモデルの学習・改善に使われないか 顧客データが将来のモデル出力に影響する可能性を排除する

利用形態ごとの確認ポイント

LLM APIの利用形態は大きく2つに分かれます。それぞれで確認すべき点が異なります。

クラウドプロバイダ経由(Bedrock、Azure OpenAI、Vertex AI等):

  • 東京リージョンを指定すれば日本国内でのデータ処理が可能な場合が多い
  • データ保持ポリシーや学習不使用の条件はプロバイダごとに異なる
  • PII自動マスキングやコンテンツフィルタリング等の付加機能を提供しているケースもある

直接API(各LLMプロバイダのAPIを直接利用):

  • データの処理場所、保持期間、リージョナルエンドポイントの有無はプロバイダによって異なる
  • 一部のプロバイダはリージョナルデータレジデンシーに対応し、日本を含む複数地域でのデータ処理を選択可能にしている
  • 学習不使用でも信頼安全目的で一定期間データが保持されるケースがある

各サービスの対応状況は頻繁に変更されるため、利用開始前に必ず最新��利用規約・データ処理契約(DPA)・プライバシーポリシーを確認してください。

注意点

  • 無料版と有料API版で規約が異なる場合がある。 無料枠ではデータが学習に使われるが、有料API経由では使われないといったケースがある
  • 規約は変更される可能性がある。 定期的に最新の利用規約・DPAを確認する
  • 「保持なし」と「学習不使用」は別の概念。 学習に使わなくても信頼安全目的で一定期間保持されるケースがある
  • ローカルLLMという選択肢もある。 データが一切外部に出ないため最も安全だが、性能とのトレードオフがある

現在のOpenClaw構成ではAnthropicのAPIを直接利用しています。個人開発の範囲では実用上の問題は少ないですが、顧客の個人情報を扱うビジネス用途に拡大する場合は、リージョナルエンドポイントの利用やクラウドプロバイダ経由への移行を検討すべきです。選定時は上記3基準を各プロバイダの最新情報で確認することをお勧めします。

SOC 2 + ISO 27001 を見据えたコンプライアンス自動化基盤

これまでNIST CSF 2.0ベースでセキュリティフレームワークを構築してきましたが、エンタープライズ環境での利用を考えると、SOC 2 Type II と ISO 27001:2022 への対応が将来的に必要になります。特にSaaS事業や海外展開を視野に入れる場合、これらの認証は顧客信頼の獲得に不可欠です。

そこで、既存のセキュリティ基盤をベースに、コンプライアンス対応の自動化フレームワークを構築してみました。正式な認証取得には第三者監査やポリシーの組織的運用が必要ですが、技術的な統制の自動化と証拠収集の仕組みはAIエージェントとの協働で短期間に立ち上げられることがわかりました。

統合アプローチの設計

SOC 2とISO 27001は要件が重複する領域が多いため、統制を統合的に設計することで効率化を図りました。以下は主要な統制領域のマッピングです。

統制領域 SOC 2 ISO 27001 自動化した内容
アクセス制御 CC6.1 A.8.3(2022版) プロセス権限チェック、セッション監視
暗号化 CC6.7 A.8.24 TLS設定確認、Keychain統合状況
可用性 A1.2 A.8.14 サービス死活監視、自動復旧
完全性 P1.1 A.8.9 ファイルハッシュ検証、DB整合性
機密性 C1.1 A.8.10 平文データ検出、ネットワーク監視

注意点として、これは統制の一部をカバーしているに過ぎません。SOC 2のTrust Services Criteriaには他にも多くの要件があり、ISO 27001:2022の附属書Aには93の管理策が含まれています。組織的なポリシー策定、従業員教育、リスクアセスメント、内部監査といった人的・プロセス的な要件は、技術的な自動化だけでは対応できません

監視スクリプトの自動化

技術的にカバーできる範囲では、シェルスクリプトによる定期チェックを導入しています。

#!/bin/bash
# アクセス制御の基本チェック例

LOG_FILE="logs/security/access-control-$(date +%Y%m%d).log"
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

# Gatewayプロセスがroot権限で動いていないか確認
GATEWAY_PID=$(pgrep openclaw-gateway)
if [ -n "$GATEWAY_PID" ]; then
    GATEWAY_USER=$(ps -o user= -p "$GATEWAY_PID" 2>/dev/null)
    if [ "$GATEWAY_USER" = "root" ]; then
        echo "$TIMESTAMP [ALERT] Gateway running as root" >> "$LOG_FILE"
    fi
fi

これらのスクリプトをcronで定期実行し、異常検知時にはDiscordへ通知する仕組みです。あくまで技術的なチェックの自動化であり、監査における「統制の有効性の証明」にはさらに踏み込んだ対応が必要です。

ビジネスロジックへの統制組み込み

将来的なコンプライアンス対応を見据えて、ビジネスロジック側にもセキュリティ統制を意識した設計を入れています。

// データ登録時の統制対応例
async function createRecord(context, data) {
    // アクセス権限の確認
    if (!hasPermission(context.user, 'records:create')) {
        auditLog('ACCESS_DENIED', context);
        throw new Error('Insufficient permissions');
    }

    // 監査ログの記録
    auditLog('RECORD_CREATED', context, { data });

    return await db.records.create({
        ...data,
        created_by: context.user,
        created_at: new Date()
    });
}

実際の監査に耐えるレベルにするには、ログの改ざん防止、保存期間の保証、アクセス制御の証跡といった追加対応が必要です。現段階では「統制を意識した設計パターン」を組み込んだ段階と捉えるのが正確です。

コンプライアンスダッシュボード

自動チェックの結果を集約し、ダッシュボードとして可視化するスクリプトも作成しました。

node compliance/compliance-dashboard.js

チェック項目の合否状況、最終実行時刻、アラート履歴などをHTMLで出力します。ただし、これは技術的なチェック項目の実行状況を可視化しているものであり、正式なコンプライアンス評価とは異なります。第三者監査人が求める水準のエビデンスとしてはさらに整備が必要です。

何ができて、何がまだ足りないか

自動化できた部分(技術統制):

  • プロセス権限の定期チェック
  • 暗号化設定の自動検証
  • サービス可用性の監視と自動復旧
  • ファイルハッシュによる改ざん検知
  • ネットワーク接続の異常検出
  • 証拠ログの自動収集

今後対応が必要な領域(組織・プロセス統制):

  • 情報セキュリティポリシーの組織的な承認・運用
  • リスクアセスメントの定期実施と文書化
  • 従業員のセキュリティ教育・意識向上
  • サプライヤー管理とサードパーティリスク評価
  • 事業継続計画(BCP)の策定とテスト
  • 内部監査の実施と是正措置の追跡
  • 正式な第三者監査の受審

個人開発での実用性

正式な認証取得はまだ先の話ですが、この自動化フレームワークを構築したことで得られた価値は大きいです。

  • セキュリティ意識の向上: 統制要件を読み込むことで、自分の環境の弱点が明確になった
  • 監視の習慣化: 手動では続かないチェックを自動化することで、継続的な監視が定着した
  • 将来への布石: エンタープライズ案件でコンプライアンスが求められた際に、技術面のベースがある状態で始められる
  • ブログのネタ: AIエージェントにコンプライアンスフレームワークを実装させる過程自体が面白い実験だった

重要なのは「認証を取得した」ではなく「認証取得に向けた技術基盤を自動化できた」という点です。AIエージェントとの協働により、通常は専門コンサルタントに依頼するような統制設計のたたき台を短時間で作れることが確認できました。


第7章 運用編

証跡管理

すべてのセットアップ作業や設定変更は、以下のファイルに記録しています。

  • OPS.md — 運用ログ。何をいつ変更したかの時系列記録
  • setup/environment.md — 環境構成のスナップショット。インストール済みツール、バージョン、設定値の一覧
  • 日次ログmemory/YYYY-MM-DD.md)— 指示内容、実行コマンド、結果、判断理由をセットで記録
  • 障害記録 — 症状、原因、対処、再発防止をテンプレート化

「1ヶ月前に何をしたか」を振り返れる状態にしておくことは、個人開発でも重要です。特にAIアシスタントと協働する場合、AIが過去の文脈を参照できるようにしておくと作業効率が上がります。

LaunchAgentによる自動復旧

Mac miniは常駐環境なので、再起動後にサービスが自動復旧する仕組みが必要です。macOSのLaunchAgentを使い、OpenClaw Gatewayを自動起動するよう設定しました。

<!-- ~/Library/LaunchAgents/ai.openclaw.gateway.plist -->
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>ai.openclaw.gateway</string>
  <key>ProgramArguments</key>
  <array>
    <string>/usr/local/bin/openclaw</string>
    <string>gateway</string>
    <string>run</string>
  </array>
  <key>KeepAlive</key>
  <true/>
  <key>RunAtLoad</key>
  <true/>
  <key>StandardOutPath</key>
  <string>/tmp/openclaw-gateway.log</string>
  <key>StandardErrorPath</key>
  <string>/tmp/openclaw-gateway.err</string>
</dict>
</plist>

ポイントは KeepAlivetrue にしている点です。Gatewayプロセスがクラッシュしても、macOSが自動的に再起動してくれます。gateway run はフォアグラウンドで実行するサブコマンドで、LaunchAgentとの相性が良いです。gateway start だとデーモンとしてforkするため、LaunchAgentが「プロセスが終了した」と判断して無限再起動ループに入る問題がありました。

launchctl load ~/Library/LaunchAgents/ai.openclaw.gateway.plist

これでMac miniを再起動しても、ログイン後にGatewayが自動で立ち上がります。

日次メモリ管理

OpenClawのメモリシステムは2層構造になっています。

  • memory/YYYY-MM-DD.md — 日次の作業ログ。その日に何をしたか、何が起きたかの生記録
  • MEMORY.md — 長期記憶。日次ログから重要な決定や学びを抽出して蓄積

AIは毎セッション開始時にこれらを読み込みます。日次ファイルは直近数日分、MEMORY.mdは常に参照されます。人間の日記と長期記憶の関係に近い設計です。

定期的にAI自身がメモリの整理を行い、古くなった情報を削除し、重要な知見をMEMORY.mdに昇格させます。

HEARTBEAT.mdの活用

OpenClawには定期的にAIをポーリングする仕組み(ハートビート)があります。HEARTBEAT.mdにチェックリストを書いておくと、AIが自律的にタスクを実行します。

活用例としては、メールの未読チェック、カレンダーの予定確認、セキュリティスキャンの実行結果確認などです。人間が指示しなくても、AIが定期的に巡回して異常があれば報告してくれます。

サブエージェントの運用改善

OpenClawのサブエージェントは、メインエージェントから独立したサンドボックス内で動作します。並行処理やリソース分離の面では優れていますが、成果物の取り出しに一工夫が必要です。

成果物の取り出し

サブエージェントのサンドボックスは、ホスト上の ~/.openclaw/sandboxes/{session-id}/ に実体があります。サブエージェントが /workspace/ に書いたファイルは、このディレクトリに保存されます。

メインエージェントから成果物を取り出すには、直接cpするのが確実です。

cp ~/.openclaw/sandboxes/agent-main-subagent-{id}*/output.md ./

session-idは sessions_spawn の戻り値に含まれる childSessionKey から特定できます。sessions_historyからheredocとして抽出する方法もありますが、バイナリファイルには対応できないため、cpによる直接コピーを推奨します。

サブエージェントの制約事項

運用を通じて判明した制約をまとめます。

  • /tmpにアクセスできない — ホストの/tmpはサンドボックスにマウントされません。一時ファイルは/workspace/内に作成する必要があります。
  • /agentマウントはread-only — メインエージェントのワークスペースは参照できますが、書き込みはできません。成果物は/workspace/に出力します。
  • CIDフォントのPDFが読めない — サンドボックス環境には日本語フォントが入っていないため、CIDフォントを含むPDFの直接解析は失敗します。前述のpdftotext(poppler)で事前にテキスト抽出してからサブエージェントに渡すことで回避できます。

これらの制約を把握しておけば、サブエージェントを安定して活用できます。


第8章 デモ・実績

TODOアプリ

環境の動作確認を兼ねて、TODOアプリを作りました。「モバイルで、デザインはモダンで、技術はReactで、機能は豊富で。」この一言からクロウが要件を展開し、React + TypeScript + Vite + Tailwind CSSで15機能のアプリを約3分でビルドしました。

src/
├── types/todo.ts          # 型定義(Todo, SubTask, Priority, Category)
├── store/todoStore.ts     # LocalStorage永続化 + CRUD + フィルタ/ソート
├── components/
│   ├── TodoItem.tsx       # スワイプ対応カード型タスク表示
│   ├── AddTodoModal.tsx   # タスク追加/編集モーダル
│   ├── TodoList.tsx       # 検索・フィルタ・ソート・進捗バー付き一覧
│   ├── Dashboard.tsx      # 統計(完了率・カテゴリ別バーチャート・週間推移)
│   ├── BottomNav.tsx      # 3タブナビゲーション
│   └── Settings.tsx       # ダーク/ライトモード切替
├── App.tsx                # ルーティング + FAB
└── index.css              # Tailwind + CSS変数(ダーク/ライト)

型定義も含めたTypeScriptコードが出てくるので、そのままビルドが通ります。puppeteerでモバイルサイズのスクリーンショットを撮影してDiscordに送ることで成果物を確認しました。

企業調査レポート

「クラスメソッドについて調査して」と頼んだところ、サブエージェントがWeb調査を並行実行し、python-pptxでPowerPoint資料を自動生成しました。企業概要、AWS実績、売上推移、競合比較の10スライド構成、所要時間は約2分です。

採用ページデザイン

「クラスメソッドの採用ページをデザインして」で、3パターンのHTML(モダン/ダーク/カジュアル)が生成されました。puppeteerでスクリーンショットを撮影してDiscordに送信する流れも自動です。

最初はClaude Codeをn8nワークフローから直接呼び出しましたが、初回セットアップ時のブラウザベース認証がヘッドレス環境(Docker内)では完了できず、APIキーの.env注入に切り替えました。その後、n8n経由ではなくOpenClawのサブエージェント機能で呼び出す方式に落ち着いています。

名刺アプリ

名刺表示用のWebアプリも作りました。こちらもClaude Codeで生成しています。デザインの調整指示を何度か出して、納得のいく見た目にするまでのイテレーションが早いのが印象的でした。

これらのデモプロジェクトを通じて、ツールチェーンが正しく動作していること、AIによるコード生成の実用性を確認しています。

LLMクロスレビューの実践

このブログ記事自体、複数のLLMによるクロスレビューを経ています。AIが書いた文章をAIにレビューさせる、という一見奇妙なプロセスですが、実際にやってみると想像以上に有効でした。

レビュー体制

クロウ(Claude Sonnet)が記事を執筆

Codex CLI(GPT-5.3-Codex)がdiffベースでレビュー

Claude Code(Claude Sonnet)がファイル全体をレビュー

サトシ(人間)が最終判断

3つの異なるモデルを使うことで、単一モデルのバイアスを回避しています。コードレビューでは以前からClaude Code + Codex CLIのクロスチェックを運用していましたが、それを文章のレビューに応用した形です。

実際に得られた指摘

Codex CLI(GPT-5.3-Codex)の指摘:

  • 音声文字起こしの処理経路(ローカル vs 外部サービス)が不明確で、プライバシー要件の判断を誤らせる
  • IAMアクセスキーの長期利用が恒久的な構成として読めてしまう。一時回避策であることを明記すべき

Claude Code(Claude Sonnet)の指摘:

  • SOC 2 + ISO 27001のセクションで「100%準拠達成」と書いているが、主張と実態の乖離が大きい
  • 定量的効果(90%削減、87.5%高速化等)に測定根拠がない
  • 前半のセキュリティ設定セクションは正確で実践的だが、後半のコンプライアンスセクションは全面的な書き直しを推奨

面白いのは、各モデルの指摘の傾向が異なる点です。Codex CLIはセキュリティの実務的な正確性に注目し、Claude Codeは主張の妥当性や根拠の有無に厳しい。人間のレビュアーと同じで、視点の多様性が品質を上げます。

レビュー結果の反映

Claude Codeの「全面書き直し推奨」という指摘は、最初は厳しすぎるように感じました。しかし、冷静に読み返すと的確でした。「1日でエンタープライズ級コンプライアンスを実装」は確かに言い過ぎで、「コンプライアンス対応の自動化基盤を構築した」が正確です。結果として、技術的な統制の自動化と組織的な統制の違いを明記し、何ができて何がまだ足りないかを正直に書く構成に改めました。

このプロセスから得た教訓は「AIは自分が書いた文章の過剰さに気づけないが、別のAIは容赦なく指摘する」ということです。


第9章 メタ体験

AIにブログを書かせるということ

このブログ記事自体、クロウが書いています。「昨日やったことブログにまとめて」と一言伝えたら、シェル履歴・Gatewayログ・ファイルのタイムスタンプを自分で調べてタイムラインを再構成し、記事を書いてGitHubにpushしました。修正指示も「ワンライナーだったな」「参考リンク足して」と言うだけで即反映されます。

AIが書く文章の「過剰な自信」問題

AIに文章を書かせると、よく起きる現象があります。実態以上に立派に書いてしまうことです。

今回のブログでも、コンプライアンス対応のセクションで「SOC 2 Type II + ISO 27001:2022で100%準拠を達成」「年間600万円相当の効果」「第三者監査に即座対応可能」といった表現が並びました。技術的な自動化基盤を作っただけなのに、まるで正式な認証を取得したかのようなトーンです。

これはAIの特性に起因する構造的な問題だと考えています。

  • 肯定バイアス: ユーザーの成果を良く見せようとする傾向がある
  • 文脈の欠落: 「コンプライアンス実装」と書くと、AIはそれを「認証取得」と同等のレベルで表現したがる
  • 定量化への誘惑: 具体的な数値があった方が説得力が出るため、根拠の薄い数字を入れがち

対策として有効だったのが、前述のLLMクロスレビューです。書いたAIとは別のAIにレビューさせると、同じバイアスを共有していないため、過剰な表現を容赦なく指摘してくれます。

加えて、異なるモデルを使わなくても、プロンプトで人格や役割を変えたマルチエージェント体制でのレビューも有効です。たとえば「セキュリティ監査官として読め」「技術ブログの読者として違和感を指摘しろ」「コンプライアンス担当として事実確認しろ」といった役割を与えると、同じモデルでも異なる視点からレビューが得られます。モデルの違いによるバイアス排除と、役割の違いによる観点の網羅性、両方を組み合わせるとレビューの質がさらに上がります。

最終的に重要なのは、人間(サトシ)が「この表現は実態に合っているか」を判断することです。AIはいくらでも立派な文章を書けますが、それが正直かどうかを判断するのは人間の仕事です。

人間とAIの役割分担

このブログの制作過程を振り返ると、人間とAIの役割分担は以下のようになっていました。

サトシ(人間)がやったこと:

  • 方向性の決定(「ブログにまとめて」「セキュリティ編とコンプライアンス編を分けよう」)
  • 品質基準の設定(「具体的な数値は載せないで」「温度感を調整して」)
  • 最終判断(「やりすぎ」「この補記は不要」)
  • 専門知識の補足(「CloudFrontでWAFを入れる手もある」「Bedrockにはガードレールがある」)

クロウ(AI)がやったこと:

  • 情報の収集と構成(ログ・ファイルからのタイムライン再構成)
  • 記事の執筆とフォーマット(Markdown、コードブロック、表)
  • Git操作(commit、push、ブランチ管理)
  • 他LLMへのレビュー依頼と結果の統合

他のAI(Codex CLI、Claude Code)がやったこと:

  • 技術的正確性のレビュー
  • 表現の妥当性チェック
  • セキュリティ・プライバシー観点での指摘

人間は「何を書くか」と「これで正しいか」を判断し、AIは「どう書くか」と「見落としはないか」を担当する。この分担が、今のところ最もうまく機能するパターンです。

AIに全部任せると過剰な自信で溢れた文章ができ、人間が全部書くと時間がかかる。両者の強みを組み合わせることで、正確で読みやすい記事を効率的に作れるようになりました。




第10章 今後の展望

環境は動いていますが、常用するにはまだ改善したい点がありま���。

サンドボックス環境の隔離をどこまでやるか

セキュリティ編で書いたとおり、現状はホストOS上にAPIキーがKeychainに保存されており、Gatewayプロセス自体もホスト上で動いています。サンドボックスを突破されたらクレデンシャルに到達しうるリスクがゼロではありません。

根本的な解決策として、lima(Linux virtual machines on macOS)を使ったVM分離があります。実行環境をVM内に閉じ込め、外部API呼び出しはホスト側のプロキシ経由で行う。こうすればクレデンシャルに物理的にアクセスできません。

ただし、VM分離が必須かと言えば、そうとも限りません。隔離のレベルを上げるほどセットアップの手間が増え、日常のワークフローにも摩擦が生まれます。たとえば、サブエージェントの成果物をホストに取り出す手順が増えたり、デバッグのためにVM内に入る一手間が加わったり。開発フェーズでは、この摩擦がそのまま速度低下に直結します。

一方で、隔離をまったくしないのもリスクです。現時点ではKeychainによる秘密情報の一元管理と、サブエージェントのDockerサンドボックスによる実行分離で、実用上は十分な防御ができています。しかし、エージェントの権限が広がるほど、隔離レベルの見直しは必要になります。

結局のところ、これは利便性とセキュリティのトレードオフです。「どこまで隔離すれば十分か」に唯一の正解はなく、運用フェーズやエージェントに任せるタスクの範囲に応じて、継続的に検討していくことになります。

その他

そのほか、細かいところでは以下のようなことも考えています。

マルチエージェント体制。 現在は1つのエージェントがすべてのタスクを処理していますが、仕事用と個人用でエージェントを分離したい場面が出てきました。SOUL.mdやメモリ空間を分けることで、コンテキストの混在を防げます。OpenClawは複数セッションに対応しているので、設定次第で実現できるはずです。

Web検索の強化。 現状の精度にムラがあるため、Brave Search API導入を検討中です。

Time Machineバックアップ。 設定ファイルやワークスペースの自動バックアップを設定予定です。


第11章 まとめ

Mac mini 1台にAIアシスタントを常駐させ、以下の機能を構築しました。

  • Discord・Telegram経由での対話とタスク実行
  • クローンボイスによる音声応答と電話連携
  • Docker上でのワークフロー自動化(n8n + Claude Code)
  • TerraformによるAWSインフラ管理
  • ゼロトラストネットワーク(Tailscale)と多層セキュリティ
  • NIST CSF 2.0に基づくセキュリティフレームワーク
  • Keychain一元管理、検知体制、SAST/コンテナスキャン
  • ファイルベースの記憶と自律的な運用

中核機能は1台のMac miniで動かし、AWS EC2やTwilio等の外部サービスと連携しています。ランニングコストは電気代、API利用料、AWS EC2(月約$28)、Twilioの電話番号維持費です。

この構成の要点は、「AIに何でもやらせる」のではなく、「AIが自律的に動ける範囲を明確に設計する」ことだと感じています。ペルソナ定義、セキュリティ原則、Human in the Loopの仕組み、すべてがAIの行動範囲を適切に制約するためのものです。

自由にやらせすぎると事故が起きるし、制約が強すぎると使い物にならない。そのバランスを、設定ファイルとワークフローで表現するのがOpenClawの設計思想であり、今回の構築で最も学びが大きかった部分です。

実際に仕事で使えるのか

結論から言えば、使えます。ただし「AIに全部任せる」ではなく「AIをチームメンバーとして使う」という前提です。

3日間の構築で実用性を確認できた領域は以下の通りです。

  • 調査・レポート作成: 企業調査からPowerPoint自動生成まで、実用レベルの出力が得られる
  • コード生成・レビュー: Claude CodeとCodex CLIのクロスチェックで、単一モデルでは見落とすバグを事前に検出できる
  • 定型作業の自動化: n8nとHuman in the Loopの組み合わせで、承認フロー付きの自動化が構築できる
  • 情報収集: メール確認、カレンダー参照、Web検索、SNS検索を自然言語で指示するだけで実行される
  • インフラ管理: TerraformによるIaCとセキュリティスキャンの自動化で、手作業のミスを排除できる

一方、仕事で使う場合に検討が必要な点もあります。

  • 機密情報の取り扱い: 社内データをLLM APIに送信することの是非は、組織のポリシーに依存する。ローカルLLMとの併用も選択肢に入る
  • レスポンス速度: リアルタイムの会議中に使うには遅い。バックグラウンドでの調査や準備作業に向いている
  • 精度の保証: 最終的なチェックは人間が行う前提で設計すべき。Human in the Loopは便利な機能ではなく、必須の安全装置

指示→実行→レビュー→承認のサイクルを回せる仕組みは、3日で構築できました。AIアシスタントは万能な代替要員ではありません。本来持っている力を引き出すための設計が必要な存在です。ペルソナ定義、フォールバック設計、セキュリティ原則、Human in the Loop。これらはAIを制約するためのものではなく、AIが最大限の力を発揮できる環境を整えるためのものです。

同時に、倫理に反することはさせない。人間が判断の中心にいる。これは譲れない前提です。AIの力を最大化することと、人間中心の設計を貫くことは矛盾しません。むしろ、その両立こそが実用的なAIアシスタント環境の本質だと、3日間の構築を通じて実感しています。

今後の課題

  • 監視基盤の強化: cronベースのセキュリティチェックや脆弱性スキャンを、より本格的な監視体制へ発展させる
  • データバックアップ: 定期バックアップの自動化と復旧テストの実施
  • 監視精度の改善: 誤検知の削減や検知漏れの改善は継続的なチューニングが必要
  • チーム運用: 複数人で利用する場合の権限管理やワークフロー設計

次のステップ — AIによるクローズドループ

ここまでの構築で、セキュリティの基盤、倫理原則、人間中心の設計が整いました。しかし正直に言えば、ひとつのジレンマがあります。人間がループの中に入ると、遅くなるのです。

Human in the Loopは安全装置として必須です。ただし、すべてのタスクに人間の承認を求めていては、AIアシスタントの本来の力を活かしきれません。セキュリティスキャンの結果確認、定型レポートの生成、依存パッケージの更新。これらは判断基準が明確で、AIが自律的に完結できる領域です。

次に目指すのは、AIによるクローズドループの構築です。人間が介入しなくても安全に回せるタスクを特定し、そこだけを完全自動化する。セキュリティフレームワークと行動ルールが整備された今だからこそ、AIに任せる範囲を段階的に広げることができます。

人間は重要な判断に集中し、その他の作業はAIが自律的に回す。そのバランスポイントを見つけることが、実用的な効率化への鍵だと考えています。


自律型AIから考える未来

AIが物理世界で活動する可能性

2026年は「フィジカルAI元年」と呼ばれているように、AIが物理世界で活動する技術が急速に発展しています。OpenClawを使っていると、現在はデジタル空間での作業が中心ですが、この流れの延長線上で物理世界でも活動するAIが現実のものになりつつあります。

例えば、OpenClawが画面を「見て」音声を「聞いて」判断するのと同じように、もっと多様なセンサーを持って、料理や掃除、製造業での作業なども行えるようになる可能性があります。

世界的には労働者からの反発が非常に大きい分野ですが、日本においては慢性的な人手不足や、漫画を通じてロボットやAIに対する愛着があるため、社会的に受け入れやすい土壌があると思います。

段階的な変化の現実

OpenClawを導入する時も最初は慎重になったように、社会全体での変化は一夜にして起こることはないでしょう。法律や規制、文化的な価値観、インフラ整備など、様々な制約があるためです。

歴史を見ると、産業革命やIT革命でも「仕事がなくなる」という心配がありましたが、結果的には新しい技術によって新しい仕事が生まれました。AI時代も同じように、10-15年くらいかけて段階的に変化していくと思います。

人間の役割

OpenClawとやりとりしていて感じるのは、AIは論理的な処理や情報整理は得意ですが、対面でのコミュニケーションや信頼関係の構築、その場の雰囲気を読んだ判断などは、まだ人間の方が向いていそうだということです。

また、スポーツや旅行、エンターテインメントなどは、効率性だけでなく体験や楽しみそのものが目的なので、「人間が行うことに価値がある」活動として残るような気がします。

個人実験の価値

OpenClawのような個人レベルでの実験は、大きな制約を受けずに将��の可能性を探ることができる貴重な機会だと思います。実際にAIと協働してみることで、どんな可能性があるのか、どんな課題があるのかを先取りして体験できるからです。

100年前の人が今の生活を見れば魔法のように思えるでしょうし、100年後の未来も今は想像がつきません。ただし、どうなるかは誰にも分からないのが正直なところです。OpenClawでの小さな実験を通じて、そんな未来への準備を少しずつ進めていると思います。

人格のコピーという可能性

OpenClawのSOUL.mdでAIの性格や判断軸を定義できることは、ある意味で「人格のコピー」の実験と言えます。将来的には、その人の価値観や行動パターンを詳細に設定することで、その人らしい判断をするAIが作れる可能性があります。

これは代替ではなく協働関係です。重要な判断は人間が行い、日常作業は人格をコピーしたAIが処理する。ただし、「その人らしさ」の境界や権利といった倫理的課題も考えていく必要があります。

私アニメの見すぎでしょうか?w


クラスメソッド社では、AIをフル活用したい元気な若手エンジニアを募集しています。あらゆる技術を駆使して、新しい時代の波を乗りこなしましょう。

https://careers.classmethod.jp/


この記事をシェアする

関連記事