メインコンテンツまでスキップ

セキュリティ設計ドキュメント

このドキュメントでは、secretctl のセキュリティアーキテクチャ、設計決定、実装詳細の包括的な概要を提供します。セキュリティ意識の高いユーザー、監査者、コントリビューター向けです。

エグゼクティブサマリー

secretctl は以下のコア原則で多層防御セキュリティアーキテクチャを実装しています:

原則実装
AI安全設計AI エージェントは平文シークレットを受け取らない
ローカルファーストクラウド依存なし、すべてのデータはマシン上に
標準暗号AES-256-GCM + Argon2id(OWASP 準拠)
最小信頼Go stdlib + golang.org/x/crypto のみ
完全な監査可能性HMAC チェーンによる改ざん検出可能なログ

アーキテクチャ概要

┌─────────────────────────────────────────────────────────────────────────────┐
│ secretctl セキュリティアーキテクチャ │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ アクセス層 │ │
│ │ │ │
│ │ CLI デスクトップアプリ MCP サーバー │ │
│ │ ──── ────────────── ────────── │ │
│ │ 人間信頼 人間信頼 AI 信頼 │ │
│ │ フルアクセス フルアクセス 制限付き │ │
│ │ (AI安全設計) │ │
│ └──────────────────────────────┬──────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────┴──────────────────────────────────────┐ │
│ │ ポリシー層 │ │
│ │ │ │
│ │ MCP ポリシーエンジン コマンド検証 レート制限 │ │
│ │ ───────────────── ────────────── ───────────── │ │
│ │ allowed_keys blocked_commands 5同時実行 │ │
│ │ denied_keys タイムアウト強制 最大実行数 │ │
│ │ capabilities 非TTYモード │ │
│ └──────────────────────────────┬──────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────┴──────────────────────────────────────┐ │
│ │ 暗号層 │ │
│ │ │ │
│ │ 鍵導出 暗号化 整合性 │ │
│ │ ────────── ────────── ───────── │ │
│ │ Argon2id AES-256-GCM HMAC-SHA256 │ │
│ │ 64MBメモリ ランダムnonce チェーン検証 │ │
│ │ 3イテレーション シークレットごと │ │
│ │ 4スレッド │ │
│ └──────────────────────────────┬──────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────┴──────────────────────────────────────┐ │
│ │ ストレージ層 │ │
│ │ │ │
│ │ vault.db (0600) vault.salt (0600) audit.log (0600) │ │
│ │ ───────────────── ──────────────── ──────────────── │ │
│ │ 暗号化シークレット 128ビットランダム HMACチェーン │ │
│ │ 暗号化DEK Vaultごと 改ざん検出 │ │
│ │ メタデータ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

鍵階層

secretctl は防御を深めるために3層の鍵階層を使用します:

ユーザー入力: マスターパスワード

▼ Argon2id (m=64MB, t=3, p=4, salt=128ビット)

マスターキー (256ビット、メモリのみ)

▼ AES-256-GCM 暗号化/復号

データ暗号化キー (256ビット、暗号化して保存)

▼ AES-256-GCM 暗号化/復号

暗号化されたシークレット (SQLite に保存)

設計の理由

レイヤー目的セキュリティ特性
マスターパスワードユーザー認証保存されない、復元不可
マスターキーDEK を保護永続化されない、アンロック時に導出
DEKシークレットを暗号化再暗号化なしでパスワードローテーション可能
暗号化シークレット保護されたデータGCM による機密性 + 整合性

パスワードローテーションサポート

DEK レイヤーにより、すべてのシークレットを再暗号化せずにパスワード変更が可能:

旧パスワード ─▶ 旧マスターキー ─▶ DEK を復号


新パスワード ─▶ 新マスターキー ─▶ DEK を再暗号化

暗号仕様

Argon2id パラメータ(OWASP 2025 準拠)

パラメータ理由
メモリ64 MBセキュリティとユーザビリティのバランス
イテレーション3インタラクティブ使用に推奨
並列性4典型的な CPU コア数
Salt128 ビットVault ごとにユニーク
出力256 ビットAES-256 キー要件

