Skip to content

Commit 91c2ef8

Browse files
committed
통제 증적 실증적 자동 스냅샷 — 라이브 집계를 날짜 찍힌 증적으로 원클릭 생성
- POST /controls/detail/{id}/evidence-records/auto (admin·security) — 휘발성 라이브 증적 (Fleet 자산 수·Zabbix 경보/모니터링·크로스매핑)을 한국어 요약 본문으로 조립해 수기 증적처럼 영속. 심사 대비 "이 날 이만큼의 증적" 시점 증거를 수기 타이핑 없이 박제. - 증적 레코드에 source(manual|auto) 구분 — schema/011 자가치유 ALTER + postgres load/save 반영 - UI: 수기 증적 섹션에 "⚡ 실증적 자동 기록" 버튼 + auto 배지(자동), 본문 pre-wrap 렌더 - CSV 내보내기에 kind=auto 표기 - 전체 163 passed
1 parent fc6db0a commit 91c2ef8

11 files changed

Lines changed: 101 additions & 19 deletions

File tree

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ All notable changes to this project are documented here.
44
Format follows [Keep a Changelog](https://keepachangelog.com/); this is an alpha project so
55
versions are `x.y.z-alpha.n`.
66

7+
## [v0.17.1-alpha.1] — 2026-07-09 — 실증적 자동 증적 스냅샷
8+
9+
### Added
10+
- **실증적 자동 기록 (⚡ 원클릭 스냅샷)** — 통제 상세의 휘발성 라이브 집계(Fleet 자산 수·Zabbix
11+
경보/모니터링·크로스매핑 등)를 **날짜 찍힌 증적 레코드로 자동 생성**. 수기 타이핑 없이
12+
"이 날 이만큼의 증적이 있었다" 시점 증거를 박제. `POST /controls/detail/{id}/evidence-records/auto`
13+
(admin·security). 증적 레코드에 `source`(manual|auto) 구분 추가(`schema/011` 자가치유 ALTER),
14+
UI에 ⚡자동 배지, CSV `kind=auto` 로 표기.
15+
716
## [v0.17.0-alpha.1] — 2026-07-09 — 통제 카탈로그 편집 · 법령 NLP 임포트 · 수기 증적 문서화
817

918
정본 카탈로그를 admin이 직접 편집하고, 법령/고시 텍스트를 통제 초안으로 자동 변환하며,

README.en.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ It sits **read-only on top of your existing** **Zabbix · FleetDM · Wazuh · Tr
5050
|---|---|---|
5151
| 📊 | **Unified operations UI** | Dashboard · Alert Triage · Incidents · Assets/Vulns · Compliance PDCA on one screen (`/ui`) |
5252
| 🎯 | **Risk assessment** | Per-CVE 3×3 matrix = impact (asset criticality) × likelihood → **score (1–9)** + treatment decision, residual risk, DoA auto-classify (admin·security) |
53-
| 📚 | **Control catalog** | ISMS-P 101 + ISO 27001:2022 93 = **194 controls** (KO/EN) tree + editable/persisted status + **admin direct edit (add/edit/delete)** + **regulation-text NLP import** (Claude/heuristic) + **documented manual evidence** + evidence pack **CSV/PDF download** |
53+
| 📚 | **Control catalog** | ISMS-P 101 + ISO 27001:2022 93 = **194 controls** (KO/EN) tree + editable/persisted status + **admin direct edit (add/edit/delete)** + **regulation-text NLP import** (Claude/heuristic) + **documented manual evidence + ⚡auto live-evidence snapshot** + evidence pack **CSV/PDF download** |
5454
| 🧑‍💻 | **Account governance** | Server/PC local accounts (osquery) × LDAP × approval ledger → detects leavers, unregistered privilege, unapproved sudo, dormant · IP team/purpose CSV export (defaults to admin·security, admin configures view roles) |
5555
| 🧾 | **Automatic evidence** | Asset owner/criticality, CVE remediation/exception, risk assessment, triage & incident changes accrued as _who/when/what_**6 CSV/PDF reports** |
5656
| 🔐 | **Role-based views** | Risk & controls are admin·security only; infra/help-desk see **only their own servers' remediation rate** |
@@ -129,9 +129,11 @@ Per-host Critical/High counts + per-CVE remediation plan/exception/expiry + chan
129129
**Admins edit the catalog directly** — ✏️edit/🗑️delete controls inline, "➕ Add control", and
130130
**"📥 Import regulation text (NLP)"**: paste CISA / privacy-law / notice text and it's auto-converted
131131
and saved as draft controls (precise structuring via Claude when `MORI_ANTHROPIC_API_KEY` is set,
132-
clause-level heuristic otherwise). Per control you can **document manual evidence** (title, body,
133-
collector, date, reference) and download the evidence pack — live + documented evidence merged — as
134-
**CSV or PDF**. Editing is admin-only; evidence documentation is admin·security.
132+
clause-level heuristic otherwise). Per control you can **document manual evidence**, or use
133+
**⚡ "Auto-capture live evidence"** to snapshot the current live aggregation (Fleet asset count,
134+
Zabbix alerts/monitoring, mappings) into a **dated evidence record with one click**. Download the
135+
evidence pack — live + documented, merged — as **CSV or PDF**. Editing is admin-only; evidence
136+
documentation is admin·security.
135137

