セキュリティ

6 件の記事

さまざまな権限付与方式

AIにGitHubを操作させる方法としては、HITL(Human In The Loop)、プロキシ利用、GitHub App、PAT格納などの方式があり、それぞれ利便性やリスクが異なる。単独で他のすべてに勝る方式はないため、用途に応じて選択するとよい。

モデル基本方式漏洩時の権限の寿命効率性流出リスク
HITL(Human In The Loop)AIがアクセスできない場所から人間がghなどで操作を実行(AIにPAT/tokenを渡さない)人手が常に必要ありえない
プロキシ利用PATを格納したプロキシに中継させる(AIにPAT/tokenを渡さない)使えるツールが限定され不便ありえない
GitHub AppGitHub Appが短命トークンを発行。それをAIが利用する短命高いありえるが悪用リスクは限定的
直接トークンPATをAIに直接付与長命高いありえる

※ 流出リスクについて: 上記はあくまでAIによるPAT流出リスクについての評価である。オペミス等別の要因によって流出するケースは議論の外である。

使い分け

  • 極めて高いセキュリティを求められており、わずかなリスクの可能性すら許容しがたい -> HITL
  • PRスパム程度ならともかくPAT漏洩リスクの可能性は一切許容できない、あるいは諸事情でGitHub Appが使えない -> プロキシ
  • 他の施策と合わせればインシデント発生時の被害を許容範囲内に抑えられる -> GitHub App
  • 漏洩してもさして問題ない環境(実験用など)である -> PAT直渡し

利用方法

HITL

手動で利用するのと同じ。

AIはコマンドを指示したり、テキストを作ったりする程度である。

プロキシ利用

PAT/Tokenをプロキシに配置し、AIがアクセスできないようにする。AIはHTTP経由でGitHub APIを呼ぶだけである。

理屈は難しくなく、docker-composeでDevContainerを起動してサイドカーにNginxを使い

  gh-proxy:
    image: nginx:alpine
    volumes:
      - ./gh-proxy/default.conf.template:/etc/nginx/templates/default.conf.template:ro
    environment:
      GH_PAT: ${GITHUB_CLAUDECODE_KEY}

環境変数でPATをこのような設定を読み込ませるだけでも利用できる。なお、なるべくFine-grained personal access tokensを用い、強すぎる権限を付与しないこと。

Dev Container

Why Dev Container?

  • AIを隔離してセキュリティを維持(権限最小化)
    • AIが閲覧できるのはマウントしたディレクトリだけ
    • 利用できるツールやネットワークも限定
    • GithubやAWSなどの権限もAI専用に
  • 環境統一が容易
    • 設定ファイルをリポジトリに保存しておけばワンクリックで環境再現
      • 仮想環境だとこうはいかない
    • たとえWindows/Mac混在チームでもDevContainerなら対応可能
    • CI/CD(Linux)との環境統一も視野に入れられる
  • エディタ連携もある
    • Visual Studio Codeとの連携も便利
  • VS ホスト起動
    • AIがユーザーの権限を利用できてしまう。これは通常広すぎるし強すぎる
      • e.g., 機密情報を含んだファイルが閲覧できる権限、データを消せる権限、AWSの重要リソースを停止・破壊できる権限など
    • チーム間の環境統一も手間がかかる
      • ホストのOS自体WindowsだったりMacだったり
      • CI/CDとの連携も加えるとさらに難儀に
    • ホスト環境も汚れるしセットアップも面倒

Setup

設定ファイルの保存場所

  • <Gitのルートリポジトリ>/.devcontainer/

単一コンテナ VS docker compose

  • 開発のためミドルウェアなどの別コンテナが必要ならdocker-compose
  • それ以外は単一コンテナで十分(YAGNIの精神)
    • あとからdocker-compose対応にするのもAIを使えばさほど手間ではない

バージョン指定

  • 環境統一のため、ベースイメージや主要ツールはバージョンを明記する
    • 原則フルバージョン(X.Y.Z)を記載する
    • マイナーバージョンまで(X.Y)でも可
    • 固定ではなく指定。バージョンアップは積極的に
    • latest運用は避ける

ベースイメージ管理

  • ビルド済イメージを活用
    • ゴールデンイメージを作って主要部分は確実に共通化
    • 開発用とCI/CD用の違いはそれぞれのDockerfileで吸収
    • 管理の手間がかかるため、これ自体も自動化
      • 定期的な自動ビルド
      • 脆弱性スキャン