なぜ Argon2id か?

  • メモリハード: GPU/ASIC 攻撃に耐性
  • ハイブリッド: Argon2i(サイドチャネル耐性)と Argon2d(GPU 耐性)を組み合わせ
  • 標準: パスワードハッシュコンペティション優勝者

AES-256-GCM

プロパティ
キーサイズ256 ビット
Nonce96 ビット、暗号化ごとにランダム
タグ128 ビット
モードGCM(認証付き暗号化)

なぜ AES-256-GCM か?

  • 認証付き: 機密性と整合性の両方を提供
  • 標準: NIST 承認、広く監査済み
  • 高性能: 現代の CPU でハードウェアアクセラレーション

HMAC チェーン(監査ログ)

レコード N:
hmac = HMAC-SHA256(
id || op || key || timestamp || result || prev,
audit_key
)

audit_key = HKDF-SHA256(master_key, "audit-log-v1", 32)

AI安全設計

コア原則

AI エージェントはシークレットを見ずに使用する。

これは 1Password の「Access Without Exposure」哲学に従っています。

実装

┌─────────────────────────────────────────────────────────────────────────────┐
│ AI安全設計実装 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 禁止(未実装) 許可(制限付き) │
│ ════════════════════════ ════════════════════════════ │
│ │
│ secret_get (平文) secret_list (名前のみ) │
│ secret_set (書き込み) secret_exists (メタデータ) │
│ secret_delete (破壊的) secret_get_masked (****WXYZ) │
│ export (一括アクセス) secret_run (環境変数注入) │
│ secret_list_fields (フィールド名) │
│ secret_get_field (非機密) │
│ secret_run_with_bindings │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

secret_run セキュリティレイヤー

AI リクエスト: secret_run(keys=["aws/*"], command="aws s3 ls")


┌─────────────────────────────────────────────────────┐
│ レイヤー 1: 入力検証 │
│ • コマンドブロックリスト (env, printenv, export など) │
│ • キーパターン検証 │
│ • ポリシーエンジンチェック │
└───────────────────────┬─────────────────────────────┘


┌─────────────────────────────────────────────────────┐
│ レイヤー 2: 実行分離 │
│ • クリーンな環境でのサブプロセス │
│ • 非TTYモード強制 │
│ • タイムアウト: 設定可能、最大1時間 │
│ • 一時的な作業ディレクトリ │
└───────────────────────┬─────────────────────────────┘


┌─────────────────────────────────────────────────────┐
│ レイヤー 3: シークレット注入 │
│ • シークレットは環境変数として設定 │
│ • 値はサブプロセスメモリにのみ存在 │
│ • AI コンテキストを通過しない │
└───────────────────────┬─────────────────────────────┘


┌─────────────────────────────────────────────────────┐
│ レイヤー 4: 出力サニタイズ │
│ • stdout/stderr でシークレット値をスキャン │
│ • マッチを [REDACTED:key] で置換 │
│ • レスポンスに sanitized フラグを返却 │
└───────────────────────┬─────────────────────────────┘


AI レスポンス: {"exit_code": 0, "stdout": "bucket1\n", "sanitized": true}

ブロックされたコマンド

環境変数を露出する可能性のあるコマンドはブロック:

var defaultDeniedCommands = []string{
"env", // すべての環境変数を一覧
"printenv", // 環境変数を出力
"set", // 環境を表示するシェル組み込み
"export", // 環境用シェル組み込み
"cat /proc/*/environ", // Linux プロセス環境
}

ポリシーエンジン

設定

ポリシーエンジンは secret_run で実行できるコマンドを制御:

# ~/.secretctl/mcp-policy.yaml
version: 1
default_action: allow # allow | deny
denied_commands: # 常にブロック(デフォルトに追加)
- rm
- dd
allowed_commands: # 明示的に許可(default_action: deny 時)
- aws
- kubectl
env_aliases: # 環境固有のキー解決
dev:
- pattern: "db/*"
target: "db/dev/*"
prod:
- pattern: "db/*"
target: "db/prod/*"