136138
### 5) Account governance (access review)
137139
<!-- 📸 SCREENSHOT GUIDE ④

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
|---|---|---|
5151
| 📊 | **통합 운영 UI** | 대시보드 · Alert Triage · 인시던트 · 자산/취약점 · Compliance PDCA를 한 화면(`/ui`)에서 |
5252
| 🎯 | **위험성 평가** | CVE별 3×3 매트릭스 = 영향도(자산 중요도) × 발생가능성 → **점수(1~9)** + 위험처리 결정·잔여위험·DoA 자동분류 (admin·security) |
53-
| 📚 | **통제 카탈로그** | ISMS-P 101 + ISO 27001:2022 93 = **194 인증기준**(한/영) 트리 + 이행상태 편집·영속 + **admin 직접 편집(추가/수정/삭제)** + **법령 텍스트 NLP 임포트**(Claude/휴리스틱) + **수기 증적 문서화** + 증적 팩 **CSV/PDF 선택 다운로드** |
53+
| 📚 | **통제 카탈로그** | ISMS-P 101 + ISO 27001:2022 93 = **194 인증기준**(한/영) 트리 + 이행상태 편집·영속 + **admin 직접 편집(추가/수정/삭제)** + **법령 텍스트 NLP 임포트**(Claude/휴리스틱) + **수기 증적 문서화 + ⚡실증적 자동 스냅샷** + 증적 팩 **CSV/PDF 선택 다운로드** |
5454
| 🧑‍💻 | **계정 거버넌스** | 서버·PC 로컬 계정(osquery) × LDAP × 승인대장 대조 → 퇴사자 잔존·미등록 특권·미승인 sudo·휴면 검출 · IP 팀/용도 선별 CSV (기본 admin·security, admin이 열람 역할 조정) |
5555
| 🧾 | **자동 증적** | 자산 담당자·중요도, CVE 조치·예외, 위험성 평가, Triage·인시던트 변경을 _who/when/what_ 으로 누적 → **6종 CSV/PDF** |
5656
| 🔐 | **역할별 화면** | 위험성 평가·통제는 admin·security 전용, 인프라·헬프데스크는 **내 담당 서버 조치율**|
@@ -121,8 +121,9 @@ docker compose up -d mori-worker # 재적용
121121
**admin은 카탈로그를 직접 편집**합니다 — 트리에서 통제 ✏️수정/🗑️삭제, "➕ 통제 추가", 그리고
122122
**"📥 법령 텍스트 임포트(NLP)"** 로 CISA·개인정보보호법·고시 전문을 붙여넣으면 통제 초안(draft)으로
123123
자동 변환·저장됩니다(`MORI_ANTHROPIC_API_KEY`가 있으면 Claude로 정밀 구조화, 없으면 조항 단위
124-
휴리스틱). 통제별로 **수기 증적을 문서화**(제목·내용·수집자·수집일·참조링크)하고, 증적 팩은
125-
라이브 증적과 합쳐 **CSV 또는 PDF**로 골라 내려받습니다. 편집은 admin 전용, 증적 문서화는 admin·security.
124+
휴리스틱). 통제별로 **수기 증적을 문서화**하거나, **⚡ "실증적 자동 기록"** 으로 현재 라이브 집계
125+
(Fleet 자산 수·Zabbix 경보/모니터링·매핑)를 **날짜 찍힌 증적으로 원클릭 스냅샷**할 수 있습니다.
126+
증적 팩은 라이브+수기 증적을 합쳐 **CSV 또는 PDF**로 골라 내려받습니다. 편집은 admin 전용, 증적 문서화는 admin·security.
126127

