---
sidebar_label: "監査ログ"
title: "監査ログ - CyberGo env | セキュリティ監査設定"
description: "CyberGo env 監査ログ設定ガイド。JSONAuditHandler・LogAuditHandler・ChannelAuditHandler の 3 種ハンドラーとカスタム AuditHandler で変数の読み込み・読み取り・変更・削除を記録し、セキュリティ監査とコンプライアンスに活用します。"
sidebar_position: 5
---

# 監査ログ

監査ログ機能はすべての環境変数操作を記録し、セキュリティ監査、コンプライアンスチェック、トラブルシューティングに使用します。

## 監査の有効化

### 設定による有効化

```go
cfg := env.ProductionConfig()
cfg.AuditEnabled = true
cfg.AuditHandler = env.NewJSONAuditHandler(os.Stdout)

loader, _ := env.New(cfg)
```

### 設定プリセット

| プリセット | 監査状態 |
|------|----------|
| `DefaultConfig()` | 無効 |
| `DevelopmentConfig()` | 無効 |
| `TestingConfig()` | 無効 |
| `ProductionConfig()` | 有効 |

---

## 監査ハンドラー

### JSONAuditHandler

JSON フォーマットのログを出力：

```go
import (
    "os"
    "github.com/cybergodev/env"
)

cfg := env.ProductionConfig()
cfg.AuditEnabled = true
cfg.AuditHandler = env.NewJSONAuditHandler(os.Stdout)
```

**出力例：**

```json
{"timestamp":"2024-01-15T10:30:00Z","action":"load","file":".env","success":true,"duration_ns":1234567}
{"timestamp":"2024-01-15T10:30:01Z","action":"set","key":"[MASKED:7 chars]","success":true,"masked":true}
{"timestamp":"2024-01-15T10:30:02Z","action":"set","key":"CUSTOM_VAR","success":true}
```

機密キー（例：`API_KEY`）は監査ログの `key` フィールドで自動的に `[MASKED:N chars]`（N はキーの文字数）にマスクされ、非機密キー（例：`CUSTOM_VAR`）はそのまま表示されます。

---

### LogAuditHandler

標準 log パッケージを使用して出力：

```go
import (
    "log"
    "os"
    "github.com/cybergodev/env"
)

logger := log.New(os.Stderr, "[AUDIT] ", log.LstdFlags)
cfg.AuditHandler = env.NewLogAuditHandler(logger)
```

**出力例：**

```text
[AUDIT] 2024/01/15 10:30:00 action=load success=true reason="" file=.env duration=1.23ms
[AUDIT] 2024/01/15 10:30:01 action=set key=[MASKED:7 chars] success=true reason=""
[AUDIT] 2024/01/15 10:30:02 action=set key=CUSTOM_VAR success=true reason=""
```

---

### ChannelAuditHandler

チャネルに送信して非同期処理：

```go
ch := make(chan env.AuditEvent, 100)
cfg.AuditHandler = env.NewChannelAuditHandler(ch)

// 非同期処理監査イベント
go func() {
    for event := range ch {
        processAuditEvent(event)
    }
}()
```

**ユースケース：**
- リモートログサービスに送信
- データベースに書き込み
- リアルタイム監視アラート

---

### NopAuditHandler

何もしないハンドラー、すべてのイベントを破棄：

```go
cfg.AuditHandler = env.NewNopAuditHandler()
```

**ユースケース：**
- 監査を一時的に無効化
- テスト環境

---

## 監査イベント

### AuditEvent 構造体

```go
type AuditEvent struct {
    Timestamp time.Time   // タイムスタンプ
    Action    AuditAction // 操作タイプ
    Key       string      // キー名
    File      string      // ファイル名
    Reason    string      // 理由
    Success   bool        // 成功したかどうか
    Masked    bool        // マスクされているか
    Details   string      // 詳細
    Duration  int64       // 所要時間（ナノ秒）
}
```

### AuditAction 操作タイプ

| 定数 | 値 | 説明 |
|------|---|------|
| `ActionLoad` | `load` | ファイル読み込み |
| `ActionParse` | `parse` | 解析操作 |
| `ActionGet` | `get` | 変数読み取り |
| `ActionSet` | `set` | 変数設定 |
| `ActionDelete` | `delete` | 変数削除 |
| `ActionValidate` | `validate` | 検証操作 |
| `ActionExpand` | `expand` | 変数展開 |
| `ActionSecurity` | `security` | セキュリティイベント |
| `ActionError` | `error` | エラーイベント |
| `ActionFileAccess` | `file_access` | ファイルアクセス |

---

## カスタムハンドラー

### FullAuditLogger インターフェースの実装

`FullAuditLogger` は完全な監査ログインターフェースで、最小インターフェース `AuditLogger`（LogError メソッドのみを含む）を拡張します：

```go
type FullAuditLogger interface {
    AuditLogger  // 最小インターフェースを埋め込み（LogError）
    Log(action AuditAction, key, reason string, success bool) error
    LogWithFile(action AuditAction, key, file, reason string, success bool) error
    LogWithDuration(action AuditAction, key, reason string, success bool, duration time.Duration) error
    Close() error
}
```

### 例：データベース監査ハンドラー

