Skip to content

Latest commit

 

History

History
286 lines (222 loc) · 16.8 KB

File metadata and controls

286 lines (222 loc) · 16.8 KB

Database Schema

IoT, 백엔드, 프론트, 보안이 같은 DB 스키마를 기준으로 개발하기 위한 문서입니다. 스키마 변경 시 이 파일과 api.md를 함께 수정한 뒤 PR을 올립니다.

REST API · MQTT: api.md · 배포: deployment.md
팀 역할: CONTRIBUTING.md

담당 · 역할

영역 주 담당 협업
스키마·ERD·마이그레이션 박소정 (Backend) 전원 (해당 API/기능 담당자 리뷰)
devices · WireGuard 필드 박소정 윤아령 (Collector)
sbom · packages 박소정 윤아령, 최지현 (Trivy 연동)
cves · AI 피처·LLM 캐시 박소정 박대호 (ML·LLM), 최지현 (CVE 소스)
network_scans 박소정 최지현

ERD

Database ERD

관계 요약: customers → users · devices · settings · notifications · sbom → packages → package_cves ← cves · devices_cves · scan_history · network_scans · scan_schedule


1. 사용자 (users)

플랫폼 관리자(제조사 담당자) 계정 정보를 저장합니다.

필드 타입 설명
id bigint (PK) 사용자 ID
email varchar(255) 이메일
password_hash varchar(255) 해시된 비밀번호
customer_id bigint (FK, null 허용) customers 참조 — 이 계정이 속한 고객사. /devices 등 기기 조회 범위를 결정(§15). NULL이면 기기 목록이 빈 배열
created_at timestamp 생성 시각
updated_at timestamp 수정 시각

2. 설정 (settings)

관리자별 자동 스캔 주기, 알림 여부, 위험도 임계값 등 개인 설정을 저장합니다.

필드 타입 설명
user_id bigint (PK/FK) users 참조
auto_scan boolean 자동 스캔 ON/OFF
scan_interval integer 스캔 주기
alert_enabled boolean 알림 ON/OFF
risk_threshold_critical integer critical 위험도 기준
risk_threshold_high integer high 위험도 기준
risk_threshold_medium integer medium 위험도 기준
updated_at timestamp 설정 수정 시각

2026-09-02부로 scan_interval(스캔 주기)은 실제 재스캔 스케줄러가 참조하는 값이 아니게 됐습니다 — 사용자별 settings.scan_interval은 화면에 남아있지만 무시되고, 실제 주기는 아래 scan_schedule(시스템 전체 공통 단일 설정)을 따릅니다.

2.1 스캔 주기 설정 (scan_schedule)

Trivy·네트워크 주기 재스캔이 실제로 참조하는 시스템 전체 공통 설정. 항상 id=1 한 행만 존재합니다.

필드 타입 설명
id integer (PK) 항상 1
scan_interval integer 재스캔 간격(시간) — 24=매일, 168=매주, 720=매월
updated_at timestamp 마지막 변경 시각. 재스캔 주기 계산의 기준(앵커)으로도 쓰임

3. 고객사 (customers)

판매된 IoT 기기가 등록되는 고객사(기업) 또는 개인 고객 정보를 저장합니다.

필드 타입 설명
id bigint (PK) 고객사/개인 ID
name varchar(255) 이름
type varchar(20) 고객 유형 (enterprise/individual)
contact varchar(255) 연락처
created_at timestamp 생성 시각

4. 기기 (Devices)

플랫폼에 등록된 모든 IoT 기기의 기본 정보를 저장합니다. customer_id가 NULL이면 아직 판매되지 않은 기기입니다. 2026-08-28부로 이 값이 계정별 기기 조회 범위 제한에도 쓰입니다(§15) — 로그인한 관리자의 customer_id와 다르면 조회되지 않습니다.

필드 타입 설명
device_id uuid (PK) 전 세계 고유 식별자
customer_id bigint (FK, null 허용) customers 참조 (미판매 기기는 NULL)
name varchar(255) 기기 이름
ip_address varchar(45) IP 주소
model varchar(255) 모델명
kernel_version varchar(255) 커널 버전
arch varchar(50) CPU 아키텍처
os_info text OS 정보
created_at timestamp 생성 시각
updated_at timestamp 수정 시각
last_seen_at timestamp 마지막 heartbeat
deleted_at timestamp (null 허용) 소프트 삭제 시각. NULL이면 정상 기기. DELETE /devices/{id}는 이 값만 채우고 실제 row는 지우지 않는다
wg_ip_address varchar(15) (null 허용) WireGuard 가상 IP (WG_ENABLED 시 할당, 예: 10.100.0.x)
wg_public_key varchar(64) (null 허용) WireGuard 클라이언트 공개키 (기기당 1개)
exposure_level varchar(20) (null 허용) 네트워크 노출 구역 (internal / dmz / internet_facing)