127128
### 5) 계정 거버넌스 (접근권한 검토)
128129
<img width="1287" height="694" alt="image" src="https://github.com/user-attachments/assets/274b5b78-1ee5-439b-9b37-452daa4ba1f4" />

README_FULL.en.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ A one-line (`docker compose up -d`) **ISMS-P / ISO 27001 audit-evidence accumula
2323
- 🧑‍💻 **Account governance (access review; defaults to admin·security, admin configures view roles)** — collect server/PC **local accounts** via osquery (`POST /ingest/accounts`) and reconcile them against the **LDAP directory × approval list** → auto-detect **leaver-remains · unmanaged privileged · unapproved sudo · dormant** accounts. Dedicated **🔑 Accounts tab** (unified list + **IP team/purpose CSV export** + approval list + CSV evidence) + per-host account section. **View roles are configured from the admin console Access tab** (`account_view_roles`, admin always included). ISMS-P 2.5.1·2.5.5·2.5.6 / ISO A.5.16·A.5.18·A.8.2. e.g. `osquery "SELECT * FROM users" → POST /ingest/accounts`
2424
- 📊 **Screens** — Unified dashboard · Alert Triage · Incidents · Assets / Vulnerabilities · **Risk Assessment Matrix** · Compliance PDCA + **Control catalog (ISMS-P 101 × ISO)** · 6 audit-evidence CSV/PDF reports
2525
- 🎯 **Risk Assessment (R-series)** — Per-CVE **Risk = Impact (asset importance H/M/L) × Likelihood (severity)** as a **score (1–9)** on a 3×3 matrix (score-forward), with treatment decision (mitigate/accept/transfer/avoid) · residual risk · review date. **Admin-only assessment-basis (provenance)** panel. A single **risk-acceptance threshold (DoA)** auto-classifies risks at or below it as **auto-acceptable**. Based on ISMS-P risk management / ISO 27001 6.1.2·8.8
26-
- 📚 **Control catalog (Phase 2)** — ISMS-P 101 + ISO 27001:2022 93 = **194 criteria** (KO/EN) as a tree in the **Compliance tab**. Edit each control's **implementation status (implemented/partial/not-implemented/N-A) · owner · plan · due date** → persisted to `control_status` (`schema/009`, survives restarts) + change history. **Admins edit the catalog itself** (add/edit/delete controls) — an overlay (`schema/011`) kept separate from the base (`controls/*.yaml`) so it survives re-sync. **Regulation-text NLP import** (`POST /controls/import-nlp`) — precise structuring via Claude when `MORI_ANTHROPIC_API_KEY` is set, clause-level heuristic otherwise → saved as draft controls. Per control, **document manual evidence** (`control_evidence`: title, body, collector, date, reference) and **download the evidence pack as CSV or PDF** (live + documented, merged). Editing = admin; evidence documentation/view = admin·security
26+
- 📚 **Control catalog (Phase 2)** — ISMS-P 101 + ISO 27001:2022 93 = **194 criteria** (KO/EN) as a tree in the **Compliance tab**. Edit each control's **implementation status (implemented/partial/not-implemented/N-A) · owner · plan · due date** → persisted to `control_status` (`schema/009`, survives restarts) + change history. **Admins edit the catalog itself** (add/edit/delete controls) — an overlay (`schema/011`) kept separate from the base (`controls/*.yaml`) so it survives re-sync. **Regulation-text NLP import** (`POST /controls/import-nlp`) — precise structuring via Claude when `MORI_ANTHROPIC_API_KEY` is set, clause-level heuristic otherwise → saved as draft controls. Per control, **document manual evidence** (`control_evidence`: title, body, collector, date, reference) or **⚡ auto-snapshot the live evidence** into a dated record (`POST …/evidence-records/auto`, `source=auto`), and **download the evidence pack as CSV or PDF** (live + documented, merged). Editing = admin; evidence documentation/view = admin·security
2727
- 🔐 **Role-aware screens** — Risk assessment & control catalog are **admin·security only**; infra/helpdesk see only **their servers' vulnerabilities & remediation rate**. **My servers** is trimmed to `hostname·importance·status·IP`; **double-click a row** opens a detail modal that buckets open items into **exception-expired / overdue / other risks** + **Zabbix/Grafana/Fleet deep-links** (per asset kind). Asset tables have **team & 'my assets only' filters**. The Trivy table shows a **risk score (1–9)** instead of severity counts. The dashboard is a **role-aware security hero + 24h/12h infra status (Zabbix/Wazuh deep links)**, with **panel editing** for per-user widget selection (persisted)
2828
- 🌐 **Multi-language UI** — Korean / English toggle on every page (login, dashboard, admin console); moved from a fixed top-right widget into the **account menu (👤)**, persisted in a cookie + localStorage and switches instantly without a reload
2929
- 👤 **User profile + My Servers** — Save name · department · assigned servers to your account, and view only your assets in a dedicated **⭐ My Servers** view (profile-menu shortcut)