評価順序

  1. デフォルト拒否を最初に: 組み込みブロックコマンドをチェック(env、printenv など)
  2. ユーザー拒否コマンド: denied_commands パターンをチェック
  3. 許可コマンド: default_action: deny の場合、allowed_commands をチェック
  4. デフォルトアクション: 明示的なマッチがない場合 default_action を適用
  5. 監査ログ: アクセス試行を記録
キーレベルアクセス制御

現在のポリシーエンジンはコマンド実行を制御し、キーレベルアクセスは制御しません。フィールド感度(機密 vs 非機密)は AI安全設計を通じて MCP ツールレベルで強制されます。将来のバージョンでキーごとのアクセスポリシーを追加する可能性があります。

監査システム

ログストレージ

監査ログは月次 JSONL ファイルとメタデータファイルとして保存:

~/.secretctl/
├── audit/
│ ├── audit.meta # チェーン状態(シーケンス、prevHash)
│ ├── 2025-01.jsonl # 2025年1月イベント
│ └── 2025-02.jsonl # 2025年2月イベント

ログエントリ構造

{
"v": 1,
"id": "01HQ5E7N8KM...",
"ts": "2025-01-15T10:30:00.123456789Z",
"op": "run",
"key": "aws/credentials",
"key_hmac": "a3f2b1...",
"actor": {
"type": "user",
"source": "mcp",
"session_id": "..."
},
"result": "success",
"ctx": {
"command": "aws s3 ls",
"exit_code": 0
},
"chain": {
"seq": 42,
"prev": "7c8d4e...",
"hmac": "b4e5f6..."
}
}

整合性検証

$ secretctl audit verify
15,234 レコードを検証
✓ チェーン整合性: OK
✓ ギャップは検出されず

# 改ざんが検出された場合:
$ secretctl audit verify
✗ レコード id=01HQ5E7N8K... でチェーン破損
期待される prev: a3f2b1...
実際の prev: 7c8d4e...
アラート: 改ざんの可能性が検出されました

ファイル権限

ファイル権限内容
~/.secretctl/0700Vault ディレクトリ
vault.db0600暗号化シークレット、暗号化DEK、salt(vault_keys テーブル)
vault.salt0600レガシー Argon2 salt(128ビット)、DB に移行
vault.meta0600バージョン、タイムスタンプ
audit/0700監査ログディレクトリ
audit/*.jsonl0600月次 HMAC チェーン監査レコード
audit/audit.meta0600チェーン状態メタデータ
mcp-policy.yaml0600MCP アクセスポリシー

サプライチェーンセキュリティ

最小限の依存関係

secretctl は以下のみを使用:

  • Go 標準ライブラリ
  • golang.org/x/crypto (Argon2, HKDF)
  • modernc.org/sqlite (ストレージ、Pure Go 実装)
  • github.com/spf13/cobra (CLI フレームワーク)

検証

# バイナリチェックサムを検証
sha256sum secretctl-darwin-arm64

# 依存関係をチェック
go list -m all

既知の制限

メモリ保護

Go のガベージコレクターがメモリ割り当てを管理。これは:

  • シークレットがガベージコレクションまでメモリに残る可能性
  • 確実なシークレットのゼロ化は不可能

軽減策: secretctl はシークレットの存在時間とスコープを最小化。

対象外の脅威

業界標準(Vault、1Password、Infisical)と一貫して:

  • Root/カーネルレベルの侵害
  • 物理デバイスアクセス(アンロック時)
  • 弱いマスターパスワード
  • メモリダンプ攻撃

詳細は脅威モデルを参照。

バージョン履歴

バージョンセキュリティ変更
v0.8.xマルチフィールドシークレット、フィールド感度、パスワード変更
v0.7.xAI安全設計用語、secret_get_masked 強化
v0.6.xsecret_run のバインディングサポート
v0.5.x監査ログ HMAC チェーン、出力サニタイズ
v0.4.xMCP サーバー、AI安全設計実装
v0.3.x初期 Argon2id + AES-256-GCM 実装

関連ドキュメント

セキュリティ連絡先

脆弱性を見つけましたか?責任を持って報告してください: