Skip to main content

DB 안전 가드

MSK는 Laravel Core와 루트 Makefile 두 계층에서 파괴적 DB 명령을 차단합니다. 목적은 AI 에이전트, 운영자, 개발자가 실수로 운영 DB 또는 장기 보존 데이터가 들어 있는 개발 DB를 초기화하지 못하게 막는 것입니다.

차단 대상​

다음 Artisan 명령은 기본적으로 차단됩니다.

명령위험
migrate:fresh모든 테이블 삭제 후 재생성
migrate:refresh전체 롤백 후 재실행
migrate:reset전체 마이그레이션 롤백
db:wipeDB 테이블/뷰/타입 삭제
schema:dump --prune스키마 덤프 후 기존 migration 정리

migrate, migrate:status, db:seed처럼 데이터를 대량 삭제하지 않는 명령은 차단하지 않습니다.

적용 계층​

Laravel Core​

App\Core\Base\Database\Providers\DatabaseSafetyServiceProvider가 Artisan CommandStarting 이벤트를 감시합니다. 프로젝트가 Core를 symlink로 사용하면 모든 프로젝트에 동일하게 적용됩니다.

핵심 구현:

  • DestructiveCommandGuard가 명령 이름과 옵션을 판정
  • core.database.blocked_commands로 추가 차단 명령을 지정 가능
  • 위 기본 차단 명령은 config에서 제거해도 항상 차단
  • config cache에 고정되지 않도록 unlock token은 런타임 환경변수에서 직접 읽음

Makefile​

루트 make artisan과 make fresh도 Docker 실행 전에 동일한 명령을 사전 차단합니다. Makefile guard는 편의와 조기 실패를 위한 1차 방어선이고, 최종 방어선은 Laravel Core guard입니다.

make artisan NAME=template.codebase.how CMD="migrate:status"

위 명령은 허용됩니다.

make fresh NAME=template.codebase.how

위 명령은 기본 차단됩니다.

예외 허용​

정말 DB 초기화가 필요한 경우에는 명령별 1회성 unlock token을 해당 실행에만 주입합니다.

MSK_ALLOW_DESTRUCTIVE_ARTISAN="MSK-ALLOW-DB-DESTRUCTIVE:migrate:fresh" \
make artisan NAME=template.codebase.how CMD="migrate:fresh --seed"

주의사항:

  • token은 명령별로만 유효합니다. migrate:fresh token으로 db:wipe는 실행할 수 없습니다.
  • token을 .env에 상시 저장하지 않습니다.
  • 운영 서버에서는 token 사용 전에 백업, 대상 DB, 서버 단계를 먼저 확인합니다.

테스트 환경​

Laravel RefreshDatabase는 PHPUnit 실행 중 APP_ENV=testing에서 내부적으로 migrate:fresh를 호출할 수 있습니다. 이 경로만 허용됩니다.

테스트 안전성은 DB 안전 가드만으로 완성되지 않습니다. tests/TestCase와 phpunit.xml에서 테스트 DB가 별도 DB 또는 SQLite in-memory를 사용하도록 강제해야 합니다. 운영 DB를 가리키는 테스트 실행은 금지합니다.

한계와 보완​

DB 안전 가드는 Laravel Artisan과 루트 Makefile 경로를 보호합니다. 다음 경로는 별도 운영 정책과 DB 권한 분리로 막아야 합니다.

  • psql 등 DB CLI에서 직접 실행하는 TRUNCATE, 조건 없는 DELETE
  • 애플리케이션 밖에서 실행되는 임의 스크립트
  • 운영 DB 사용자에게 과도한 DDL 권한을 부여한 경우

권장 운영 방식:

  • 일반 앱 DB 계정은 운영에서 최소 권한으로 운용
  • 스키마 변경은 Laravel migration으로만 수행
  • 백업/복구 절차를 먼저 확인한 뒤 파괴적 명령 token 사용

관련 코드​

  • platform/web/laravel/core/Base/Database/Providers/DatabaseSafetyServiceProvider.php
  • platform/web/laravel/core/Base/Database/Services/DestructiveCommandGuard.php
  • ops/makefile/_common.mk
  • ops/makefile/database.mk
  • ops/makefile/utils.mk