인증·인가: RBAC/ABAC, service account, credential rotation
권한이 올바르다는 것은 어떻게 아는가
데이터 플랫폼을 운영하다 보면 권한과 관련해 비슷한 상황이 반복된다.
- 신입 데이터 엔지니어가 입사했다. 어느 데이터에 접근 권한을 줘야 하는가?
- DAG 파이프라인이 production DB에 쓸 수 있다. 이 service account는 어디까지 접근 가능한가?
- 6개월 전 팀을 이동한 분석가의 old 권한이 아직 남아 있다. 언제 회수해야 하는가?
- production MySQL 비밀번호가 환경변수에 평문으로 들어 있다. 마지막으로 바꾼 게 언제인가?
앞 장의 least privilege 원칙은 "최소 권한을 부여하라"고 했다. 이번 장은 그 원칙을 실제로 구현하는 세 가지 도구인 RBAC, ABAC, service account 설계, 그리고 credential rotation을 다룬다.
1. 인증(Authentication)과 인가(Authorization)의 차이
두 개념을 혼동하면 권한 설계가 어디서 틀렸는지 찾기 어렵다.
| 개념 | 질문 | 예시 |
|---|---|---|
| 인증(Authentication) | "당신이 누구인가?" | 비밀번호, 토큰, 인증서, MFA |
| 인가(Authorization) | "당신이 무엇을 할 수 있는가?" | RBAC 역할, IAM policy, DB grant |
인증이 먼저 이루어지고, 인가가 그 다음이다. 강한 인증(MFA, 단기 토큰, 인증서 기반)이 있어도 인가가 느슨하면 인증된 계정이 원하는 것을 모두 할 수 있다. 반대로 인가가 세밀해도 인증이 약하면 권한이 도용된다.
데이터 플랫폼에서는 두 계층이 모두 여러 곳에 흩어져 있다.
- DB 자체: 사용자/역할/권한, MySQL
GRANT, PostgreSQLROLE - 클라우드 IAM: AWS IAM, GCP IAM, Azure AD
- 데이터 플랫폼 레이어: Airflow connection, Kafka ACL, Spark submit 권한, BI 도구 권한
- 비밀 관리: AWS Secrets Manager, HashiCorp Vault, GCP Secret Manager
모든 계층을 따로 관리하면 일관성이 무너진다. 이상적으로는 IAM을 source of truth로 삼고 DB 권한, 플랫폼 권한이 그 아래에서 동기화된다.
2. RBAC: 역할 기반 접근 통제
RBAC(Role-Based Access Control)는 사용자에게 권한을 직접 부여하는 대신, 역할(role)에 권한을 부여하고 사용자를 역할에 묶는 방식이다. 94% 이상의 조직이 RBAC를 주요 접근 통제 모델로 운영한다.
2.1 DB 레벨 RBAC
PostgreSQL과 MySQL 모두 역할 기반 권한 모델을 기본 제공한다.
PostgreSQL:
-- 역할 생성
CREATE ROLE analytics_reader NOLOGIN;
GRANT SELECT ON ALL TABLES IN SCHEMA mart TO analytics_reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA mart GRANT SELECT ON TABLES TO analytics_reader;
-- 사용자를 역할에 연결
CREATE USER alice WITH LOGIN PASSWORD '...';
GRANT analytics_reader TO alice;MySQL:
CREATE ROLE pipeline_operator;
GRANT SELECT, INSERT, UPDATE ON raw.* TO pipeline_operator;
CREATE USER 'pipeline-svc'@'%' IDENTIFIED BY '...';
GRANT pipeline_operator TO 'pipeline-svc'@'%';
SET DEFAULT ROLE pipeline_operator TO 'pipeline-svc'@'%';역할을 만들 때 두 가지 원칙이 중요하다.
- 역할 이름에 권한 범위와 목적을 담는다:
analytics_reader,finance_readonly,pipeline_raw_writer처럼 읽으면 바로 무엇을 할 수 있는지 알아야 한다. - 역할 수를 적게 유지한다: 역할이 너무 많으면 어느 역할로 어디에 접근하는지 파악이 안 된다. 역할 100개보다 역할 10개에 명확한 의미가 더 낫다.
2.2 클라우드 IAM RBAC
클라우드에서는 IAM 역할을 사용한다. AWS의 경우 IAM role + policy, GCP의 경우 IAM role + predefined/custom role이다.
데이터 플랫폼에서 중요한 패턴은 DB IAM 인증이다. AWS Aurora PostgreSQL, RDS는 IAM 데이터베이스 인증을 지원한다. 이 방식에서 비밀번호는 IAM 외부에 저장되지 않고, 토큰 유효시간은 15분이다. 장기 비밀번호보다 훨씬 안전하다.
3. ABAC: 속성 기반 접근 통제
ABAC(Attribute-Based Access Control)는 역할 대신 사용자·리소스·환경의 속성을 기반으로 접근 여부를 결정한다. RBAC가 "finance analyst 역할이면 접근 가능"이라면, ABAC는 "사용자의 department=finance이고, 리소스의 classification=confidential이고, 요청 시간이 업무 시간 내"라면 접근을 허용하는 방식이다.
| 속성 유형 | 예시 |
|---|---|
| 사용자 속성 | department, team, clearance_level, location |
| 리소스 속성 | data_classification, owner_team, region, sensitivity |
| 환경 속성 | time_of_day, request_source_ip, device_type |
| 액션 속성 | read, write, export, delete |
ABAC의 강점은 세밀한 정책이다. "EU 팀원만 EU 고객 PII 데이터에 접근 가능", "classification=restricted인 테이블은 data_owner와 security_team만 접근 가능", "분석가는 업무시간 내에만 raw zone에 접근 가능" 같은 규칙이 가능하다.
단점도 있다. 속성 품질이 나쁘면 정책이 올바르게 평가되지 않는다. 정책 자체가 복잡해져 디버깅이 어렵다. 속성 저장소, 정책 엔진, enforcement point를 추가로 관리해야 한다.
4. RBAC와 ABAC: 어떻게 조합하는가
실제 운영에서는 두 모델이 섞인다.
| 단계 | 모델 | 이유 |
|---|---|---|
| 초기 구축 | RBAC 중심 | 단순하고 이해하기 쉽다. 승인 흐름을 설계하기 쉽다 |
| 규모 성장 | RBAC + 속성 조건 추가 | 역할만으로 표현 안 되는 조건이 생긴다 |
| 대규모 플랫폼 | ABAC로 전환 (일부) | 도메인·지역·분류 기반 정책이 필요해진다 |
현실적인 출발점은 다음과 같다.
- RBAC로 거친 분류:
finance_analyst_readonly,data_engineer_pipeline_operator,dba_operator등 소수의 역할을 정의한다. - restricted 데이터만 속성 조건 추가: classification=restricted인 데이터는 별도 승인 + 목적 기록 필요.
- row/column policy: PostgreSQL row-level security, BigQuery column policy, Snowflake row access policy 등 DB 레벨에서 속성 기반 필터를 추가한다.
5. Service account 설계와 관리
service account는 사람이 아닌 애플리케이션, 파이프라인, 스크립트가 사용하는 계정이다. Airflow DAG, Spark job, Kafka consumer, API 서버, 마이그레이션 스크립트가 모두 service account를 사용한다.
service account가 위험한 이유는 세 가지다.
- 소유자 없이 남는다: 팀원이 떠나거나 프로젝트가 종료되어도 service account는 그대로 남는다.
- 넓은 권한이 쌓인다: 편의상 superuser 또는 모든 테이블 접근 권한으로 생성된다.
- credential이 오래 산다: 비밀번호나 key가 수년간 바뀌지 않는 경우가 있다.
5.1 Service account 설계 원칙
최소권한 정의
credential 저장
사용 모니터링
미사용 감지
권한 회수
모든 service account에는 반드시 다음 정보가 있어야 한다.
| 항목 | 내용 | 이유 |
|---|---|---|
| 이름 | airflow-pipeline-raw-writer, spark-etl-reader | 목적과 권한 범위를 이름에 담는다 |
| owner | 팀 또는 담당자 | owner가 없으면 검토와 폐기가 안 된다 |
| 목적 | "Airflow DAG X의 raw 스키마 적재" | 권한 심사 때 기준이 된다 |
| 권한 범위 | 최소 필요 권한만, 가능하면 특정 schema/table | least privilege 원칙 |
| rotation 주기 | 90일, 180일, 이벤트 기반 | 오래된 credential 방지 |
| 만료 또는 review 주기 | 사용하지 않으면 폐기 기준 | 좀비 account 방지 |
5.2 Service account와 비밀 관리
비밀(credential)은 소스 코드, 환경변수, 설정 파일에 평문으로 넣으면 안 된다. 전용 비밀 관리 시스템을 사용한다.
- AWS Secrets Manager: 자동 rotation, Lambda로 DB 비밀번호 rotate 기능 내장
- HashiCorp Vault: dynamic secrets 기능으로 매 요청마다 임시 DB credential 생성
- GCP Secret Manager: 버전 관리, IAM 연동
- Kubernetes Secrets: 기본은 Base64 인코딩(암호화 아님), External Secrets Operator나 Vault 연동이 권장됨
Dynamic secrets가 이상적이다. Vault의 dynamic secrets는 Airflow DAG가 실행될 때마다 시간 제한이 있는 DB credential을 새로 생성하고, DAG 종료 후 즉시 폐기한다. 장기 credential이 아예 존재하지 않는다.
6. Credential rotation
credential rotation은 비밀번호, API key, 인증서 같은 접근 자격증명을 주기적으로 교체하는 것이다. 오래된 credential은 이미 유출되었을 수 있지만 모르는 상태일 수 있다. 짧은 credential 수명은 그 피해를 시간으로 제한한다.
6.1 Rotation 유형
| 유형 | 설명 | 적합한 상황 |
|---|---|---|
| 정기 rotation | 90일, 180일 주기로 교체 | 사람 계정 비밀번호, 장기 API key |
| 이벤트 기반 rotation | 퇴직, 의심 활동, 침해 탐지 시 즉시 교체 | 비상 상황 |
| Dynamic credential | 매 요청 또는 세션마다 새 credential 발급 | service account, pipeline |
| Short-lived token | IAM 토큰, JWT, STS token (수분~수시간) | 클라우드 서비스 인증 |
6.2 DB 비밀번호 rotation 실전
AWS Secrets Manager는 RDS/Aurora 비밀번호를 자동으로 rotate한다. 흐름은 다음과 같다.
- Secrets Manager가 rotation Lambda를 실행한다.
- Lambda가 새 비밀번호를 생성하고 DB에
ALTER USER또는SET PASSWORD를 실행한다. - Secrets Manager에 새 비밀번호를 저장한다.
- 이전 버전은 일정 기간 유지하다가 폐기한다.
rotation 중에는 이전 credential과 새 credential이 동시에 유효한 짧은 window가 있다. connection pool에서 rotation 중에 기존 연결이 끊기지 않도록 rotation 설계에서 이 window를 고려해야 한다.
6.3 Rotation 자동화의 장벽
자동화를 막는 장벽이 있다.
- hard-coded credential: 소스 코드, 설정 파일에 비밀번호가 박혀 있으면 rotation하면 서비스가 죽는다.
- shared account: 여러 서비스가 같은 DB 사용자를 쓰면 rotation 시 영향 범위를 알기 어렵다.
- legacy 시스템: secret manager와 연동이 안 되는 오래된 시스템이 있다.
이 때문에 처음부터 credential을 비밀 관리 시스템에서만 읽도록 설계하는 것이 나중에 rotation 자동화를 훨씬 쉽게 만든다.
7. 운영 체크리스트
| 질문 | 확인 방법 |
|---|---|
| 모든 DB 역할에 목적이 명시되어 있는가? | DB \du (PostgreSQL) 또는 IAM role 목록 검토 |
| service account마다 owner가 지정되어 있는가? | 비밀 관리 시스템, service account 목록 |
| 90일 이상 credential을 바꾸지 않은 service account가 있는가? | Secrets Manager age check, last rotation date |
| 사람 계정 비밀번호 만료 정책이 있는가? | DB password policy, cloud IAM policy |
| 퇴직자 또는 이동자의 권한이 즉시 회수되는가? | 오프보딩 체크리스트, access review 기록 |
| raw PII 데이터에 접근 가능한 service account가 목적별로 구분되어 있는가? | DB grant 목록, IAM policy audit |
| credential이 소스 코드나 환경변수에 평문으로 있는가? | secret scanning (GitGuardian, trufflehog, git-secrets) |
| 정기 access review 주기가 정해져 있는가? | 분기별 또는 반기별 review 캘린더 |
8. 흔한 안티패턴
8.1 "pipeline은 superuser가 편하다"
파이프라인 서비스 계정에 superuser, root, admin 권한을 주면 pipeline 코드 오류나 침해 사고가 데이터 전체를 건드릴 수 있다. pipeline 계정은 해당 pipeline이 읽고 쓰는 schema와 table에만 권한이 있어야 한다.
8.2 "같은 계정을 여러 서비스가 나눠 쓴다"
shared account는 어느 서비스에서 쿼리를 보냈는지 추적하기 어렵다. audit log에 같은 사용자 이름만 남고, credential 회수 시 영향 범위를 파악할 수 없다. 서비스마다 별도 service account를 사용해야 한다.
8.3 "퇴직자 처리는 IT팀이 알아서 한다"
DB 권한, warehouse 권한, BI 권한은 IT 팀의 AD 계정 비활성화로 자동 회수되지 않는 경우가 많다. 오프보딩 체크리스트에 DB 권한, 플랫폼 권한, service account ownership 이전이 명시적으로 포함되어야 한다.
8.4 "rotation하면 서비스가 잠깐 죽을 수 있다"
rotation 중 downtime이 발생한다면 credential 읽기 구조에 문제가 있는 것이다. 올바르게 설계된 시스템은 새 credential을 배포할 때 서비스를 재시작하지 않아도 되거나, rotation window 동안 이전 credential도 유효하게 유지하다가 전환한다.
마무리: 권한은 설계하는 것이 아니라 운영하는 것이다
RBAC, ABAC, service account, credential rotation은 처음 설정하면 끝나는 것이 아니다. 사람이 이동하고, 파이프라인이 추가되고, 새 DB가 생기고, 오래된 계정이 남는다. 권한은 엔트로피가 있다: 아무것도 안 하면 시간이 지날수록 복잡해지고 넓어진다.
운영자에게 필요한 것은 두 가지다. 하나는 지금 상태를 볼 수 있는 수단: 누가 어디에 접근 가능한지 목록을 뽑을 수 있어야 한다. 다른 하나는 정기 회수 루틴: 분기마다 사용하지 않는 권한과 오래된 credential을 정리하는 시간이 캘린더에 있어야 한다.
다음 장에서는 권한 통제가 통하더라도 데이터 자체가 유출되었을 때의 마지막 방어선인 암호화(at-rest, in-transit, KMS, envelope encryption)를 다룬다.
References
- NIST SP 800-162, "Guide to Attribute Based Access Control (ABAC) Definition and Considerations": https://csrc.nist.gov/pubs/sp/800/162/final
- IBM, "Role-Based Access Control (RBAC) Implementation Guide": https://www.ibm.com/think/topics/role-based-access-control-implementation
- PostgreSQL Documentation, "Database Roles": https://www.postgresql.org/docs/current/database-roles.html
- AWS Documentation, "IAM database authentication for MariaDB, MySQL, and PostgreSQL": https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html
- HashiCorp Vault, "Database Secrets Engine": https://developer.hashicorp.com/vault/docs/secrets/databases
- AWS Secrets Manager, "Rotate AWS Secrets Manager secrets": https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets.html
- Satori Cyber, "RBAC vs ABAC: The Complete Guide": https://satoricyber.com/data-protect-guide/rbac-vs-abac-the-complete-guide/
- CIS Benchmark for PostgreSQL, Access Control section: https://www.cisecurity.org/benchmark/postgresql