背景
PR #45(feat/production-destructive-guard)で POST /api/test/reset の破壊的操作を HTTP 経路でガードした(dev.only middleware = APP_MODE + APP_ENV の二重チェック、拒否監査、さらに未認証対策の共有 secret を追加予定)。
しかし、この防御は HTTP ルートに閉じている。実処理は最終的に:
Artisan::call('migrate:fresh', ['--seed' => true, '--force' => true]);
であり、php artisan migrate:fresh や Tinker から直接呼べば HTTP ガードは全て素通りする。これは #36(tinker 経由の破壊的 DB 操作で開発用 DB の実ユーザーを全削除)と同じ到達経路であり、多層防御としては HTTP 層だけでは不十分。
ゴール
CLI / Tinker 経由でも、production-mode(または環境不一致)では破壊的な全消去に到達できないようにする。
対応方針(案)
いずれか、または併用:
- コマンド境界ガード: 破壊的 Artisan コマンド(
migrate:fresh / migrate:refresh / db:wipe 等)を実行する前段で APP_MODE + APP_ENV を検査し、production-mode/環境不一致なら中断する。
- 例: 破壊的コマンドをラップする共通処理、または
Event::listen(CommandStarting::class, ...) でのガード
- 共通サービス層ガード: reset 実処理を service に集約し、その入口で
AppMode チェックを必須化する。HTTP controller / Artisan 双方がこのサービスを経由する形にする。
完了条件
- production-mode(または
APP_ENV が local/testing 以外)では、artisan migrate:fresh 相当の破壊的コマンドが CLI からも拒否される
- 拒否は既存の監査ログ(
operation_audit_logs、result=failure + failure_reason)に記録される
- dev-mode + local/testing では従来どおり通過する
- CLI 拒否/通過を検証するテストを追加
関連
背景
PR #45(
feat/production-destructive-guard)でPOST /api/test/resetの破壊的操作を HTTP 経路でガードした(dev.onlymiddleware = APP_MODE + APP_ENV の二重チェック、拒否監査、さらに未認証対策の共有 secret を追加予定)。しかし、この防御は HTTP ルートに閉じている。実処理は最終的に:
であり、
php artisan migrate:freshや Tinker から直接呼べば HTTP ガードは全て素通りする。これは #36(tinker 経由の破壊的 DB 操作で開発用 DB の実ユーザーを全削除)と同じ到達経路であり、多層防御としては HTTP 層だけでは不十分。ゴール
CLI / Tinker 経由でも、production-mode(または環境不一致)では破壊的な全消去に到達できないようにする。
対応方針(案)
いずれか、または併用:
migrate:fresh/migrate:refresh/db:wipe等)を実行する前段で APP_MODE + APP_ENV を検査し、production-mode/環境不一致なら中断する。Event::listen(CommandStarting::class, ...)でのガードAppModeチェックを必須化する。HTTP controller / Artisan 双方がこのサービスを経由する形にする。完了条件
APP_ENVが local/testing 以外)では、artisan migrate:fresh相当の破壊的コマンドが CLI からも拒否されるoperation_audit_logs、result=failure + failure_reason)に記録される関連