데이터베이스 용어 사전
보안least privilege · GRANT · 역할 · ROLE

최소 권한

각 계정에 꼭 필요한 권한만 주는 원칙. 사고가 났을 때 피해 범위를 구조적으로 제한한다.

각 계정·역할에 업무에 꼭 필요한 권한만 부여하는 원칙. 사고를 막는 게 아니라 사고의 피해 범위를 제한한다.

왜 결정적인가

SQL 인젝션이 뚫렸다

앱 계정이 슈퍼유저 → DROP TABLE · 전체 데이터 유출 · 다른 DB 까지 앱 계정이 SELECT/INSERT/UPDATE 만 → 피해가 그 테이블의 데이터로 한정된다

뚫린 뒤에 차이를 만드는 유일한 장치다.

역할로 묶는다

-- PostgreSQL: 역할에 권한을 모으고 사용자에게 역할을 준다
CREATE ROLE app_read;
GRANT CONNECT ON DATABASE mydb TO app_read;
GRANT USAGE ON SCHEMA public TO app_read;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO app_read;

-- 앞으로 만들어질 테이블에도 자동 적용 (자주 빠뜨리는 부분)
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO app_read;

CREATE USER analytics PASSWORD '...';
GRANT app_read TO analytics;

ALTER DEFAULT PRIVILEGES가 핵심이다 — 없으면 새 테이블이 생길 때마다 권한이 빠져 조회가 안 된다.

-- MySQL
CREATE ROLE 'app_read';
GRANT SELECT ON mydb.* TO 'app_read';
CREATE USER 'analytics'@'%' IDENTIFIED BY '...';
GRANT 'app_read' TO 'analytics'@'%';
SET DEFAULT ROLE ALL TO 'analytics'@'%';   -- 없으면 로그인해도 역할이 비활성이다

실무에서 나누는 계정

  • app_rw — 애플리케이션. SELECT/INSERT/UPDATE/DELETE 만. DDL 없음
  • app_ro — 읽기 전용 복제본 조회 · 리포트
  • migration — DDL 전용. 배포 시에만 쓴다
  • admin — 사람이 직접. 감사 로그와 함께

애플리케이션 계정에 DDL 권한을 주지 않는 것만으로도 인젝션 피해가 크게 줄고, 실수로 마이그레이션이 도는 사고도 막는다.

확인하는 쿼리

-- PostgreSQL: 누가 무엇을 할 수 있나
SELECT grantee, table_name, privilege_type
  FROM information_schema.table_privileges WHERE table_schema = 'public';

-- 슈퍼유저 계정 점검
SELECT rolname, rolsuper, rolcreatedb FROM pg_roles WHERE rolsuper;

-- MySQL
SHOW GRANTS FOR 'app'@'%';
SELECT user, host FROM mysql.user WHERE Super_priv = 'Y';

면접 함정

  • "권한 관리는 보안팀 일" → 애플리케이션 계정 권한은 개발자가 정한다.
  • "편의상 앱 계정에 전권을" → 뚫렸을 때 피해 범위가 곧 그 권한 범위다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 보안·권한 — 인증·인가·암호화·SQL 인젝션