セキュリティ維持の取り組み

  • AIエージェントは100%安全なシステムではない
    • prompt injection、クラウドAIなら運営側の事故による漏洩などなど
    • リスクマネジメントが必要
  • 権限付与の基本は短命トークン + 最小権限
    • ExpireなしのAPIキーは原則として利用させない
      • 強すぎる権限を持つAPIキーは決して利用させない
    • AWSならIdentity Center + 妥当な範囲の権限 + Service control policies (SCPs)
      • 妥当な範囲の権限 ≒ 機密情報を含まない範囲の読取権限 + 最小限の更新権限
      • 完璧主義で最小化を目指すと実用性が損なわれるため、「妥当な」権限縮小を
      • 重要リソースの更新など責任を伴う業務は原則として人間を絡めることを推奨(ヒューマンインザループ)
    • GitHubのghはExpireを短めにしたFine-grained PATで妥協(最短のExpireでも長いので期待しすぎないこと)
      • 権限管理の仕組みが今のところAWSほどうまくかみ合わせられない
      • 読み取り禁止設定もやらないより良い
      • これでは利用できないほど重要なリポジトリでは、DevContainer + AIでリポジトリごと預けるのを潔く避ける
  • リポジトリ内の設定ファイル(e.g., .envなど)に機密情報を平文で保存しておかない
    • たとえ動作設定でDenyしても閲覧されるリスクがゼロにはならない
    • SSM Parameter Storeなど外部に出す
    • リポジトリへの保存がどうしても必要なら暗号化する
      • ただし、この場合AIが復号できてしまわないようにする
      • 復号した後のファイルを放置してうっかりAIに読まれてしまわないようにもする
      • 環境変数で受け渡す方式はリポジトリに保存しないで済むが、AIエージェント相手の隠ぺいとしては不徹底
        • 普通にアクセスできてしまう
    • そもそも論、AIが関係なくともリポジトリに平文で機密情報を保存すべきでない

Claude Codeの動作設定

  • 権限設定
    • まず危険な内容をDeny
      • 機密情報を含むファイルの閲覧(e.g., .env, ~/.aws/credentials)
      • 危険なコマンドの利用(e.g., sudorm -rf)
    • 次に効率優先でよい内容をAllow
      • コードを保存したディレクトリ(e.g., src/)でのファイル編集
    • それ以外は手動確認
  • ネットワーク設定
    • 通常必要なドメインは許可
      • Claude、GitHubなど
    • 任意ドメインは禁止
      • アタッカーのドメインにつなげられてしまうので
      • もし任意ドメインの調査がしたいなら、リポジトリに紐づいたDev Containerを使わないで別のコンテナを使う
        • コンテキストが欲しいならそこだけ複製する

Contents

Never store sensitive information (e.g., API keys) in plain text within the project. Fetch them at runtime from environment variables or external services such as SSM Parameter Store. Encrypted storage is acceptable, but do not bundle the decryption key in the project. (機密情報(APIキーなど)をプロジェクト内にプレーンテキストで保存しない。実行時に環境変数やSSM Parameter Storeなどの外部サービスから取得する。暗号化ストレージは許容されるが、復号化キーをプロジェクトに含めてはいけない)

解説

APIキーやパスワードなどの機密情報をソースコードに直接記述することは、重大なセキュリティリスクです。コードリポジトリが漏洩した場合、即座に悪用される可能性があります。環境変数や外部の秘密管理サービスを使用することで、機密情報とコードを分離し、アクセス制御が可能になります。暗号化する場合も、復号化キーを同じリポジトリに含めては意味がありません。

具体例

// 悪い例
const APIKey = "sk_live_1234567890abcdef"  // ハードコード

func callExternalAPI() {
    client := NewAPIClient(APIKey)
    client.Request()
}

// 良い例
func callExternalAPI() {
    apiKey := os.Getenv("API_KEY")  // 環境変数から取得
    if apiKey == "" {
        log.Fatal("API_KEY not set")
    }
    client := NewAPIClient(apiKey)
    client.Request()
}

// さらに良い例(AWS SSM使用)
func getAPIKey() (string, error) {
    sess := session.Must(session.NewSession())
    svc := ssm.New(sess)

    param, err := svc.GetParameter(&ssm.GetParameterInput{
        Name:           aws.String("/myapp/api_key"),
        WithDecryption: aws.Bool(true),
    })
    if err != nil {
        return "", err
    }
    return *param.Parameter.Value, nil
}

