Part 3: 역할 개념 및 백엔드 접근 통제
| 항목 | 내용 |
|---|---|
| 문서명 | Part 3: 역할 개념 및 백엔드 접근 통제 (Role Concept & Backend Access Control) |
| 제품명 | DTA Wide Sleep Management Platform |
| 작성일 | 2026-02-10 |
| 적용범위 | Part 3 (백엔드) |
1. 역할 정의 (Role Definitions)
1.1 애플리케이션 사용자 역할
| 역할 | 영문명 | 권한 레벨 | 주요 권한 |
|---|---|---|---|
| 환자 | Patient | Level 1 | 본인 데이터 CRUD, 설문 응답, 프로그램 수행 |
1.2 인프라 운영자 역할 (GCP IAM)
| 역할 | GCP IAM 역할 | 권한 범위 |
|---|---|---|
| 인프라 관리자 | Owner, Editor | 모든 GCP 리소스 |
| 개발자 | Viewer | Cloud SQL 읽기/쓰기, 로그, 배포 |
| DevOps | Cloud Run Admin | Cloud Run 배포, 설정 |
| 보안팀 | Security Admin | IAM, Audit Logs, Security Center |
2. 권한 매트릭스 (Permission Matrix)
2.1 애플리케이션 레벨
| 리소스 | Patient |
|---|---|
| 본인 수면 로그 | CRUD |
| 타인 수면 로그 | - |
| 본인 설문 응답 | CRUD |
| 타인 설문 응답 | - |
| 상담 노트 | R (본인 것만) |
| 사용자 계정 | RU (본인만) |
| 시스템 설정 | - |
| 감사 로그 | - |
권한 코드:
- C: Create (생성)
- R: Read (읽기)
- U: Update (수정)
- D: Delete (삭제)
2.2 인프라 레벨 (GCP IAM)
| GCP 리소스 | 인프라 관리자 | 개발자 | DevOps | 보안팀 |
|---|---|---|---|---|
| Cloud Run | CRUD | R | CRU | R |
| Cloud SQL | CRUD | R | R | R |
| Cloud Logging | CRUD | R | R | CRUD |
| Secret Manager | CRUD | - | R | CRUD |
| IAM & Admin | CRUD | R | R | CRUD |
| Cloud KMS | CRUD | - | - | CRUD |
3. 역할 기반 접근 통제 (RBAC) 구현
3.1 NestJS Guards
AppToken JWT 구조 (실제 구현 - app-token.guard.ts):
AppToken은 RS256 비대칭 서명 기반으로, JWK(JSON Web Key) 관리 방식을 사용합니다.
인증/인가 분리 구조:
// AppToken Payload 구조
interface AppTokenPayload {
appId: string; // 앱 식별자
deviceId: string; // 디바이스 식별자
jti: string; // JWT ID (고유 식별자)
env: string; // 환경 (dev/stage/prod)
exp: number; // 만료 시간
iat: number; // 발행 시간
}
인증 Guard 체인 (실제 구현):
| Guard | 파일 경로 | 역할 |
|---|---|---|
| AppTokenGuard | guards/app-token.guard.ts | AppToken JWT 검증 (RS256), 만료/폐기 처리 |
Service Account 인증:
iam/controllers/에서 Service Account 인증/관리 구현- 서비스 간 통신에 사용
컨트롤러 사용 예:
@Controller('sleep')
@UseGuards(AppTokenGuard)
export class SleepController {
@Get('/logs')
async getSleepLogs(@CurrentUser() user: TokenPayload) {
// AppToken + UserToken 이중 인증 후 접근
}
}
3.2 데이터 레벨 필터링
본인 데이터만 접근 (Patient):
// Query Handler
async execute(query: GetSleepLogsQuery): Promise<SleepLogDto[]> {
const { userId, requesterId, requesterRoles } = query;
// Patient는 본인 데이터만
if (requesterRoles.includes('patient') && userId !== requesterId) {
throw new ForbiddenException('Cannot access other user data');
}
return this.repository.findByUserId(userId);
}
5. 접근 승인 및 점검 주기
5.1 정기 접근 권한 검토
| 주기 | 대상 | 검토자 | 조치 |
|---|---|---|---|
| 월간 | 모든 GCP IAM 역할 | 보안팀 | 불필요한 권한 제거 |
| 분기 | 애플리케이션 Admin 역할 | CTO | 역할 재할당 |
| 연간 | 전체 접근 통제 정책 | 보안팀 + 컴플라이언스팀 | 정책 업데이트 |
5.2 권한 회수
| 조건 | 회수 시점 | 담당 |
|---|---|---|
| 퇴사 | 즉시 | 운영팀, 개발팀 |
| 역할 변경 | 즉시 | 해당 사용자 |
| 의심스러운 활동 | 즉시 | 보안팀, 해당 사용자 |
6. 감사 로그 이벤트 정의
6.1 필수 감사 이벤트
| 이벤트 | 로그 레벨 | 기록 정보 | 보관 기간 |
|---|---|---|---|
| 관리자 로그인 | WARNING | adminId, IP, timestamp, MFA 여부 | 1년 |
| 역할 변경 | ERROR | targetUserId, 변경자, 구 역할, 신 역할 | 1년 |
| DB 직접 접근 | ERROR | adminId, DB 이름, 쿼리 (파라미터 마스킹) | 1년 |
| 사용자 계정 삭제 | ERROR | adminId, 대상 userId, 사유 | 1년 |
| 민감 데이터 대량 Export | ERROR | adminId, 레코드 수, 데이터 유형 | 1년 |
| 권한 거부 (403) | WARNING | userId, 요청 경로, 필요 권한 | 90일 |
| 시스템 설정 변경 | ERROR | adminId, 설정 키, 구 값, 신 값 | 1년 |
6.2 감사 로그 예시
{
"timestamp": "2026-02-10T15:30:00.000Z",
"severity": "ERROR",
"service": "dta-wide-api",
"module": "admin",
"event_type": "user_deleted",
"adminId": "admin-uuid-123",
"admin_email": "adm***@dta-wide.com",
"target_user_id": "user-uuid-456",
"reason": "GDPR deletion request",
"ip_address": "192.168.1.***",
"user_agent": "Mozilla/5.0...",
"approval_ticket": "JIRA-1234",
"message": "[AUDIT] Admin deleted user account"
}
8. 역할 분리 (Separation of Duties)
8.1 직무 분리 매트릭스
| 직무 A | 직무 B | 분리 필요 | 이유 |
|---|---|---|---|
| 코드 개발 | 프로덕션 배포 | ✅ | 악의적 코드 배포 방지 |
| DB 스키마 변경 | DB 데이터 수정 | ⚠️ | 승인 프로세스로 통제 |
| IAM 역할 생성 | IAM 역할 할당 | ✅ | 권한 상승 방지 |
| 백업 생성 | 백업 복원 | ✅ | 데이터 변조 방지 |
| 감사 로그 설정 | 감사 로그 삭제 | ✅ | 증거 인멸 방지 |
8.2 4-Eyes 원칙 (Four-Eyes Principle)
적용 대상:
- 프로덕션 DB 스키마 변경
- 프로덕션 배포 (긴급 핫픽스 제외)
- IAM 역할 변경
- 보안 정책 수정
구현:
- Pull Request 필수 1명 승인 (작성자 제외)
- Jira 티켓 이슈 연동
- GCP IAM: 조건부 역할 (시간 제한 + 승인자 확인)
9. TODO: 비정상 활동 탐지 및 대응
9.1 탐지 패턴
| 패턴 | 탐지 조건 | 알림 | 자동 조치 |
|---|---|---|---|
| 대량 데이터 조회 | 1분 내 100개 이상 레코드 | 보안팀 (즉시) | 세션 무효화 |
| 비정상 시간대 접근 | 00:00~06:00 관리자 로그인 | 운영팀 | MFA 재확인 요구 |
| 다중 실패 시도 | 5회 연속 로그인 실패 | 보안팀 | 계정 임시 잠금 (30분) |
| 비정상 지역 접근 | EU 외 지역 로그인 | 보안팀 | 계정 확인 요청 |
| 권한 상승 시도 | 역할 변경 API 호출 (권한 없음) | 보안팀 + CTO | 계정 즉시 잠금 |
9.2 대응 절차
증빙 및 참조(Artifacts)
- 권한 매트릭스 (본 문서 Section 2)
- AppTokenGuard 구현 코드 -
guards/app-token.guard.ts - FlexibleAuthGuard 구현 코드 -
guards/flexible-auth.guard.ts - GCP IAM 역할 정의 -
artifacts/iam-roles.json - 승인 프로세스 다이어그램 (본 문서 Section 4.2)
- 감사 로그 샘플 -
logs/admin-audit-log-sample.json - 정기 검토 기록 -
reports/iam-review-2025-q4.pdf - 비정상 활동 탐지 룰 -
artifacts/anomaly-detection-rules.json - 접근 승인 Jira 티켓 샘플 -
artifacts/jira-approval-sample.pdf - 관리자 접근 로그 (30일치) -
logs/admin-access-30days.log
| 규정 | 요구사항 | 구현 | 증거 |
|---|---|---|---|
| BSI TR-03161 Part 3 | 역할 기반 접근 통제 | RBAC, Roles Guard | 권한 매트릭스 (Section 2) |
| BSI TR-03161 Part 3 | 관리자 행위 감사 | 감사 로그, 승인 프로세스 | 감사 로그 샘플 (Section 6) |
| GDPR Article 32 | 적절한 접근 통제 | RBAC, 최소 권한, 감사 | 본 문서 전체 |
| ISO 27001 A.9 | 접근 통제 | RBAC, 정기 검토 | 검토 절차 (Section 5) |