```go
package myhandler

import (
    "database/sql"
    "time"
    "github.com/cybergodev/env"
)

type DatabaseAuditHandler struct {
    db *sql.DB
}

func NewDatabaseAuditHandler(db *sql.DB) *DatabaseAuditHandler {
    return &DatabaseAuditHandler{db: db}
}

func (h *DatabaseAuditHandler) Log(action env.AuditAction, key, reason string, success bool) error {
    _, err := h.db.Exec(`
        INSERT INTO audit_log (timestamp, action, key, reason, success)
        VALUES (?, ?, ?, ?, ?)
    `, time.Now(), string(action), key, reason, success)
    return err
}

func (h *DatabaseAuditHandler) LogError(action env.AuditAction, key, errMsg string) error {
    return h.Log(action, key, errMsg, false)
}

func (h *DatabaseAuditHandler) LogWithFile(action env.AuditAction, key, file, reason string, success bool) error {
    _, err := h.db.Exec(`
        INSERT INTO audit_log (timestamp, action, key, file, reason, success)
        VALUES (?, ?, ?, ?, ?, ?)
    `, time.Now(), string(action), key, file, reason, success)
    return err
}

func (h *DatabaseAuditHandler) LogWithDuration(action env.AuditAction, key, reason string, success bool, duration time.Duration) error {
    _, err := h.db.Exec(`
        INSERT INTO audit_log (timestamp, action, key, reason, success, duration_ms)
        VALUES (?, ?, ?, ?, ?, ?)
    `, time.Now(), string(action), key, reason, success, duration.Milliseconds())
    return err
}

func (h *DatabaseAuditHandler) Close() error {
    return nil
}
```

---

## 完全な例

### 本番環境設定

```go
package main

import (
    "log"
    "os"
    "github.com/cybergodev/env"
)

func main() {
    // 監査ログファイルを作成
    auditFile, err := os.OpenFile("/var/log/app/env-audit.log",
        os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
    if err != nil {
        log.Fatal(err)
    }
    defer auditFile.Close()

    // 設定
    cfg := env.ProductionConfig()
    cfg.AuditEnabled = true
    cfg.AuditHandler = env.NewJSONAuditHandler(auditFile)
    cfg.RequiredKeys = []string{"DB_HOST", "API_KEY"}

    // ローダーの作成
    loader, err := env.New(cfg)
    if err != nil {
        log.Fatal(err)
    }
    defer loader.Close()

    // 設定を読み込み
    err = loader.LoadFiles(".env")
    if err != nil {
        log.Fatal(err)
    }

    // 検証
    err = loader.Validate()
    if err != nil {
        log.Fatal(err)
    }

    // 設定を使用
    log.Println("Configuration loaded successfully")
}
```

### 非同期監査処理

```go
package main

import (
    "encoding/json"
    "log"
    "os"
    "github.com/cybergodev/env"
)

func main() {
    // 監査イベントチャネルを作成
    auditChan := make(chan env.AuditEvent, 1000)

    // 非同期プロセッサーを起動
    go processAuditEvents(auditChan)

    // 設定
    cfg := env.ProductionConfig()
    cfg.AuditEnabled = true
    cfg.AuditHandler = env.NewChannelAuditHandler(auditChan)

    loader, _ := env.New(cfg)
    defer loader.Close()

    // 通常の使用...
}

func processAuditEvents(ch chan env.AuditEvent) {
    file, _ := os.OpenFile("/var/log/app/audit.log",
        os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
    defer file.Close()

    encoder := json.NewEncoder(file)

    for event := range ch {
        // フィルタリング、集計などのロジックを追加可能
        if event.Action == env.ActionError {
            log.Printf("Audit error: %+v", event)
        }

        encoder.Encode(event)
    }
}
```

---

## セキュリティ上の注意

### 監査記録とマスク

監査ログは機密キーの `key` フィールドを自動的にマスクします（デフォルトでは `[MASKED:N chars]` と表示、N はキー名の文字数。非機密キーはそのまま表示）。**書き込み操作のみが監査イベントを記録します**：`Set` / `Delete` / `LoadFiles` などは `ActionSet` / `ActionDelete` / `ActionLoad` などのイベントをトリガーし、イベントにはマスク後のキー名が記録されます。

読み取り操作は監査を生成しません：`Get` / `GetString` / `GetInt` / `GetSecure` などの**正常な読み取りは監査ログに記録されません**。`ActionGet` イベントは `GetInt` / `GetBool` / `GetFloat64` などの型変換**解析失敗**のエラーパス（`success=false`）でのみトリガーされます。例：

```go
// 書き込み操作：監査イベントを記録（機密キーはマスク後に記録）
_ = loader.Set("API_KEY", "sk-1234567890")
// 監査記録：{"action":"set","key":"[MASKED:7 chars]","success":true,"masked":true}

// 読み取り操作：正常な読み取りは監査を生成しない
secret := loader.GetSecure("API_KEY") // 監査ログを生成しない
_ = loader.GetInt("PORT")             // 解析成功、監査ログを生成しない
_ = loader.GetInt("API_KEY")          // 解析失敗時に ActionGet イベントを生成（success=false）
```

### 監査ログの権限

```bash
# 監査ログファイルの権限を設定
chmod 600 /var/log/app/env-audit.log

# アプリケーションユーザーのみが読み書き可能であることを保証
chown app:app /var/log/app/env-audit.log
```

### ログローテーション

logrotate を使用した監査ログの管理を推奨：

```bash
# /etc/logrotate.d/app-env-audit
/var/log/app/env-audit.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    create 0600 app app
}
```

---

## 関連ドキュメント

- [セキュリティ概要](/ja/env/security/) - セキュリティアーキテクチャとコア機能
- [本番チェックリスト](/ja/env/security/production-checklist) - 監査設定の確認
- [インターフェース定義](/ja/env/api-reference/interfaces) - AuditLogger インターフェース
- [コンポーネントファクトリー](/ja/env/api-reference/factory) - 監査ハンドラーファクトリー