5. 스캔 이력 (scan_history)

기기별로 실행된 스캔(Syft/Trivy/RustScan+Nmap+Nuclei)의 실행 시점과 성공/실패 상태를 기록합니다.

필드 타입 설명
id bigint (PK) 스캔 이력 ID
device_id uuid (FK) devices 참조
scan_type varchar(20) 스캔 종류
triggered_by varchar(20) 스캔 실행 주체
status varchar(20) 스캔 상태
started_at timestamp 스캔 시작 시각
finished_at timestamp 스캔 종료 시각
result_summary text 스캔 결과 요약

6. SBOM 업로드 (Collector → Backend)

Syft로 추출한 기기별 소프트웨어 구성 명세(SBOM) 원본을 저장합니다.

전송: HTTPS -> AWS S3

필드 타입 설명
id bigint (PK) SBOM ID
device_id uuid (FK) devices 참조
sbom_format varchar(20) 예: cyclonedx-json, spdx-json
sbom_version varchar(20) SBOM 버전
tool_name varchar(100) SBOM 생성 도구명
sbom_payload jsonb Syft 출력 본문
hash varchar(64) SBOM 해시값
collected_at timestamp 수집 시각
created_at timestamp 생성 시각
source_container varchar(255) 기기가 여러 컨테이너로 구성된 경우 이 SBOM의 출처(Collector --scan-target 값). 레거시 데이터는 NULL

7. 패키지 (packages)

SBOM에서 추출된 개별 오픈소스 패키지(라이브러리) 목록을 저장합니다.

필드 타입 설명
id bigint (PK) 패키지 ID
device_id uuid (FK) devices 참조
sbom_id bigint (FK) sbom 참조
component_id text 컴포넌트 식별자
package_name text 패키지명
version text 설치 버전
type varchar(50) 패키지 유형
purl text Package URL
supplier text 공급자
relationship varchar(100) 의존 관계
license text 라이선스 (2026-09-23부로 varchar(255)→text — syft가 SPDX 식별자 대신 라이선스 전문을 넣는 경우가 있어 INSERT 자체가 실패하던 버그 수정)

8. CVE 정보 (cves)

NVD, GitHub Advisory 등에서 수집한 CVE(취약점) 원본 정보를 저장합니다.

필드 타입 설명
id bigint (PK) CVE 레코드 ID
cve_id varchar(50) UNIQUE CVE 번호 (예: CVE-2024-0001)
title text 취약점 제목
description text 취약점 설명
severity varchar(20) critical, high, medium, low
cvss_score decimal(3,1) CVSS 점수
cvss_vector varchar(255) CVSS 벡터
published_date date 공개 날짜
last_modified_date date 최종 수정일 (Trivy LastModifiedDate)
primary_url text 참고 링크 (대표 1개)
cwe_ids varchar(50)[] CWE 식별자 목록 (Trivy CweIDs)
references text[] 참고 링크 전체 목록 (Trivy References)
created_at timestamp 생성 시각
updated_at timestamp 수정 시각
attack_vector varchar(20) AI 모델 입력 피처 — NVD CVSS v3 (NETWORK/ADJACENT_NETWORK/LOCAL/PHYSICAL)
attack_complexity varchar(10) AI 모델 입력 피처 — NVD CVSS v3 (LOW/HIGH)
privileges_required varchar(10) AI 모델 입력 피처 — NVD CVSS v3 (NONE/LOW/HIGH)
user_interaction varchar(10) AI 모델 입력 피처 — NVD CVSS v3 (NONE/REQUIRED)
confidentiality_impact varchar(10) AI 모델 입력 피처 — NVD CVSS v3 (NONE/LOW/HIGH)
integrity_impact varchar(10) AI 모델 입력 피처 — NVD CVSS v3 (NONE/LOW/HIGH)
availability_impact varchar(10) AI 모델 입력 피처 — NVD CVSS v3 (NONE/LOW/HIGH)
epss_score numeric(8,5) AI 모델 입력 피처 — EPSS(FIRST.org) 악용 가능성 점수(0~1), 매일 갱신됨
epss_percentile numeric(8,5) AI 모델 입력 피처 — EPSS 백분위(0~1)
has_exploit_ref boolean 공개 Exploit 레퍼런스 존재 여부 — NVD references의 Exploit 태그
ref_count integer NVD references 개수
config_count integer NVD configurations 노드 수
nvd_cwe_id varchar(50) NVD 공식 CWE(단일) — cwe_ids(Trivy, 배열)와 별개. AI 모델은 NVD 기준으로 학습돼 추론 시 이 값을 우선 사용
ai_features_updated_at timestamp 위 AI 피처들을 NVD/EPSS API로 마지막으로 채운 시각. NULL이면 미채움 — 매일 자동 백필(AI_ENRICH_HOUR_UTC) 대상
llm_analysis jsonb Groq LLM(gpt-oss-20b) 분석 텍스트 캐시 — {analysis_summary, attack_types, attack_scenarios, recommended_actions}
llm_analysis_label varchar(10) llm_analysis를 생성할 당시의 predicted_label — 위험도가 바뀌면 캐시 무효화 판단에 사용
llm_analysis_updated_at timestamp llm_analysis 마지막 생성 시각

