-
Notifications
You must be signed in to change notification settings - Fork 0
security auth rbac
Cognito는 사용자를 인증하고, RDS PostgreSQL의 앱 테이블은 역할과 접근 범위를 결정한다. Frontend 표시 정책과 Backend 강제 인가는 서로 다른 계층이다.
Cognito User Pool
로그인, MFA/임시 비밀번호, Hosted UI, JWT 발급
|
v
Dashboard Web
OIDC Authorization Code + PKCE, access token 전달
|
v
FastAPI Backend
JWT 검증 -> Cognito sub 조회 -> RDS Principal 생성 -> endpoint 인가
|
v
RDS PostgreSQL
app_user, factory, user_factory_access, audit_log
PostgreSQL 사람별 DB role을 만드는 구조가 아니다. Backend 서비스 계정만 DB에 접속하며, 애플리케이션 사용자의 권한은 앱 테이블에서 관리한다.
Backend deps/auth.py는 다음을 검증한다.
-
Authorization: Bearer존재 - Cognito JWKS의
kid와 RS256 signature - User Pool issuer
- access token의
client_id또는 ID token의aud -
token_use가access또는id - token 만료 등 JOSE 기본 검증
JWKS는 TTL cache와 lock을 사용한다. 갱신 실패 시 기존 cache가 있으면 사용하고,
검증 실패는 401과 WWW-Authenticate: Bearer로 반환한다.
WebSocket은 query의 JWT를 같은 방식으로 검증한다. 인증 실패는 close code
4001, 앱 사용자/공장 권한 실패는 4003이다.
| 테이블 | 역할 |
|---|---|
app_user |
Cognito sub, email, 표시 이름, global role, System 권한, 상태 |
factory |
앱에서 관리하는 공장 목록 |
user_factory_access |
사용자별 공장 grant와 legacy 공장 role |
audit_log |
사용자 생성/수정/삭제 actor와 target |
JWT의 sub로 active app_user를 찾는다.
- 사용자가 없으면
403 User is not provisioned - disabled면
403 User is disabled - 설정된 bootstrap
sub는 RDS row 없이 임시super_adminPrincipal로 허용
| 역할 | 현재 의미 |
|---|---|
super_admin |
모든 공장, 사용자 관리, System 접근 |
factory_admin |
user_factory_access에 배정된 공장만 접근 |
org_admin |
legacy global 관리자. 모든 공장, 사용자 관리, System 접근 |
viewer |
legacy 제한 사용자. 배정 공장과 별도 System flag 적용 |
사용자 생성/수정 API와 UI는 super_admin과 legacy org_admin만 허용한다.
factory_admin, viewer는 생성·부여 가능한 사용자 역할이지만 사용자 관리 endpoint 접근 권한은 아니다.
공장 grant의 admin/viewer도 legacy 호환 값이다. 현재 factory_admin을
저장할 때 grant는 admin으로 정규화되며, 공장 조회 endpoint는 두 값을 기능별로
구분하지 않고 factory ID 포함 여부로 접근을 판단한다.
RDS에는 app_user.can_view_system이 저장된다. Principal의 실제 System 접근은:
can_access_system = can_manage_users OR can_view_system
can_manage_users = global_role in {super_admin, org_admin}
따라서:
-
super_admin, legacyorg_admin: 항상 System 접근 -
factory_admin:can_view_system=true일 때만 System 접근 - legacy
viewer: flag가 true이면 System 접근
GET /auth/me의 can_view_system은 DB 원본 flag가 아니라 위의 최종
can_access_system 결과다. Frontend는 이 값을 Sidebar와 Reports selector에
사용한다.
| Endpoint | Backend 정책 |
|---|---|
GET /healthz |
공개 |
GET /auth/me |
유효 JWT + active/provisioned 앱 사용자 |
GET /factories |
허용 공장만 필터링 |
GET /factories/{id} |
권한 없는 공장은 403
|
GET /factories/{id}/history |
권한 없는 공장은 403
|
WS /ws/factories/{id} |
구독 전 공장 권한 검사, 실패 시 4003
|
GET /reports |
공장 보고서는 허용 공장만, Cloud Infra는 System 권한 사용자만 |
GET /reports/{date}/{id} |
공장은 공장 권한, cloud-infra는 System 권한, 실패 시 403
|
GET /cloud-infra |
System 권한, 없으면 403
|
GET /cloud-infra/history |
System 권한, 없으면 403
|
GET/POST /admin/users |
super_admin 또는 legacy org_admin, 없으면 403
|
PATCH/DELETE /admin/users/{id} |
super_admin 또는 legacy org_admin, 없으면 403
|
404는 권한 거부의 대체가 아니다. 공장/보고서 권한은 먼저 403으로 거부하고,
권한이 있는 대상의 실제 데이터가 없을 때 404를 반환한다.
| 기능 | Frontend 표시 정책 | Backend 강제 정책 |
|---|---|---|
| 공장 목록 |
/factories 응답만 표시 |
서버가 허용 공장만 필터링 |
| 공장 상세 | Sidebar에 허용 공장만 표시 | 직접 URL/API도 공장 권한 검사 |
| Cloud Infra |
can_view_system일 때 메뉴 표시 |
두 endpoint 모두 System 권한 검사 |
| Cloud Infra 보고서 |
can_view_system일 때 selector 표시 |
보고서 조회 시 System 권한 검사 |
| 사용자 관리 |
can_manage_users일 때 메뉴 표시 |
모든 admin endpoint에서 관리자 검사 |
| SPA route | 로그인 여부만 검사 | 데이터 요청마다 Principal과 권한 검사 |
메뉴 숨김은 보안 통제가 아니다. 사용자가 숨겨진 route를 직접 입력하거나 REST를 직접 호출해도 Backend가 동일한 권한을 강제해야 한다.
- 관리자 권한 검사
- 역할과 공장 ID 검증
- Cognito 사용자 생성
- RDS
app_user와 공장 grant 생성 - audit log 기록
중복 active email은 409, 알 수 없는 공장은 400, Cognito 작업 실패는
502다. 과거 disabled row가 남아 있으면 stale Cognito/RDS 정보를 정리한 뒤
재생성한다.
- email은 UI에서 변경하지 않는다.
- global 관리자는 개별 공장 grant를 가질 수 없다.
-
factory_admingrant role은admin으로 정규화한다. -
super_admin의 System 권한은 항상 true다. - 변경 후 audit log를 기록한다.
Cognito 사용자를 먼저 삭제하고 RDS grant/user를 삭제한다. Cognito 삭제가
실패하면 RDS만 먼저 지우지 않고 502를 반환한다. 성공한 작업은 audit log에
기록한다.
인증 성공과 앱 인가 성공은 별개다.
- Cognito에만 존재: 로그인은 가능하지만 Backend에서 미등록 사용자
403 - RDS에만 존재: Cognito 로그인이 불가능하므로 앱 접근 불가
- Cognito
sub불일치: RDS 사용자를 찾지 못해403 - RDS disabled: Cognito token이 유효해도
403 - 생성/삭제 Cognito Admin API 실패: Backend가
502를 반환하고 성공으로 확정하지 않음
운영 시 사용자 lifecycle은 /admin/users API를 통해 수행해 두 저장소를 함께
변경해야 한다. Cognito console 또는 RDS를 한쪽만 수동 변경하면 위 불일치가
발생할 수 있다.
관련 문서
- 시스템 아키텍처
- 제어 & 데이터 플레인
- Dashboard VPC 설계
- 하드웨어 배치
- Hub EKS 네임스페이스
- Tailscale Mesh VPN
- 데이터 생명주기
- 데이터 조회 모델
- 실시간 갱신 구조
- IoT 데이터 계약
- Reporting Pipeline
- 로컬 스토리지
- 클라우드 스토리지
- Edge Agent
- Edge AI 탐지
- Factory-A Log Adapter
- Dummy Sensor
- Edge IoT Publisher
- Lambda Data Processor
- Risk Normalizer
- Risk Score Engine
- Pipeline Status Aggregator
- Graph Aggregator 5m
- Cloud Infra Collector
- Daily Report Generator
- Risk Alert Dispatcher
- Image Snapshot Pipeline
- Dashboard Backend
- Dashboard Web
- AI 채팅 어시스턴트