개발자에게 운영 DB 권한을 어디까지 줄 것인가
전면 차단도 전면 허용도 실무에서 지속되지 않는다. 단계별 권한 분리와 감사 기록.
양 극단이 지속되지 않는 이유
전면 차단: 장애가 났을 때 원인을 볼 수 없다. 결국 예외 경로가 생기고, 그 경로가 관리되지 않는다.
전면 허용: 실수 한 번의 비용이 크다. WHERE 없는 UPDATE 하나로 전체 행이 바뀐다.
현실적인 방향은 권한을 나누고 기록을 남기는 것이다.
단계별 분리
| 등급 | 권한 | 대상 |
|---|---|---|
| 1 | 복제본 읽기 (마스킹) | 전체 개발자 |
| 2 | 운영 읽기 | 담당 영역 개발자 |
| 3 | 운영 쓰기 (승인 후 임시) | 장애 대응 |
| 4 | 스키마 변경 | 배포 파이프라인 |
4등급이 사람이 아니라 파이프라인이라는 점이 중요하다. 스키마 변경은 코드로 관리되어야 리뷰와 이력이 남는다.
1등급 — 복제본을 기본으로
대부분의 조회는 복제본에서 가능하다. 이점:
- 운영 부하에 영향 없음
- 실수로 쓰기가 나갈 수 없음
- 개인정보를 마스킹한 버전을 제공 가능
"운영 데이터를 봐야 한다"는 요구의 상당수가 복제본으로 충족된다.
2등급 — 읽기도 완전히 안전하지는 않다
읽기 전용 계정에서도 두 가지 위험이 남는다.
1. 개인정보 조회
권한이 있다고 봐도 되는 것은 아니다. 접근 기록이 남아야 하고, 필요 최소 범위 원칙이 적용돼야 한다.
2. 대량 쿼리 부하
```sql
SELECT * FROM events; -- 수억 행
```
읽기만으로도 운영에 영향을 준다. 타임아웃과 결과 크기 제한을 계정 수준에서 걸어두는 방법이 있다.
3등급 — 임시 권한
운영 쓰기가 필요한 경우는 실제로 있다. 잘못된 데이터를 고쳐야 하거나, 장애 대응 중이거나.
관리 방식:
```
- 요청 (사유 명시)
- 승인 (다른 사람)
- 시간 제한 부여 (예: 2시간)
- 자동 만료
- 실행 내역 기록
```
4번이 핵심이다. 수동 회수는 대부분 잊힌다. 시간이 지나면 자동으로 사라지는 구조여야 한다.
감사 기록
무엇을 남길 것인가:
- 누가, 언제, 어떤 쿼리를
- 결과 행 수
- 접근한 테이블 (특히 개인정보 포함 테이블)
기록의 목적은 처벌이 아니라 사고 시 추적이다. 무엇이 언제 바뀌었는지 알 수 있으면 복구가 빨라진다.
실수를 줄이는 습관
권한 구조와 별개로, 개인 차원의 방어책이 있다.
1. 프롬프트 색상 구분
운영 연결은 빨간색으로 표시되게 설정한다. 어느 DB에 붙어 있는지 착각하는 사고가 실제로 흔하다.
2. SELECT 먼저
```sql
-- 1) 먼저 대상 확인
SELECT COUNT(*) FROM orders WHERE ...;
-- 2) 예상과 맞으면 UPDATE
```
3. 트랜잭션으로 감싸기
```sql
BEGIN;
UPDATE ...;
-- 결과 확인 후 COMMIT 또는 ROLLBACK
```
4. 자동 커밋 끄기
클라이언트 설정에서 auto-commit을 꺼두면 실수한 문장을 되돌릴 여지가 생긴다.
도구 쪽에서 할 수 있는 것
DB 클라이언트를 고를 때 확인할 만한 기능:
- 연결별 환경 표시(색상·라벨)
- 읽기 전용 모드
- WHERE 없는 UPDATE·DELETE 경고
- 결과 행 수 제한
- 쿼리 실행 이력
이런 장치가 있으면 권한 구조가 느슨해도 사고 확률이 크게 준다.
최종 수정 2026-08-28