参考リンク

ルール

Never open repositories containing sensitive information in LLM-integrated editors

(機密情報を含むリポジトリをLLM統合エディタで開かない)

解説

LLMを統合したエディタは、開いたファイル内容がクラウドサービスへ送信される可能性があります。うっかり機密情報を外部に流してしまわないよう、機密情報を含むリポジトリはLLM統合エディタでは開かないようにします。

暗号化していれば別ですが、その場合は復号するための鍵がLLM統合エディタの手の届かないようにします。もちろん復号した後の平文のテキストがLLM統合エディタから開ける状態もNGです。

サンプルコード

MARPは、Markdownでプレゼンテーションスライドを作成できる便利なツールです。シンプルなテキストファイルから、美しいスライドを生成できます。

PowerPoint出力

以下のコマンドでMarkdownファイルをPowerPoint形式に変換できます。

docker run -v $(pwd):/home/marp/app/ marpteam/marp-cli marp.md --pptx

このコマンドは、現在のディレクトリにあるmarp.mdファイルを読み込み、同じディレクトリにPowerPointファイル(.pptx)を生成します。Dockerを使用することで、環境構築の手間なく簡単に変換できます。

マークダウンのサンプル


---
marp: true
theme: gaia # default
paginate: true
---

# タイトルスライド

## 副題などを書くこともできます

---

## アジェンダ

- トピック1
- トピック2
- トピック3

---

## トピック1

ここに詳細な説明を書きます。

- ポイント1
- ポイント2

---

## トピック2

画像の例:

![画像の説明](https://placehold.jp/400x300.png)

---

## まとめ

- 要点の復習
- 今後のステップ

---

## ご清聴ありがとうございました 🙏

質問があればどうぞ!

画像と音声を動画に変換

GCPのText to Speech等を使って作成した音声と、スライド画像を合成して動画にすることもできます

自分は普段Windowsを使っていて、開発もWSL上のUbuntuを使っています。簡単にLinuxを使えてとても便利です。

が、初期状態ではWindowsのCドライブ全体が/mnt/cにマウントされています。手軽に使えはするものの、WSL上で外部から取得したツールやAIエージェントを利用する場合、この設定は考え物です。何かの拍子に機密重要を含むファイルにアクセスされたり破壊されたりするわけにいきません。

そこでWSLからは必要なディレクトリしか見られないよう制限をかけました。

※ディレクトリ名は仮の名前を使用しています。

og

リスクのあるツールには必要なディレクトリだけ見せる

設定

1. Linux(WSL)で設定

Linux側で、/etc/wsl.confにautomountとinteropの項目を追加します。

~$ cat /etc/wsl.conf

[automount]
enabled = false

[interop]
appendWindowsPath = false

automountの項目だけでは下記のようなエラーが出たため、interopの項目を追加しています。

<3>WSL (346 - Relay) ERROR: UtilTranslatePathList:2878: Failed to translate C:\windows\system32

また、起動時に自動でマウントされるよう/etc/fstabに設定を追加します。

~$ cat /etc/fstab
# UNCONFIGURED FSTAB FOR BASE SYSTEM

C:/example/mydir /mnt/c/example/mydir drvfs metadata,notime,gid=1000,uid=1000,defaults 0 0

~$

2. WindowsからLinux(WSL)を再起動

Windows側に戻ってWSLを再起動。

wsl -t Ubuntu

wsl

3. Linux(WSL)上で確認

下記のように、必要なディレクトリだけが見えているようになっていれば成功です。

~$ ls /mnt/c
example

権限は絞っておくと安心

以上、Linux(WSL)からアクセスできるWindowsのファイルを制限する方法をご紹介しました。

セキュリティは使い勝手とのトレードオフになりがちです。しかし、アクセス制限が適切に設定されていることで信頼性に若干の不安があるツールも利用しやすくなる、という側面もあります。あらかじめ保険をかけていれば、「このツール、絶対便利だけどちょっとセキュリティに不安が……」と感じる場面でも積極的にリスクを取っていけるわけです。

「攻めための守備」として、アクセス権限の制限は一つの解法になりえます。

参考

ChatGPTと下記ページを参考にしました。