README_FULL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
- 🧑‍💻 **계정 거버넌스 (접근권한 검토, 기본 admin·security · admin이 열람 역할 조정)** — 서버·PC **로컬 계정**을 osquery로 수집(`POST /ingest/accounts`)해 **LDAP 디렉터리 × 승인 대장**과 대조 → **퇴사자 잔존·미등록 특권·미승인 sudo·휴면 계정** 자동 검출. 전용 **🔑 계정 탭**(통합 목록 + **IP 팀/용도 선별 CSV** + 승인 대장 + CSV 증적) + 호스트 상세 계정 섹션. **열람 역할은 어드민 콘솔 권한 탭에서 조정**(`account_view_roles`, admin 항상 포함). ISMS-P 2.5.1·2.5.5·2.5.6 / ISO A.5.16·A.5.18·A.8.2. 예: `osquery "SELECT * FROM users" → POST /ingest/accounts`
2424
- 📊 **화면** — 통합 대시보드 · Alert Triage · 인시던트 · 자산/취약점 · **위험성 평가 매트릭스** · Compliance PDCA + **통제 카탈로그(ISMS-P 101 × ISO)** · 6종 감사 증적 CSV/PDF
2525
- 🎯 **위험성 평가 (R-series)** — 취약점(CVE)별 **위험도 = 영향도(자산 중요도 상/중/하) × 발생가능성(심각도)** 를 3×3 매트릭스로 **점수(1~9)** 산정(라벨보다 점수 우선), 위험처리 결정(조치/수용/이관/회피)·잔여위험·재평가일 기록. **어드민 전용 산정 근거(provenance)** 패널. **위험 수용 기준(DoA)** — admin이 임계 점수를 입력하면 그 이하 위험은 **기본 수용가능**으로 자동 분류. ISMS-P 위험관리 / ISO 27001 6.1.2·8.8 기반
26-
- 📚 **통제 카탈로그 (Phase 2)** — ISMS-P 101 + ISO 27001:2022 93 = **194개 인증기준**(한/영) 트리를 **컴플라이언스 탭**에 표시. 통제별 **이행 상태(이행/부분이행/미이행/해당없음)·담당자·개선계획·기한을 편집**하면 `control_status`(`schema/009`)에 **영속(재시작 유지)** + 변경 이력 기록. **admin은 카탈로그 정본을 직접 편집**(통제 추가/수정/삭제) — base(`controls/*.yaml`)와 분리된 오버레이(`schema/011`)에 쌓여 재싱크에도 유지. **법령/고시 텍스트 NLP 임포트**(`POST /controls/import-nlp`) — `MORI_ANTHROPIC_API_KEY`가 있으면 Claude로 정밀 구조화, 없으면 조항 단위 휴리스틱 → 통제 초안(draft) 저장. 통제별 **수기 증적 문서화**(`control_evidence`, 제목·내용·수집자·수집일·참조)와 **증적 팩 CSV/PDF 선택 다운로드**(라이브+수기 합본). 편집=admin, 증적 문서화·열람=admin·security
26+
- 📚 **통제 카탈로그 (Phase 2)** — ISMS-P 101 + ISO 27001:2022 93 = **194개 인증기준**(한/영) 트리를 **컴플라이언스 탭**에 표시. 통제별 **이행 상태(이행/부분이행/미이행/해당없음)·담당자·개선계획·기한을 편집**하면 `control_status`(`schema/009`)에 **영속(재시작 유지)** + 변경 이력 기록. **admin은 카탈로그 정본을 직접 편집**(통제 추가/수정/삭제) — base(`controls/*.yaml`)와 분리된 오버레이(`schema/011`)에 쌓여 재싱크에도 유지. **법령/고시 텍스트 NLP 임포트**(`POST /controls/import-nlp`) — `MORI_ANTHROPIC_API_KEY`가 있으면 Claude로 정밀 구조화, 없으면 조항 단위 휴리스틱 → 통제 초안(draft) 저장. 통제별 **수기 증적 문서화**(`control_evidence`, 제목·내용·수집자·수집일·참조) 또는 **⚡실증적 자동 스냅샷**(라이브 집계를 날짜 찍힌 증적으로 원클릭 생성, `POST …/evidence-records/auto`, `source=auto`)와 **증적 팩 CSV/PDF 선택 다운로드**(라이브+수기 합본). 편집=admin, 증적 문서화·열람=admin·security
2727
- 🔐 **역할별 화면** — 위험성 평가·통제 카탈로그는 **admin·security 전용**, 인프라·헬프데스크는 **내 담당 서버 취약점·조치율**만 열람. **내 담당 서버**`호스트명·중요도·상태·IP`로 간소화, 행 **더블클릭 → 상세 모달**에서 미조치를 **예외 만료·조치기한 초과·기타 위험** 3버킷으로 표시 + **Zabbix/Grafana/Fleet 딥링크**(자산 종류별). 자산 표엔 **팀별·'내 자산만' 필터**. 취약점(Trivy) 표는 심각도 대신 **위험점수(1~9)** 표기. 대시보드는 **역할별 보안 히어로 + 24h/12h 인프라 현황(Zabbix/Wazuh 딥링크)** 로 구성, **패널 편집**으로 개인별 위젯 선택·영속화
2828
- 🌐 **다국어 UI** — 로그인·대시보드·어드민 콘솔 전 페이지 한국어/영어 토글 (우상단 고정 위젯 → **계정 메뉴(👤)**로 이동, 쿠키·localStorage 저장, 새로고침 없이 즉시 전환)
2929
- 👤 **사용자 프로필 + 내 서버** — 이름·부서·담당 서버를 계정에 저장하고, 담당 자산만 모아 보는 **⭐ 내 서버** 뷰(프로필 메뉴 바로가기) 제공

