# バッチ設計書 9-secrets:remove

## 概要

本ドキュメントは、Symfonyフレームワークが提供する `secrets:remove` コンソールコマンドのバッチ設計書である。暗号化されたVaultからシークレット（機密情報）を削除する処理の仕様を定義する。

### 本バッチの処理概要

`secrets:remove` コマンドは、Symfonyのシークレット管理システム（Vault）から指定されたシークレットを削除する。メインVaultまたはローカルVaultを対象として選択可能である。

**業務上の目的・背景**：不要になったシークレットや、セキュリティ上の理由で無効化が必要なシークレットをVaultから安全に削除するために使用する。例えば、外部サービスのAPIキーをローテーションした後に旧キーを削除する、使用されなくなった機能に関連するシークレットをクリーンアップするといったユースケースに対応する。ローカルVaultからの削除により、開発環境固有のオーバーライドを解除することも可能である。

**バッチの実行タイミング**：シークレットの無効化・削除が必要になった場合に随時実行される。セキュリティインシデント対応時やアプリケーション設定の整理時に使用される。

**主要な処理内容**：
1. 引数からシークレット名を取得し、対象Vault（メインまたはローカル）を決定
2. ローカルVault使用時のVault有効性確認
3. Vaultの `remove()` メソッドでシークレットを削除
4. 削除結果に応じて成功メッセージまたは不在メッセージを出力
5. メインVaultから削除した場合、ローカルVaultにオーバーライドが存在すればその旨を通知

**前後の処理との関連**：`secrets:list` で削除対象のシークレットを確認してから実行することが推奨される。`secrets:set` で設定したシークレットを削除する逆の操作にあたる。

**影響範囲**：指定されたVault内の1つのシークレットのみが削除される。アプリケーションの設定ファイルで `%env(SECRET_NAME)%` として参照されている場合、削除後にアプリケーションが正常に動作しなくなる可能性がある。

## バッチ種別

シークレット管理 / セキュリティ設定コマンド

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時 |
| 実行時刻 | 任意 |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | 手動 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Vault設定 | シークレット管理（Vault）が設定済みであること |
| ローカルVault使用時 | ローカルVaultが有効であること |

### 実行可否判定

`--local` オプション指定時にローカルVaultが無効（null）の場合、エラーメッセージを出力して終了コード1を返す。シークレットが存在しない場合でもエラーにはならず、コメントメッセージを出力して終了コード0を返す。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| name | string | Yes | なし | 削除するシークレット名 |
| --local / -l | bool | No | false | ローカルVaultから削除する |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| AbstractVault (vault) | サービス | メインVault |
| AbstractVault (localVault) | サービス | ローカルVault（オプション） |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| stderr | テキスト | 処理メッセージ（SymfonyStyleはstderrに出力） |

### 出力ファイル仕様

該当なし（Vault内の暗号化ファイルが削除される）

## 処理フロー

### 処理シーケンス

```
1. 引数・オプション解析
   └─ シークレット名と--localオプションを取得
2. 対象Vault決定
   └─ --local指定時はローカルVault、未指定時はメインVault
3. Vault有効性確認
   └─ ローカルVault指定時にnullならエラー終了
4. シークレット削除
   └─ vault.remove()を呼び出し
5. 結果出力
   └─ 成功時: 成功メッセージ、不在時: コメントメッセージ
6. ローカルオーバーライド確認
   └─ メインVault削除時、ローカルVaultにオーバーライドがあれば注意メッセージ
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[name引数と--localオプション取得]
    B --> C{--local指定?}
    C -->|Yes| D{ローカルVault有効?}
    C -->|No| E[メインVaultを使用]
    D -->|No| F[エラー: ローカルVault無効・終了コード1]
    D -->|Yes| G[ローカルVaultを使用]
    E --> H[vault.remove 実行]
    G --> H
    H --> I{削除成功 true?}
    I -->|Yes| J[成功メッセージ出力]
    I -->|No| K[コメント: シークレット不在]
    J --> L{メインVaultから削除?}
    K --> L
    L -->|Yes| M{ローカルVaultにオーバーライド存在?}
    L -->|No| N[バッチ終了 コード0]
    M -->|Yes| O[注意メッセージ出力]
    M -->|No| N
    O --> N
```

## データベース操作仕様

### 操作別データベース影響一覧

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 該当なし | - | - | データベース操作なし（ファイルベースのVault） |

### テーブル別操作詳細

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 終了コード1 | Vault無効 | ローカルVaultが無効（null） | Vault設定を確認する |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

### 障害時対応

1. ローカルVaultが無効の場合は、`framework.secrets` の設定を確認する。
2. シークレットが存在しない場合は正常終了となるため、特段の対応は不要。

## トランザクション仕様

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 単一シークレットの削除操作 |
| コミットタイミング | remove()完了時 |
| ロールバック条件 | 該当なし |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1件（単一シークレット） |
| 目標処理時間 | ミリ秒単位（即座に完了） |
| メモリ使用量上限 | 最小限 |

## 排他制御

Vaultファイルへの同時アクセスに対する明示的な排他制御はコマンド内には実装されていない。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 成功ログ | 削除成功時 | Vaultからのメッセージまたは `Secret was removed from the vault.` |
| 情報ログ | シークレット不在時 | Vaultからのメッセージまたは `Secret was not found in the vault.` |
| 注意ログ | ローカルオーバーライド存在時 | `Note that this secret is overridden in the local vault.` |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 終了コード | 0以外 | 運用監視システム |

## 備考

- シェル補完機能をサポートしている。シークレット名の入力時にVault内の既存シークレット名が候補として表示される。
- `--local` オプション指定時の補完候補は、メインVaultとローカルVaultの両方に存在するシークレット名の積集合（array_intersect）となる。
- シークレットが存在しない場合でも終了コードは0（成功）であり、べき等性を持つ設計となっている。
- メッセージ出力はstderrに送信される（`ConsoleOutputInterface::getErrorOutput()` 使用）。
- 本コマンドは `@internal` マーク付きであり、フレームワーク内部使用を前提としている。
- ソースコード: `src/Symfony/Bundle/FrameworkBundle/Command/SecretsRemoveCommand.php`