9. 패키지-취약점 연결 (package_cves)

특정 패키지가 일반적으로 어떤 CVE에 영향을 받는지 매핑합니다 (기기와 무관한 범용 연관관계).

필드 타입 설명
id bigint (PK) 패키지-CVE 연결 ID
package_id bigint (FK) packages 참조
cve_id bigint (FK) cves 참조
affected_versions text 영향받는 버전
fixed_versions text 수정된 버전
created_at timestamp 생성 시각

10. 기기-취약점 연결 (devices_cves)

특정 기기에서 실제로 탐지된 CVE 발생 이력을 기록합니다. 어떤 스캔 실행(scan_history)에서 발견됐는지도 함께 남깁니다.

필드 타입 설명
id bigint (PK) 기기-CVE 연결 ID
device_id uuid (FK) devices 참조
cve_id bigint (FK) cves 참조
package_id bigint (FK) packages 참조
scan_history_id bigint (FK) scan_history 참조
installed_version varchar(255) 설치 버전
installed_path text 취약 파일 경로 (Trivy PkgPath, 언어별 패키지에서만 채워짐)
status varchar(20) 상태
detected_at timestamp 탐지 시각
resolved_at timestamp 해결 시각
source varchar(20) 탐지 출처
notes text 비고

11. 네트워크 스캔 결과 (network_scans)

RustScan(포트탐지) → Nmap(서비스식별) → Nuclei(취약점매칭)로 수행한 기기별 네트워크 포트·노출 스캔 결과를 저장합니다.

필드 타입 설명
id bigint (PK) 스캔 ID
device_id uuid (FK) devices 참조
scan_type varchar(20) 스캔 종류
target varchar(255) 스캔 대상
protocol varchar(20) 프로토콜
service varchar(100) 서비스명
port integer 포트
nvt_name varchar(255) Nuclei 템플릿 이름
severity varchar(20) 심각도
cvss_score decimal(3,1) CVSS 점수
description text 설명
solution text 해결 방법
cve_id varchar(50) CVE 참조가 있는 발견물만 채워짐(null 가능)
scanned_at timestamp 스캔 시각

12. 알림 (notifications)

신규 취약점 발생 시 담당 관리자에게 발송되는 알림 내역을 저장합니다. (고객사에는 발송되지 않음)

2026-09-03부로 실제로 채워집니다 — 기기에서 CVE가 이전 스캔에는 없던 조합으로 처음 탐지되면(services/trivy_runner.py), 그 기기 소유 고객사의 계정들에게 알림 row가 생성됩니다. 재스캔으로 같은 CVE가 다시 잡히는 건 알림을 새로 만들지 않습니다. settings.alert_enabled가 명시적으로 false인 계정만 제외(설정 안 건드린 계정은 기본으로 받음) — 단, 이 값을 켜고 끄는 화면(Settings "알림 설정" 탭)은 PR #56에서 제거되어 현재는 코드로만 존재합니다.

필드 타입 설명
id bigint (PK) 알림 ID
user_id bigint (FK) users 참조
device_id uuid (FK) devices 참조
title varchar(255) 알림 제목
message text 알림 내용
severity varchar(20) 알림 위험도
is_read boolean default false 읽음 여부
created_at timestamp 생성 시각