schema/011_catalog_edits.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,14 @@ CREATE TABLE IF NOT EXISTS control_evidence (
3535
collected_by TEXT NOT NULL DEFAULT '',
3636
collected_at TEXT NOT NULL DEFAULT '', -- YYYY-MM-DD (수집/작성일)
3737
reference TEXT NOT NULL DEFAULT '', -- 링크/문서 위치
38+
source TEXT NOT NULL DEFAULT 'manual', -- manual | auto (실증적 스냅샷 자동 생성)
3839
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
3940
created_by TEXT
4041
);
4142

43+
-- 기존 볼륨(011 이전 생성)에도 source 컬럼을 자가 치유로 추가.
44+
ALTER TABLE control_evidence ADD COLUMN IF NOT EXISTS source TEXT NOT NULL DEFAULT 'manual';
45+
4246
CREATE INDEX IF NOT EXISTS idx_control_evidence_control ON control_evidence (control_id);
4347

4448
COMMENT ON TABLE catalog_controls IS 'admin 편집/NLP 임포트 통제 오버레이(base 카탈로그와 분리, 재싱크에도 유지).';

src/mori_soc/api/i18n.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,9 @@ def _i18n_toggle_html(fixed: bool = True) -> str:
257257
"dash.ctl.ev_ttl_ph": "증적 제목(예: 접근권한 검토 회의록)", "dash.ctl.ev_ref_ph": "참조 링크/위치",
258258
"dash.ctl.ev_body_ph": "증적 내용/설명", "dash.ctl.ev_add": "기록",
259259
"dash.ctl.ev_need_ttl": "제목을 입력하세요", "dash.ctl.ev_del_confirm": "이 수기 증적을 삭제할까요?",
260+
"dash.ctl.ev_auto": "자동", "dash.ctl.ev_auto_btn": "실증적 자동 기록",
261+
"dash.ctl.ev_auto_tip": "현재 실증적(라이브 집계)을 날짜 찍힌 증적으로 자동 생성",
262+
"dash.ctl.ev_auto_run": "스냅샷 생성 중…",
260263
"dash.ctl.nlp_ttl": "법령/고시 텍스트 → 통제 초안",
261264
"dash.ctl.nlp_help": "규정 텍스트를 붙여넣으면 통제 초안(draft)으로 변환·저장됩니다. Claude API 키가 있으면 정밀 구조화, 없으면 조항 단위 휴리스틱.",
262265
"dash.ctl.nlp_fw": "프레임워크(예: 개인정보보호법)", "dash.ctl.nlp_ph": "법령/고시 전문을 붙여넣으세요…",
@@ -899,6 +902,9 @@ def _i18n_toggle_html(fixed: bool = True) -> str:
899902
"dash.ctl.ev_ttl_ph": "Evidence title (e.g. access review minutes)", "dash.ctl.ev_ref_ph": "Reference link/location",
900903
"dash.ctl.ev_body_ph": "Evidence content/description", "dash.ctl.ev_add": "Record",
901904
"dash.ctl.ev_need_ttl": "Enter a title", "dash.ctl.ev_del_confirm": "Delete this evidence record?",
905+
"dash.ctl.ev_auto": "auto", "dash.ctl.ev_auto_btn": "Auto-capture live evidence",
906+
"dash.ctl.ev_auto_tip": "Snapshot the current live evidence into a dated record",
907+
"dash.ctl.ev_auto_run": "Creating snapshot…",
902908
"dash.ctl.nlp_ttl": "Regulation text → control drafts",
903909
"dash.ctl.nlp_help": "Paste regulation text to convert & save it as draft controls. Precise structuring with a Claude API key; clause-level heuristic otherwise.",
904910
"dash.ctl.nlp_fw": "Framework (e.g. PIPA)", "dash.ctl.nlp_ph": "Paste the full regulation/notice text…",

0 commit comments

Comments
 (0)