DocVault X-Ray

DocVault๋ฅผ endpoint๋ถ€ํ„ฐ hash-chain๊นŒ์ง€ ์„ค๋ช…ํ•˜๋Š” ํŽ˜์ด์ง€

๋ชฉํ‘œ๋Š” ๋ณด์•ˆ ์šฉ์–ด๋ฅผ ์™ธ์šฐ๋Š” ๊ฒŒ ์•„๋‹ˆ๋‹ค. ๋ฌด์—‡์„ ํƒ์ง€ํ•˜๋Š” ์ œํ’ˆ์ธ์ง€, ์™œ Go/Postgres/htmx์ธ์ง€, endpoint agent๊ฐ€ ์–ด๋–ป๊ฒŒ ๋“ค์–ด์˜ค๋Š”์ง€, ๊ฐ์‚ฌ ๋กœ๊ทธ ๋ฌด๊ฒฐ์„ฑ์„ ์–ด๋–ป๊ฒŒ ๋ณด์žฅํ•˜๋Š”์ง€, ์–ด๋””๊นŒ์ง€๊ฐ€ ํ•œ๊ณ„์ธ์ง€๋ฅผ ๋„ค ์ž…์œผ๋กœ ์„ค๋ช…ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค.

49
cards
12
domains
10
flows
One sentence

DocVault is a self-hosted insider-risk event collection and audit tool: endpoint agents send activity, Go normalizes it, Postgres stores tamper-evident logs, and admins review alerts through an htmx console.

ํ•ต์‹ฌ์€ โ€œ์ฐจ๋‹จโ€์ด ์•„๋‹ˆ๋ผ โ€œํƒ์ง€์™€ ๊ฐ์‚ฌโ€๋‹ค. Go/Postgres/htmx๋ฅผ ์“ด ์ด์œ ๋„ ์ด ๋ฒ”์œ„์™€ endpoint agent ๋ฐฐํฌ ๋ฌธ์ œ์—์„œ ๋‚˜์˜จ๋‹ค.

Tech stack from absolute zero

Go, Postgres, chi, pgx, htmx, osquery, JWT, TOTP, AES-GCM, hash chain, Docker Compose, Caddy ๊ฐ™์€ ๋‹จ์–ด๋ฅผ ๋ˆ„๋ฅด๋ฉด ์ด๊ฒŒ ๋ญ”์ง€, ์™œ ์ผ๋Š”์ง€, ๋Œ€์•ˆ๊ณผ trade-off๊ฐ€ ๋ญ”์ง€, ์–ด๋”” ์ฝ”๋“œ์— ์žˆ๋Š”์ง€ ๋ฐ”๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

44
stack cards

0. Product shape

1
0. Product shapeCore

Insider-risk event collection product

์ง์› PC ์ด๋ฒคํŠธ๋ฅผ ๋ชจ์•„ ๋‚ด๋ถ€์ž ์œ„ํ˜‘์„ ์‚ฌํ›„ ํƒ์ง€ํ•˜๋Š” ์ œํ’ˆ์ด๋‹ค.

DocVault is a detection and audit product for small teams, not a DRM or full EDR replacement.

What it does

osquery์™€ ์ž์ฒด clipboard agent๊ฐ€ endpoint activity๋ฅผ ๋ณด๋‚ด๊ณ , Go server๊ฐ€ Postgres์— ์ €์žฅํ•œ ๋’ค ๊ด€๋ฆฌ์ž๊ฐ€ web UI์—์„œ ์กฐํšŒํ•œ๋‹ค.

Why this stack

์ด ์ œํ’ˆ์˜ ๋ชฉ์ ์€ DRM์ฒ˜๋Ÿผ ์ฐจ๋‹จํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ž‘์€ ํŒ€์ด ์œ ์ถœ ์ง•ํ›„๋ฅผ ๋นจ๋ฆฌ ๋ณด๊ณ  ์กฐ์‚ฌ ๊ทผ๊ฑฐ๋ฅผ ๋‚จ๊ธฐ๋Š” ๊ฒƒ์ด๋‹ค.

Trade-off

์ฐจ๋‹จ์„ ๋ชป ํ•œ๋‹ค. ์‚ฌ๊ณ  ํ›„ ํƒ์ง€์™€ ๊ฐ์‚ฌ์—๋Š” ๋งž์ง€๋งŒ ๊ฐ•์ œ DRM/EDR ๋Œ€์ฒดํ’ˆ์œผ๋กœ ํŒ”๋ฉด ํ‹€๋ฆฐ๋‹ค.

Alternative

DRM์€ ์ฐจ๋‹จ์ด ๊ฐ•ํ•˜์ง€๋งŒ ์—…๋ฌด ๋งˆ์ฐฐ์ด ํฌ๊ณ , EDR์€ ๊นŠ์€ ๊ฐ€์‹œ์„ฑ์ด ์žˆ์ง€๋งŒ ๋น„์šฉ/์šด์˜์ด ๋ฌด๊ฒ๋‹ค.

Terms you must know
  • insider risk = ๋‚ด๋ถ€ ๊ตฌ์„ฑ์›์— ์˜ํ•œ ์ •๋ณด ์œ ์ถœ ์œ„ํ—˜
  • detection = ์ผ์ด ๋ฐœ์ƒํ•œ ๋’ค ์ฐพ๋Š” ๊ฒƒ
  • prevention = ์ผ์ด ๋ฐœ์ƒํ•˜๊ธฐ ์ „์— ๋ง‰๋Š” ๊ฒƒ
Where

docvault/README.md, docs/ARCHITECTURE.md

Beginner trap

๊ฐ์‹œ ์ œํ’ˆ์ด๋ผ๊ณ  ๋งํ•˜๊ธฐ ์ „์— ํ•ฉ๋ฒ•์  ๋™์˜์™€ ํšŒ์‚ฌ ์†Œ์œ  PC ๋ฒ”์œ„๋ฅผ ๋งํ•ด์•ผ ํ•œ๋‹ค.

1. Languages

1
1. LanguagesCore

Go 1.26

์„œ๋ฒ„์™€ endpoint agent๋ฅผ ๊ฐ™์€ ์–ธ์–ด๋กœ ๋งŒ๋“ ๋‹ค.

Go was chosen mainly because the same codebase can ship the server and lightweight cross-platform endpoint agents.

What it does

HTTP server, clipboard agent, crypto, DB access, scheduled background work๋ฅผ Go binary๋กœ ์‹คํ–‰ํ•œ๋‹ค.

Why this stack

์—์ด์ „ํŠธ ๋ฐฐํฌ๊ฐ€ ํ•ต์‹ฌ์ด๋ผ JVM/Python runtime ์—†์ด Windows/macOS ๋‹จ์ผ ์‹คํ–‰ํŒŒ์ผ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” Go๊ฐ€ ๋งž๋‹ค.

Trade-off

ML/data science ์ƒํƒœ๊ณ„๋Š” Python๋ณด๋‹ค ์•ฝํ•˜๊ณ  ๊ณ ์ˆ˜์ค€ ์ถ”์ƒํ™”๋Š” Java/Kotlin๋ณด๋‹ค ๋‹จ์ˆœํ•˜๋‹ค.

Alternative

Java/Spring์€ enterprise ์„œ๋ฒ„์— ๊ฐ•ํ•˜์ง€๋งŒ agent ๋ฐฐํฌ๊ฐ€ ๋ฌด๊ฒ๊ณ , Rust๋Š” ์•ˆ์ „ํ•˜์ง€๋งŒ ๊ฐœ๋ฐœ ์†๋„ ๋น„์šฉ์ด ํฌ๋‹ค.

Terms you must know
  • compiled language = ์‹คํ–‰ํŒŒ์ผ๋กœ ๋ฒˆ์—ญ๋˜๋Š” ์–ธ์–ด
  • static binary = dependency๋ฅผ ๋งŽ์ด ํ’ˆ์€ ๋‹จ์ผ ์‹คํ–‰ํŒŒ์ผ
  • goroutine = Go์˜ ๊ฐ€๋ฒผ์šด ๋™์‹œ ์ž‘์—… ๋‹จ์œ„
Where

go.mod, cmd/server, cmd/clipagent

Beginner trap

์„œ๋ฒ„๋งŒ ๋ณด๊ณ  Go๋ฅผ ๊ณจ๋ž๋‹ค๊ณ  ๋งํ•˜์ง€ ๋ง๊ณ  agent ๋ฐฐํฌ ๋™๊ธฐ๋ฅผ ๋ฐ˜๋“œ์‹œ ๋งํ•ด์•ผ ํ•œ๋‹ค.

2. Runtime

3
2. RuntimeCore

osquery

PC ์ƒํƒœ๋ฅผ SQL์ฒ˜๋Ÿผ ์กฐํšŒํ•˜๋Š” ์˜คํ”ˆ์†Œ์Šค endpoint agent๋‹ค.

osquery is used for endpoint telemetry so DocVault does not reinvent file, USB, and process collection from scratch.

What it does

ํŒŒ์ผ ๋ณ€๊ฒฝ, USB, process ๊ฐ™์€ endpoint telemetry๋ฅผ scheduled query๋กœ ์ˆ˜์ง‘ํ•œ๋‹ค.

Why this stack

๊ฒ€์ฆ๋œ endpoint collector๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๊ณ  DocVault๋Š” normalize/store/analyze์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

Trade-off

user-mode๋ผ kernel-level ๊ณต๊ฒฉ์ด๋‚˜ ์ง์ ‘ ์ฐจ๋‹จ์€ ๋ชป ํ•œ๋‹ค.

Alternative

์ง์ ‘ agent๋ฅผ ๋งŒ๋“ค๋ฉด ํ†ต์ œ๋Š” ๊ฐ•ํ•˜์ง€๋งŒ ๋น„์šฉ์ด ํฌ๊ณ , ์ƒ์šฉ EDR์€ ๊ฐ•ํ•˜์ง€๋งŒ ๊ฐ€๊ฒฉ/์šด์˜์ด ๋ฌด๊ฒ๋‹ค.

Terms you must know
  • telemetry = ์‹œ์Šคํ…œ์—์„œ ์ˆ˜์ง‘ํ•œ ๊ด€์ธก ๋ฐ์ดํ„ฐ
  • scheduled query = ์ผ์ •๋งˆ๋‹ค ์‹คํ–‰๋˜๋Š” query
  • user-mode = ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž ๊ณต๊ฐ„์—์„œ ๋„๋Š” ํ”„๋กœ๊ทธ๋žจ
Where

deploy/osquery, internal/endpoint/osquery.go

Beginner trap

osquery๋ฅผ ์“ด๋‹ค๊ณ  EDR ์ˆ˜์ค€์˜ ์ปค๋„ ๊ฐ€์‹œ์„ฑ์ด ์ƒ๊ธฐ๋Š” ๊ฑด ์•„๋‹ˆ๋‹ค.

2. RuntimeCore

Go clipboard agent

์ง์› PC์—์„œ clipboard ๋ณ€ํ™”๋ฅผ ๊ฐ์‹œํ•˜๋Š” ์ž์ฒด agent๋‹ค.

The custom clipboard agent covers a specific exfiltration signal that osquery does not handle well.

What it does

Windows/macOS๋ณ„ clipboard API๋ฅผ ์ฝ๊ณ  ์ด๋ฒคํŠธ, heartbeat, self-test๋ฅผ ์„œ๋ฒ„์— POSTํ•œ๋‹ค.

Why this stack

osquery๊ฐ€ clipboard๋ฅผ ์ง์ ‘ ์ปค๋ฒ„ํ•˜์ง€ ๋ชปํ•˜๋ฏ€๋กœ ์œ ์ถœ ์œ„ํ—˜์ด ํฐ ๋ณต์‚ฌ ๋™์ž‘์„ ๋ณ„๋„ agent๋กœ ์žก๋Š”๋‹ค.

Trade-off

OS๋ณ„ API์™€ ๊ถŒํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ๊ณ  Windows์—์„œ๋Š” ์„œ๋น„์Šค๊ฐ€ ์•„๋‹Œ ์‚ฌ์šฉ์ž ์„ธ์…˜ ์‹คํ–‰์ด ํ•„์š”ํ•˜๋‹ค.

Alternative

ํด๋ฆฝ๋ณด๋“œ ๊ฐ์‹œ๋ฅผ ํฌ๊ธฐํ•˜๋ฉด ์„ค์น˜๋Š” ์‰ฌ์›Œ์ง€์ง€๋งŒ ํ•ต์‹ฌ ์œ ์ถœ ์ฑ„๋„ ํ•˜๋‚˜๊ฐ€ ๋น ์ง„๋‹ค.

Terms you must know
  • clipboard = ๋ณต์‚ฌ/๋ถ™์—ฌ๋„ฃ๊ธฐ ์ž„์‹œ ์ €์žฅ์†Œ
  • agent = endpoint์— ์„ค์น˜๋˜๋Š” ์ž‘์€ ํ”„๋กœ๊ทธ๋žจ
  • heartbeat = ์‚ด์•„์žˆ์Œ์„ ์ฃผ๊ธฐ์ ์œผ๋กœ ์•Œ๋ฆฌ๋Š” ์‹ ํ˜ธ
Where

cmd/clipagent, internal/endpoint/clipboard.go

Beginner trap

ํด๋ฆฝ๋ณด๋“œ ๊ฐ์‹œ๋Š” ๋ฏผ๊ฐํ•˜๋ฏ€๋กœ ํšŒ์‚ฌ ์žฅ๋น„/๋™์˜/๊ณ ์ง€ ๋ฒ”์œ„๋ฅผ ๋ถ„๋ช…ํžˆ ํ•ด์•ผ ํ•œ๋‹ค.

2. RuntimeCore

Windows Scheduled Task

Windows์—์„œ ์‚ฌ์šฉ์ž ๋กœ๊ทธ์ธ ์„ธ์…˜์— agent๋ฅผ ์ž๋™ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

The Windows agent runs as a per-user scheduled task because clipboard capture requires an interactive user session.

What it does

installer bat๊ฐ€ DocVaultClipAgent scheduled task๋ฅผ ๋งŒ๋“ค๊ณ  interactive session์—์„œ clipboard๋ฅผ ์ฝ๊ฒŒ ํ•œ๋‹ค.

Why this stack

LocalSystem service๋Š” Session 0 ๋ฌธ์ œ ๋•Œ๋ฌธ์— clipboard ์ ‘๊ทผ์ด ์•ˆ ๋˜๋ฏ€๋กœ Scheduled Task๊ฐ€ ํ˜„์‹ค์  ์„ ํƒ์ด๋‹ค.

Trade-off

์„œ๋น„์Šค๋ณด๋‹ค ์ค‘์•™ ๊ด€๋ฆฌ/๊ฒฉ๋ฆฌ๊ฐ์€ ์•ฝํ•˜๊ณ  ์‚ฌ์šฉ์ž session ์ƒํƒœ์— ์˜์กดํ•œ๋‹ค.

Alternative

Windows service๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์šด์˜์ด ๊ฐ•ํ•˜์ง€๋งŒ clipboard์—๋Š” ๋ถ€์ ํ•ฉํ•˜๊ณ , ์ˆ˜๋™ ์‹คํ–‰์€ ์‹ ๋ขฐ์„ฑ์ด ๋‚ฎ๋‹ค.

Terms you must know
  • Session 0 = Windows service๊ฐ€ ๋„๋Š” ๋น„์ƒํ˜ธ์ž‘์šฉ ์„ธ์…˜
  • interactive session = ์‚ฌ์šฉ์ž๊ฐ€ ๋ณด๋Š” ํ™”๋ฉด ์„ธ์…˜
  • Scheduled Task = Windows ์ž๋™ ์‹คํ–‰ ์ž‘์—…
Where

internal/web/pages.go installer, docs/DEPLOY.md

Beginner trap

์„œ๋น„์Šค๋กœ ๋งŒ๋“ค๋ฉด ๋” professionalํ•ด ๋ณด์ธ๋‹ค๊ณ  ๋ฌด์กฐ๊ฑด ๋งž๋Š” ๊ฒŒ ์•„๋‹ˆ๋‹ค.

3. Frontend

3
3. FrontendCore

htmx

์„œ๋ฒ„๊ฐ€ ๋งŒ๋“  HTML ์กฐ๊ฐ์œผ๋กœ ํ™”๋ฉด ์ผ๋ถ€๋ฅผ ๊ฐฑ์‹ ํ•˜๋Š” ์ž‘์€ JS library๋‹ค.

htmx is a pragmatic frontend choice because DocVault is an admin console, not a highly interactive consumer SPA.

What it does

๊ด€๋ฆฌ์ž ํ™”๋ฉด์—์„œ React SPA ์—†์ด search, form submit, partial update, dashboard UI๋ฅผ ๋งŒ๋“ ๋‹ค.

Why this stack

ํŽ˜์ด์ง€ ์ˆ˜๊ฐ€ ์ œํ•œ๋œ admin tool์ด๋ผ ๋นŒ๋“œ ์Šคํ… ์—†๋Š” htmx๊ฐ€ ๋ณต์žก๋„๋ฅผ ํฌ๊ฒŒ ์ค„์ธ๋‹ค.

Trade-off

ํด๋ผ์ด์–ธํŠธ ์ƒํƒœ๊ฐ€ ๋งค์šฐ ๋ณต์žกํ•ด์ง€๋ฉด round-trip๊ณผ DOM fragment ๊ด€๋ฆฌ๊ฐ€ ๋ถ€๋‹ด๋œ๋‹ค.

Alternative

React/Vue SPA๋Š” ๋ณต์žกํ•œ client state์— ๊ฐ•ํ•˜์ง€๋งŒ build chain๊ณผ frontend architecture๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

Terms you must know
  • server-rendered HTML = ์„œ๋ฒ„๊ฐ€ ๋งŒ๋“  HTML์„ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ฐ›๋Š” ๋ฐฉ์‹
  • partial update = ํŽ˜์ด์ง€ ์ „์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ ์ผ๋ถ€๋งŒ ๊ฐˆ์•„๋ผ์›€
  • round-trip = ๋ธŒ๋ผ์šฐ์ €์™€ ์„œ๋ฒ„๋ฅผ ์™•๋ณตํ•˜๋Š” ์š”์ฒญ
Where

internal/web/static/htmx.min.js, templates

Beginner trap

htmx๋ฅผ ์“ฐ๋ฉด ํ”„๋ก ํŠธ์—”๋“œ๊ฐ€ ์—†๋‹ค๋Š” ๋œป์ด ์•„๋‹ˆ๋ผ ์„œ๋ฒ„ ๋ Œ๋”๋ง ํ”„๋ก ํŠธ์—”๋“œ๋ผ๋Š” ๋œป์ด๋‹ค.

3. FrontendCore

Go html/template

์„œ๋ฒ„์—์„œ HTML ํ™”๋ฉด์„ ๋งŒ๋“œ๋Š” template engine์ด๋‹ค.

Go templates keep the admin UI server-rendered and deployable as a single Go service.

What it does

layout, dashboard, files, audit, agents, admin pages๋ฅผ data map๊ณผ template๋กœ ๋ Œ๋”๋งํ•œ๋‹ค.

Why this stack

Go binary ์•ˆ์—์„œ UI์™€ backend๋ฅผ ๊ฐ™์ด ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ๊ณ  XSS escaping ๊ธฐ๋ณธ๊ฐ’์ด ์žˆ๋‹ค.

Trade-off

template๊ฐ€ ์ปค์ง€๋ฉด component ์žฌ์‚ฌ์šฉ๊ณผ ํƒ€์ž… ์•ˆ์ •์„ฑ์ด ์•ฝํ•ด์ง„๋‹ค.

Alternative

React server components, templ, Jet, Jinja ๊ฐ™์€ template engine์ด ๋Œ€์•ˆ์ด๋‹ค.

Terms you must know
  • template = data๋ฅผ ๋ผ์›Œ HTML์„ ๋งŒ๋“œ๋Š” ํŒŒ์ผ
  • escaping = ์œ„ํ—˜ ๋ฌธ์ž๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๋ฐ”๊พธ๋Š” ์ฒ˜๋ฆฌ
  • server-side rendering = ์„œ๋ฒ„๊ฐ€ ํ™”๋ฉด์„ ๋งŒ๋“ค์–ด ๋ณด๋‚ด๋Š” ๋ฐฉ์‹
Where

internal/web/templates, internal/web/render.go

Beginner trap

template escaping์ด ์žˆ๋‹ค๊ณ  ๋ชจ๋“  XSS๊ฐ€ ์ž๋™ ๋ฐฉ์–ด๋˜๋Š” ๊ฑด ์•„๋‹ˆ๋‹ค.

3. FrontendCore

Server-Sent Events

์„œ๋ฒ„๊ฐ€ ๋ธŒ๋ผ์šฐ์ €๋กœ ์‹ค์‹œ๊ฐ„ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ€์–ด์ฃผ๋Š” ๋‹จ๋ฐฉํ–ฅ stream์ด๋‹ค.

SSE gives the dashboard live updates without introducing a full bidirectional WebSocket system.

What it does

dashboard์— endpoint event๋‚˜ alert๊ฐ€ ๋“ค์–ด์™”์„ ๋•Œ refresh ์—†์ด ๋ณด์—ฌ์ฃผ๋Š” ๋ฐ ์‚ฌ์šฉํ•œ๋‹ค.

Why this stack

๊ด€๋ฆฌ์ž console์—๋Š” WebSocket ์–‘๋ฐฉํ–ฅ ํ†ต์‹ ๋ณด๋‹ค ๋‹จ์ˆœํ•œ SSE๊ฐ€ ์ถฉ๋ถ„ํ•˜๋‹ค.

Trade-off

client์—์„œ server๋กœ๋„ ์‹ค์‹œ๊ฐ„ ๋ฉ”์‹œ์ง€๋ฅผ ๋งŽ์ด ๋ณด๋‚ด์•ผ ํ•˜๋ฉด WebSocket์ด ๋” ๋งž๋‹ค.

Alternative

polling์€ ๋‹จ์ˆœํ•˜์ง€๋งŒ ์ง€์—ฐ/๋ถ€ํ•˜๊ฐ€ ์žˆ๊ณ , WebSocket์€ ๊ฐ•๋ ฅํ•˜์ง€๋งŒ ์ƒํƒœ ๊ด€๋ฆฌ๊ฐ€ ๋ฌด๊ฒ๋‹ค.

Terms you must know
  • SSE = HTTP๋กœ ์„œ๋ฒ„๊ฐ€ ์ด๋ฒคํŠธ๋ฅผ ๊ณ„์† ๋ณด๋‚ด๋Š” ๋ฐฉ์‹
  • stream = ์—ฐ๊ฒฐ์„ ์œ ์ง€ํ•˜๋ฉฐ ๋ฐ์ดํ„ฐ๊ฐ€ ํ๋ฅด๋Š” ํ†ต๋กœ
  • polling = ์ฃผ๊ธฐ์ ์œผ๋กœ ์ƒˆ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š”์ง€ ๋ฌป๋Š” ๋ฐฉ์‹
Where

internal/web/sse.go, router /api/events/stream

Beginner trap

SSE๋Š” ์˜ค๋ž˜ ์—ด๋ฆฐ ์—ฐ๊ฒฐ์ด๋ผ server timeout/write timeout ์„ค์ •์„ ์‹ ๊ฒฝ ์จ์•ผ ํ•œ๋‹ค.

5. Backend

9
5. BackendCore

net/http

Go ํ‘œ์ค€ HTTP server ๊ธฐ๋ฐ˜์ด๋‹ค.

The server stays close to Go's standard net/http model, which keeps routing and middleware explicit.

What it does

chi router๊ฐ€ ํ‘œ์ค€ net/http handler ์œ„์—์„œ request/response๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.

Why this stack

ํ‘œ์ค€ library๋ผ dependency๊ฐ€ ์ž‘๊ณ , middleware/handler model์ด ๋‹จ์ˆœํ•ด์„œ ๋ณด์•ˆ ๊ฒฝ๊ณ„๋ฅผ ์ถ”์ ํ•˜๊ธฐ ์‰ฝ๋‹ค.

Trade-off

framework๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์€ ์ง์ ‘ ์กฐ๋ฆฝํ•ด์•ผ ํ•œ๋‹ค.

Alternative

Gin/Echo/Fiber๋Š” ๋” ๋งŽ์€ convenience๋ฅผ ์ฃผ์ง€๋งŒ framework convention๊ณผ dependency๊ฐ€ ๋Š˜์–ด๋‚œ๋‹ค.

Terms you must know
  • handler = HTTP ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜
  • ResponseWriter = ์‘๋‹ต์„ ์“ฐ๋Š” ๊ฐ์ฒด
  • Request = ๋“ค์–ด์˜จ HTTP ์š”์ฒญ ๊ฐ์ฒด
Where

internal/web/router.go, cmd/server/main.go

Beginner trap

net/http๋Š” router๊ฐ€ ์•„๋‹ˆ๋ผ HTTP server primitive๋‹ค.

5. BackendCore

chi router

HTTP ๊ฒฝ๋กœ๋ฅผ handler์™€ middleware๋กœ ์—ฐ๊ฒฐํ•˜๋Š” Go router๋‹ค.

chi gives DocVault a small, explicit routing layer around authentication, audit logging, and admin-only routes.

What it does

JWT, audit, CSRF, role check ๊ฐ™์€ middleware chain์„ route group๋ณ„๋กœ ๋ถ™์ธ๋‹ค.

Why this stack

ํ‘œ์ค€ net/http์™€ ์ž˜ ๋งž๊ณ  router ์ž์ฒด๊ฐ€ ์ž‘์•„์„œ admin tool backend์— ์ถฉ๋ถ„ํ•˜๋‹ค.

Trade-off

๋Œ€ํ˜• framework์ฒ˜๋Ÿผ validation/DI/ORM์„ ์ž๋™ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค.

Alternative

์ˆœ์ˆ˜ net/http๋Š” ๋” ์ˆ˜๋™์ด๊ณ , Gin/Echo๋Š” ๊ธฐ๋Šฅ์ด ๋งŽ์ง€๋งŒ lock-in๊ณผ ์ถ”์ƒํ™”๊ฐ€ ๋Š˜์–ด๋‚œ๋‹ค.

Terms you must know
  • router = URL์„ ์•Œ๋งž์€ handler๋กœ ๋ณด๋‚ด๋Š” ๊ตํ†ต์ •๋ฆฌ
  • middleware = request ์ „ํ›„์— ๊ณตํ†ต์œผ๋กœ ๋ผ๋Š” ์ฒ˜๋ฆฌ
  • route group = ๊ฐ™์€ middleware๋ฅผ ๊ณต์œ ํ•˜๋Š” ๊ฒฝ๋กœ ๋ฌถ์Œ
Where

internal/web/router.go

Beginner trap

๋ผ์šฐํ„ฐ๊ฐ€ ๋ณด์•ˆ ์ •์ฑ…์„ ๋Œ€์‹ ํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ middleware๋ฅผ ์–ด๋””์— ๋ถ™์˜€๋Š”์ง€๊ฐ€ ์ค‘์š”ํ•˜๋‹ค.

5. BackendCore

Agent enrollment

endpoint agent๋ฅผ ์„œ๋ฒ„์— ๋“ฑ๋กํ•˜๊ณ  hostname์„ ์‚ฌ์šฉ์ž์™€ ์—ฐ๊ฒฐํ•˜๋Š” ํ๋ฆ„์ด๋‹ค.

Enrollment turns raw endpoint hostnames into accountable user timelines.

What it does

install token, reported username, hostname, source๋ฅผ ๋ฐ›์•„ endpoint_agents์™€ user mapping์„ ๊ฐฑ์‹ ํ•œ๋‹ค.

Why this stack

์ด๋ฒคํŠธ๋ฅผ ์‚ฌ๋žŒ์—๊ฒŒ ๊ท€์†ํ•ด์•ผ dashboard์™€ audit timeline์ด ์˜๋ฏธ๋ฅผ ๊ฐ–๋Š”๋‹ค.

Trade-off

hostname/user ์ž๋™ ๋งคํ•‘์ด ํ‹€๋ฆฌ๋ฉด ์ž˜๋ชป๋œ ์‚ฌ๋žŒ์—๊ฒŒ ์ด๋ฒคํŠธ๊ฐ€ ๋ถ™์„ ์ˆ˜ ์žˆ๋‹ค.

Alternative

์ˆ˜๋™ admin assignment๋Š” ์•ˆ์ „ํ•˜์ง€๋งŒ ๋ฒˆ๊ฑฐ๋กญ๊ณ , directory integration์€ ์ •ํ™•ํ•˜์ง€๋งŒ ๊ตฌ์ถ•์ด ๋ฌด๊ฒ๋‹ค.

Terms you must know
  • enrollment = agent ์ตœ์ดˆ ๋“ฑ๋ก
  • hostname = PC ์ด๋ฆ„
  • attribution = ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ท€์†ํ•˜๋Š” ๊ฒƒ
Where

internal/endpoint/handler.go, internal/web/pages.go

Beginner trap

agent๊ฐ€ ๋ณด๋‚ด๋Š” username๋งŒ ๋งน์‹ ํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.

5. BackendCore

Audit middleware

์ธ์ฆ๋œ ์š”์ฒญ์„ ์ž๋™์œผ๋กœ audit_logs์— ๋‚จ๊ธฐ๋Š” ๊ณตํ†ต ๊ณ„์ธต์ด๋‹ค.

Audit logging belongs in middleware because every protected action must be recorded consistently.

What it does

ํ•ธ๋“ค๋Ÿฌ๋งˆ๋‹ค log ํ˜ธ์ถœ์„ ๋„ฃ์ง€ ์•Š๊ณ  middleware๊ฐ€ action, target, status๋ฅผ ๊ธฐ๋กํ•œ๋‹ค.

Why this stack

๊ฐ์‚ฌ๋Š” cross-cutting concern์ด๋ผ ๋ˆ„๋ฝ์„ ์ค„์ด๋ ค๋ฉด ๊ณตํ†ต ๊ฒฝ๊ณ„์— ๊ฐ•์ œํ•˜๋Š” ๊ฒŒ ๋งž๋‹ค.

Trade-off

path ๊ธฐ๋ฐ˜ action derivation์€ ๋ผ์šฐํŠธ ์ถ”๊ฐ€ ๋•Œ ๊นจ์งˆ ์ˆ˜ ์žˆ๋‹ค.

Alternative

๋ช…์‹œ route metadata ๋ฐฉ์‹์€ ์•ˆ์ „ํ•˜์ง€๋งŒ route ๋“ฑ๋ก ์ฝ”๋“œ๊ฐ€ ๋” ๋ณต์žกํ•ด์ง„๋‹ค.

Terms you must know
  • cross-cutting concern = ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ์— ๊ณตํ†ต์œผ๋กœ ๊ฑธ์น˜๋Š” ๊ด€์‹ฌ์‚ฌ
  • status recorder = ์‘๋‹ต ์ฝ”๋“œ๋ฅผ ์บก์ฒ˜ํ•˜๋Š” wrapper
  • target_id = ๊ฐ์‚ฌ ๋Œ€์ƒ์˜ ์‹๋ณ„์ž
Where

internal/audit/middleware.go, router protected groups

Beginner trap

๋ฏธ๋“ค์›จ์–ด๊ฐ€ ์žˆ๋‹ค๊ณ  ๋ชจ๋“  path๊ฐ€ ์ •ํ™•ํ•œ action์œผ๋กœ ๊ธฐ๋ก๋œ๋‹ค๊ณ  ๋‹จ์ •ํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.

5. BackendCore

Streaming I/O

ํฐ ํŒŒ์ผ์„ ๋ฉ”๋ชจ๋ฆฌ์— ๋ชจ๋‘ ์˜ฌ๋ฆฌ์ง€ ์•Š๊ณ  ์กฐ๊ธˆ์”ฉ ์ฝ๊ณ  ์“ฐ๋Š” ๋ฐฉ์‹์ด๋‹ค.

Streaming I/O keeps large encrypted uploads from turning into memory spikes.

What it does

multipart upload, encryption stream, disk writer, download response๊ฐ€ io.Reader/Writer๋กœ ์ด์–ด์ง„๋‹ค.

Why this stack

CAD ํŒŒ์ผ์ฒ˜๋Ÿผ ํฐ ํŒŒ์ผ์„ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋ฏ€๋กœ Go streaming abstraction์ด ์ค‘์š”ํ•˜๋‹ค.

Trade-off

์ค‘๊ฐ„ ์‹คํŒจ ์‹œ partial file cleanup๊ณผ transaction boundary๋ฅผ ์‹ ๊ฒฝ ์จ์•ผ ํ•œ๋‹ค.

Alternative

์ „์ฒด buffering์€ ๊ตฌํ˜„์€ ์‰ฝ์ง€๋งŒ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ํŒŒ์ผ ํฌ๊ธฐ์— ๋น„๋ก€ํ•œ๋‹ค.

Terms you must know
  • io.Reader = ์กฐ๊ธˆ์”ฉ ์ฝ๋Š” ์ธํ„ฐํŽ˜์ด์Šค
  • io.Writer = ์กฐ๊ธˆ์”ฉ ์“ฐ๋Š” ์ธํ„ฐํŽ˜์ด์Šค
  • backpressure = ๋А๋ฆฐ ์ชฝ์— ๋งž์ถฐ ํ๋ฆ„์ด ์ œํ•œ๋˜๋Š” ํ˜„์ƒ
Where

internal/vault/encryption.go, vault/handler.go

Beginner trap

streaming์€ ์„ฑ๋Šฅ๋งŒ์ด ์•„๋‹ˆ๋ผ failure cleanup๊นŒ์ง€ ๊ฐ™์ด ์„ค๊ณ„ํ•ด์•ผ ํ•œ๋‹ค.

5. BackendCore

Rule-based anomaly scoring

๋จธ์‹ ๋Ÿฌ๋‹์ด ์•„๋‹ˆ๋ผ ์ž„๊ณ„๊ฐ’ rule๋กœ ์œ„ํ—˜ ์ ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๋ถ„์„๊ธฐ๋‹ค.

The honest label is rule-based anomaly scoring, not full ML-based UEBA.

What it does

์•ผ๊ฐ„ ํ™œ๋™, ์ƒˆ IP, ๋Œ€๋Ÿ‰ ๋‹ค์šด๋กœ๋“œ, messenger/process ๊ฐ™์€ factor๋ฅผ ๊ฐ€์ค‘์น˜๋กœ risk score์— ๋ˆ„์ ํ•œ๋‹ค.

Why this stack

์ž‘์€ ํŒ€๊ณผ ์„ค๋ช… ๊ฐ€๋Šฅํ•œ ๋ณด์•ˆ ์šด์˜์—๋Š” ML๋ณด๋‹ค ๊ทœ์น™ ๊ธฐ๋ฐ˜ scoring์ด ํ˜„์‹ค์ ์ด๋‹ค.

Trade-off

์ •๊ตํ•œ UEBA์ฒ˜๋Ÿผ ์‚ฌ์šฉ์ž๋ณ„ ๋ณต์žกํ•œ ํŒจํ„ด์„ ํ•™์Šตํ•˜์ง€ ๋ชปํ•˜๊ณ  false positive/negative๊ฐ€ ์žˆ๋‹ค.

Alternative

Python ML service, statistical anomaly detection, commercial UEBA๊ฐ€ ํ™•์žฅ ๋Œ€์•ˆ์ด๋‹ค.

Terms you must know
  • baseline = ํ‰์†Œ ํ–‰๋™ ๊ธฐ์ค€์„ 
  • risk score = ์œ„ํ—˜ ์š”์†Œ๋ฅผ ๋”ํ•œ ์ ์ˆ˜
  • false positive = ์ •์ƒ์ธ๋ฐ ์œ„ํ—˜์œผ๋กœ ์žก๋Š” ๊ฒฝ์šฐ
Where

internal/ueba, docs/LIMITATIONS.md

Beginner trap

๋””๋ ‰ํ„ฐ๋ฆฌ๋ช…์ด ueba๋ผ๊ณ  ํ•ด์„œ ์—…๊ณ„ ์˜๋ฏธ์˜ UEBA๋ผ๊ณ  ๋งํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.

5. BackendCore

Alert engine

์ €์žฅ๋œ endpoint event๋ฅผ rule๊ณผ ๋น„๊ตํ•ด alert๋ฅผ ๋งŒ๋“œ๋Š” ๊ณ„์ธต์ด๋‹ค.

The alert engine turns raw endpoint telemetry into actionable security signals.

What it does

alert rules์™€ monitoring config๋ฅผ ๋ณด๊ณ  Slack/email notifier๋‚˜ dashboard alert๋กœ ์—ฐ๊ฒฐํ•œ๋‹ค.

Why this stack

์ด๋ฒคํŠธ ์ €์žฅ๋งŒ์œผ๋กœ๋Š” ์šด์˜์ž๊ฐ€ ๋ฐ”๋กœ ๋Œ€์‘ํ•˜๊ธฐ ์–ด๋ ค์šฐ๋ฏ€๋กœ rule engine์ด ํ•„์š”ํ•˜๋‹ค.

Trade-off

inline evaluation์ด๋ผ ์™ธ๋ถ€ webhook ์ง€์—ฐ์ด๋‚˜ ์‹คํŒจ๊ฐ€ request path์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ๋‹ค.

Alternative

๋น„๋™๊ธฐ queue๋ฅผ ๋‘๋ฉด ๋‚ด๊ตฌ์„ฑ๊ณผ ๊ฒฉ๋ฆฌ๊ฐ€ ์ข‹์•„์ง€์ง€๋งŒ ์‹œ์Šคํ…œ์ด ๋ณต์žกํ•ด์ง„๋‹ค.

Terms you must know
  • rule engine = ์กฐ๊ฑด์„ ํ‰๊ฐ€ํ•ด action์„ ๋งŒ๋“œ๋Š” ์ฝ”๋“œ
  • notifier = ์™ธ๋ถ€ ์•Œ๋ฆผ์„ ๋ณด๋‚ด๋Š” ๊ณ„์ธต
  • inline = ์š”์ฒญ ์ฒ˜๋ฆฌ ์ค‘ ๋ฐ”๋กœ ์‹คํ–‰
Where

internal/alert, endpoint handler fan-out

Beginner trap

alert๊ฐ€ ์žˆ๋‹ค๊ณ  incident response process๊ฐ€ ์™„์„ฑ๋œ ๊ฑด ์•„๋‹ˆ๋‹ค.

5. BackendCore

DB-based monitoring config

๊ฐ์‹œํ•  process, extension, path, disguise rule์„ DB์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ๊ตฌ์กฐ๋‹ค.

Moving monitoring rules into the database makes the security policy configurable from the admin UI.

What it does

hardcoded list ๋Œ€์‹  admin UI์—์„œ monitoring ๋Œ€์ƒ๊ณผ rule์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค.

Why this stack

์šด์˜์ž๊ฐ€ ์ œํ’ˆ ์žฌ๋ฐฐํฌ ์—†์ด ๊ฐ์‹œ ๊ธฐ์ค€์„ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

Trade-off

์ž˜๋ชป๋œ config๊ฐ€ ํƒ์ง€ ํ’ˆ์งˆ์„ ๋ง์น  ์ˆ˜ ์žˆ์–ด validation๊ณผ audit๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

Alternative

config file์€ ๋‹จ์ˆœํ•˜์ง€๋งŒ runtime ๋ณ€๊ฒฝ์ด ์–ด๋ ต๊ณ , policy engine์€ ๊ฐ•ํ•˜์ง€๋งŒ ๋ณต์žกํ•˜๋‹ค.

Terms you must know
  • monitoring config = ๋ฌด์—‡์„ ๊ฐ์‹œํ• ์ง€ ์ •ํ•œ ์„ค์ •
  • process group = ๊ฐ์‹œํ•  ์•ฑ ๋ฌถ์Œ
  • extension rule = ํŒŒ์ผ ํ™•์žฅ์ž ๊ธฐ์ค€
Where

internal/monitoring, admin/monitoring routes

Beginner trap

์„ค์ •์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ข‹์€ ํƒ์ง€ ์ •์ฑ…์ด ์ž๋™ ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

5. BackendCore

Hash-based file tracking

์ค‘์š” ํŒŒ์ผ hash๋ฅผ ๋“ฑ๋กํ•˜๊ณ  endpoint event์—์„œ ๊ฐ™์€ hash๋ฅผ ์ฐพ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

Hash-based tracking can identify known sensitive files even if the filename changes.

What it does

SHA256/MD5๊ฐ€ ์ผ์น˜ํ•˜๋ฉด ํŒŒ์ผ ์ด๋ฆ„์ด ๋ฐ”๋€Œ์–ด๋„ ์ถ”์  ๋Œ€์ƒ ํŒŒ์ผ๋กœ ๊ฐ์ง€ํ•œ๋‹ค.

Why this stack

๋‹จ์ˆœ ํŒŒ์ผ๋ช… ๊ธฐ๋ฐ˜๋ณด๋‹ค ์ฆ๊ฑฐ๋ ฅ์ด ๋†’๊ณ  extension disguise ํƒ์ง€์™€ ์—ฐ๊ฒฐ๋œ๋‹ค.

Trade-off

ํŒŒ์ผ ๋‚ด์šฉ์ด ์กฐ๊ธˆ๋งŒ ๋ฐ”๋€Œ๋ฉด hash๊ฐ€ ๋‹ฌ๋ผ์ ธ ๋†“์น  ์ˆ˜ ์žˆ๋‹ค.

Alternative

fuzzy hashing, magic byte ๊ฒ€์‚ฌ, DLP fingerprinting์ด ๋” ์ •๊ตํ•œ ๋Œ€์•ˆ์ด๋‹ค.

Terms you must know
  • SHA256 = ํŒŒ์ผ ๋‚ด์šฉ์„ ๋Œ€ํ‘œํ•˜๋Š” ๊ฐ•ํ•œ hash
  • MD5 = ์˜ค๋ž˜๋์ง€๋งŒ ํ˜ธํ™˜์šฉ์œผ๋กœ ์“ฐ์ด๋Š” hash
  • fuzzy hash = ๋น„์Šทํ•œ ํŒŒ์ผ์„ ์ฐพ๋Š” hash
Where

internal/tracking, endpoint fileTracker

Beginner trap

hash tracking์€ ๋“ฑ๋ก๋œ ํŒŒ์ผ๊ณผ ๋™์ผ/๊ฑฐ์˜ ๋™์ผํ•œ ๊ฒฝ์šฐ์—๋งŒ ๊ฐ•ํ•˜๋‹ค.

6. Data

4
6. DataCore

pgx / pgxpool

Go์—์„œ PostgreSQL์— ์—ฐ๊ฒฐํ•˜๋Š” driver์™€ connection pool์ด๋‹ค.

pgx keeps database access explicit while still giving a proper PostgreSQL connection pool.

What it does

repository๋“ค์ด pgx pool์„ ํ†ตํ•ด SQL query, transaction, batch insert๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

Why this stack

Postgres native ๊ธฐ๋Šฅ๊ณผ ์„ฑ๋Šฅ์„ ์ง์ ‘ ์“ฐ๊ณ  ORM magic ์—†์ด query shape๋ฅผ ํ†ต์ œํ•˜๊ธฐ ์ข‹๋‹ค.

Trade-off

SQL์„ ์ง์ ‘ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๋ฐ˜๋ณต๊ณผ migration/schema drift๋ฅผ ์กฐ์‹ฌํ•ด์•ผ ํ•œ๋‹ค.

Alternative

GORM์€ CRUD๊ฐ€ ๋น ๋ฅด์ง€๋งŒ ๋ณต์žก query์™€ ์„ฑ๋Šฅ์ด ๋ถˆํˆฌ๋ช…ํ•˜๊ณ , database/sql์€ ํ‘œ์ค€์ด์ง€๋งŒ pgx native ๊ธฐ๋Šฅ์ด ์•ฝํ•˜๋‹ค.

Terms you must know
  • driver = DB์™€ ํ†ต์‹ ํ•˜๋Š” library
  • connection pool = DB ์—ฐ๊ฒฐ์„ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๋ฌถ์Œ
  • repository = DB ์ ‘๊ทผ์„ ๋ชจ์•„๋‘” ์ฝ”๋“œ ๊ณ„์ธต
Where

go.mod, internal/*/repository.go

Beginner trap

pgx๋ฅผ ์“ด๋‹ค๊ณ  SQL injection์ด ์ž๋™์œผ๋กœ ๋ง‰ํžˆ๋Š” ๊ฑด ์•„๋‹ˆ๊ณ  parameter binding์„ ์จ์•ผ ํ•œ๋‹ค.

6. DataCore

PostgreSQL 16

์ด๋ฒคํŠธ์™€ ๊ฐ์‚ฌ ๋กœ๊ทธ์˜ ์ค‘์‹ฌ ์ €์žฅ์†Œ๋‹ค.

Postgres is the system of record because DocVault needs constraints, triggers, indexes, and audit integrity in one place.

What it does

users, files, endpoint_events, audit_logs, alerts, baselines, agent_actions๋ฅผ ์ €์žฅํ•œ๋‹ค.

Why this stack

ํ•ด์‹œ ์ฒด์ธ trigger, indexes, tsvector, constraints๊ฐ€ ํ•„์š”ํ•ด์„œ ๋‹จ์ผ Postgres๊ฐ€ ์ดˆ๊ธฐ ๊ทœ๋ชจ์— ๋งž๋‹ค.

Trade-off

๋‹จ์ผ DB๊ฐ€ SPOF์ด๊ณ  30M+ endpoint_events ๊ทœ๋ชจ์—์„œ๋Š” partitioning/retention์ด ํ•„์š”ํ•˜๋‹ค.

Alternative

Kafka/Elasticsearch/Redis๋ฅผ ๋ถ™์ด๋ฉด ํ™•์žฅ์€ ์ข‹์ง€๋งŒ ํ˜„์žฌ 40๋ช… ๊ทœ๋ชจ์—์„œ๋Š” ์šด์˜ ๋ณต์žก๋„๊ฐ€ ๊ณผํ•˜๋‹ค.

Terms you must know
  • RDBMS = table๊ณผ transaction์„ ์ œ๊ณตํ•˜๋Š” DB
  • SPOF = ํ•˜๋‚˜๊ฐ€ ์ฃฝ์œผ๋ฉด ์ „์ฒด๊ฐ€ ๋ฉˆ์ถ”๋Š” ์ง€์ 
  • partitioning = ํฐ table์„ ์‹œ๊ฐ„/๋ฒ”์œ„๋ณ„๋กœ ๋‚˜๋ˆ„๋Š” ์„ค๊ณ„
Where

docker-compose.prod.yml, internal/database/migrations

Beginner trap

Postgres ํ•˜๋‚˜๋กœ ๋ชจ๋“  ๋ฏธ๋ž˜ ๊ทœ๋ชจ๋ฅผ ๋ฒ„ํ‹ด๋‹ค๊ณ  ๋งํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.

6. DataCore

Embedded SQL migrations

DB schema ๋ณ€๊ฒฝ์„ Go binary ์•ˆ์— ๋„ฃ์–ด ์ ์šฉํ•œ๋‹ค.

Embedding migrations lets the same server artifact carry the database schema changes it expects.

What it does

migrate command๊ฐ€ embedded migration SQL์„ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰ํ•ด table/index/trigger๋ฅผ ๋งŒ๋“ ๋‹ค.

Why this stack

๋ฐฐํฌ ํŒŒ์ผ์ด ๋‹จ์ˆœํ•˜๊ณ  ์„œ๋ฒ„์™€ schema version์„ ๊ฐ™์ด ์›€์ง์ด๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

Trade-off

์ž˜๋ชป๋œ migration์€ ์šด์˜ DB์— ์ง์ ‘ ์˜ํ–ฅ์„ ์ฃผ๋ฏ€๋กœ backward-compatible ์ „๋žต์ด ํ•„์š”ํ•˜๋‹ค.

Alternative

Flyway/Liquibase๋Š” ๋” ํ’๋ถ€ํ•œ migration ecosystem์ด๊ณ , ์ˆ˜๋™ SQL์€ ์ถ”์ ์„ฑ์ด ์•ฝํ•˜๋‹ค.

Terms you must know
  • migration = DB ๊ตฌ์กฐ ๋ณ€๊ฒฝ ๊ธฐ๋ก
  • go:embed = ํŒŒ์ผ์„ Go binary ์•ˆ์— ํฌํ•จํ•˜๋Š” ๊ธฐ๋Šฅ
  • schema version = DB ๊ตฌ์กฐ์˜ ์ ์šฉ ์ˆœ์„œ
Where

internal/database/migrations.go, cmd/server/migrate.go

Beginner trap

migration์ด ์žˆ์œผ๋ฉด rollback์ด ์ž๋™์œผ๋กœ ์‰ฌ์šด ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

6. DataCore

Postgres advisory lock

ํ•ด์‹œ ์ฒด์ธ INSERT๋ฅผ ํ…Œ์ด๋ธ”๋ณ„๋กœ ์ง๋ ฌํ™”ํ•˜๋Š” DB lock์ด๋‹ค.

The advisory lock fixes the hash-chain fork race by serializing inserts per audited table.

What it does

๋™์‹œ INSERT๊ฐ€ ๊ฐ™์€ prev_hash๋ฅผ ์ฝ๋Š” race๋ฅผ ๋ง‰๊ธฐ ์œ„ํ•ด trigger์—์„œ pg_advisory_xact_lock์„ ์žก๋Š”๋‹ค.

Why this stack

๋ฌด๊ฒฐ์„ฑ ๊ตฌ์กฐ์—์„œ๋Š” race condition ํ•˜๋‚˜๊ฐ€ ์ „์ฒด ์ฆ๊ฑฐ์„ฑ์„ ํ”๋“ค ์ˆ˜ ์žˆ์–ด์„œ ํ•„์š”ํ•˜๋‹ค.

Trade-off

INSERT ์ฒ˜๋ฆฌ๋Ÿ‰์ด ํ…Œ์ด๋ธ”๋ณ„๋กœ ์ง๋ ฌํ™”๋˜๋ฏ€๋กœ ์ดˆ๋‹น ๋งŽ์€ ์ด๋ฒคํŠธ์—์„œ๋Š” ๋ณ‘๋ชฉ์ด ๋  ์ˆ˜ ์žˆ๋‹ค.

Alternative

SERIALIZABLE transaction, batch chain, external append log ๊ฐ™์€ ๋Œ€์•ˆ์ด ์žˆ๋‹ค.

Terms you must know
  • race condition = ๋™์‹œ์— ์‹คํ–‰๋˜์–ด ๊ฒฐ๊ณผ๊ฐ€ ๊ผฌ์ด๋Š” ๋ฌธ์ œ
  • serialization = ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์”ฉ ์ˆœ์„œ๋Œ€๋กœ ์ฒ˜๋ฆฌ
  • transaction-scoped = transaction ๋๋‚˜๋ฉด ์ž๋™ ํ•ด์ œ
Where

migrations/013_audit_advisory_lock.up.sql

Beginner trap

lock์„ ๋„ฃ์—ˆ๋‹ค๊ณ  ๋ฌดํ•œ ์ฒ˜๋ฆฌ๋Ÿ‰์ด ์œ ์ง€๋˜๋Š” ๊ฑด ์•„๋‹ˆ๋‹ค.

7. AI

2
7. AICore

AI security briefing

์ตœ๊ทผ ์ด๋ฒคํŠธ digest๋ฅผ LLM์—๊ฒŒ ๋ณด๋‚ด ํ•œ๊ตญ์–ด ๋ณด์•ˆ ๋ธŒ๋ฆฌํ•‘์„ ๋ฐ›๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

The AI briefing summarizes factual database digests; it should not invent events beyond the digest.

What it does

DB์—์„œ event counts, notable events, unacknowledged alerts๋ฅผ ์••์ถ•ํ•ด Claude/Gemini์— ์š”์•ฝ์‹œํ‚จ๋‹ค.

Why this stack

๋น„์ „๋ฌธ ๊ด€๋ฆฌ์ž์—๊ฒŒ raw table๋ณด๋‹ค ์งง์€ ์œ„ํ—˜ ์š”์•ฝ์ด ํ•„์š”ํ•˜๋‹ค.

Trade-off

LLM ๋น„์šฉ/์ง€์—ฐ/ํ™˜๊ฐ ์œ„ํ—˜์ด ์žˆ์–ด factual digest์™€ admin-only ๊ฒฝ๊ณ„๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

Alternative

์ˆœ์ˆ˜ rule dashboard๋Š” ๊ฒฐ์ •๋ก ์ ์ด์ง€๋งŒ ์ž์—ฐ์–ด ์„ค๋ช…์ด ์•ฝํ•˜๊ณ , RAG๋Š” ๋ฌธ์„œ Q&A์— ๋” ๋งž๋‹ค.

Terms you must know
  • digest = ์›๋ณธ ๋ฐ์ดํ„ฐ๋ฅผ ์••์ถ•ํ•œ ์š”์•ฝ ์ž…๋ ฅ
  • hallucination = ์—†๋Š” ์ผ์„ ์ง€์–ด๋‚ด๋Š” ๋ชจ๋ธ ์˜ค๋ฅ˜
  • provider = AI API ์ œ๊ณต์ž
Where

internal/insight/summarizer.go

Beginner trap

AI ์š”์•ฝ์„ ๋ณด์•ˆ ํŒ๋‹จ์˜ ๋‹จ์ผ ๊ทผ๊ฑฐ๋กœ ์“ฐ๋ฉด ์•ˆ ๋œ๋‹ค.

7. AICore

Tool-use AI assistant

๊ด€๋ฆฌ์ž๊ฐ€ ์ž์—ฐ์–ด๋กœ live data ์กฐํšŒ์™€ ์ œํ•œ๋œ ํ–‰๋™์„ ์š”์ฒญํ•˜๋Š” AI assistant๋‹ค.

The assistant uses tools over live tables because DocVault's data is structured and action-oriented.

What it does

read tools๋Š” ์ด๋ฒคํŠธ/์‚ฌ์šฉ์ž/๊ฒฝ๋ณด๋ฅผ ์กฐํšŒํ•˜๊ณ  action tools๋Š” create_user, assign_host, acknowledge_alert๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค.

Why this stack

์ •ํ˜• ๋ฐ์ดํ„ฐ๋ผ RAG๋ณด๋‹ค SQL-backed tool-use๊ฐ€ ๋” ์ •ํ™•ํ•œ grounding์„ ์ค€๋‹ค.

Trade-off

tool output์—๋Š” ํŒŒ์ผ๋ช…/์ฐฝ์ œ๋ชฉ ๊ฐ™์€ ๊ณต๊ฒฉ์ž ์˜ํ–ฅ ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด๊ฐ€ prompt injection ์œ„ํ—˜์ด ์žˆ๋‹ค.

Alternative

์ˆ˜๋™ admin UI๋Š” ์•ˆ์ „ํ•˜์ง€๋งŒ ๋А๋ฆฌ๊ณ , RAG chat์€ ๋ฌธ์„œ ๋‹ต๋ณ€์—๋Š” ์ข‹์ง€๋งŒ row-level action์—๋Š” ์•ฝํ•˜๋‹ค.

Terms you must know
  • tool-use = ๋ชจ๋ธ์ด ์ •ํ•ด์ง„ ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ์„ ํƒํ•˜๋Š” ๋ฐฉ์‹
  • grounding = ์‹ค์ œ ๋ฐ์ดํ„ฐ์— ๊ทผ๊ฑฐํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ
  • prompt injection = ๋ฐ์ดํ„ฐ ์† ๋ช…๋ น์œผ๋กœ AI๋ฅผ ์†์ด๋Š” ๊ณต๊ฒฉ
Where

internal/agent/agent.go, internal/agent/actions.go

Beginner trap

AI assistant๊ฐ€ ์žˆ๋‹ค๊ณ  ๋ชจ๋“  ์šด์˜ ๋ณ€๊ฒฝ์„ ์ž๋™ํ™”ํ•ด๋„ ๋œ๋‹ค๋Š” ๋œป์€ ์•„๋‹ˆ๋‹ค.

8. Infra

3
8. InfraCore

Docker

Go server์™€ Postgres ์‹คํ–‰ ํ™˜๊ฒฝ์„ container๋กœ ๋ฌถ๋Š”๋‹ค.

Docker makes the deployment reproducible across a dedicated server and an all-in-one demo machine.

What it does

Dockerfile์€ server binary๋ฅผ ๋งŒ๋“ค๊ณ  compose๋Š” db/migrate/seed/server/caddy๋ฅผ ํ•จ๊ป˜ ์‹คํ–‰ํ•œ๋‹ค.

Why this stack

์นœ๊ตฌ PC all-in-one๊ณผ dedicated VM์„ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์žฌํ˜„ํ•˜๊ธฐ ์ข‹๋‹ค.

Trade-off

Docker Desktop, volume, network, backup ๊ฐ™์€ ์šด์˜ ์ง€์‹์ด ํ•„์š”ํ•˜๋‹ค.

Alternative

์ง์ ‘ ์„ค์น˜๋Š” ๋‹จ์ˆœํ•ด ๋ณด์ด์ง€๋งŒ ํ™˜๊ฒฝ drift๊ฐ€ ํฌ๊ณ , Kubernetes๋Š” 1์ธ ์šด์˜์—๋Š” ๊ณผํ•˜๋‹ค.

Terms you must know
  • container = ๊ฒฉ๋ฆฌ๋œ ์‹คํ–‰ ๋‹จ์œ„
  • image = container๋ฅผ ๋งŒ๋“œ๋Š” ์Šค๋ƒ…์ƒท
  • volume = container ๋ฐ–์— ๋ณด์กด๋˜๋Š” ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ
Where

Dockerfile, docker-compose.prod.yml

Beginner trap

Docker๊ฐ€ backup์ด๋‚˜ security๋ฅผ ์ž๋™์œผ๋กœ ํ•ด์ฃผ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

8. InfraCore

Docker Compose

db, migration, seed, server, caddy๋ฅผ ํ•œ ํŒŒ์ผ์—์„œ ๋„์šฐ๋Š” orchestrator๋‹ค.

Compose is enough for the intended single-host deployment and keeps the operational model explainable.

What it does

depends_on healthcheck๋กœ DB ์ค€๋น„ ํ›„ migration/seed/server ์ˆœ์„œ๊ฐ€ ๋งž๊ฒŒ ์‹คํ–‰๋œ๋‹ค.

Why this stack

์ž‘์€ self-hosted ์ œํ’ˆ์—๋Š” Kubernetes๋ณด๋‹ค ์ดํ•ด์™€ ๋ณต๊ตฌ๊ฐ€ ์‰ฌ์šด compose๊ฐ€ ๋งž๋‹ค.

Trade-off

HA/rolling deploy/autoscaling์€ ์•ฝํ•˜๊ณ  ํ•œ host ์žฅ์• ์— ์ทจ์•ฝํ•˜๋‹ค.

Alternative

ECS/Kubernetes/Nomad๋Š” orchestration์€ ๊ฐ•ํ•˜์ง€๋งŒ ์ดˆ๊ธฐ ์šด์˜ ๋ณต์žก๋„๊ฐ€ ํฌ๋‹ค.

Terms you must know
  • orchestrator = ์—ฌ๋Ÿฌ ์„œ๋น„์Šค๋ฅผ ์ˆœ์„œ/์ƒํƒœ์— ๋งž๊ฒŒ ์‹คํ–‰ํ•˜๋Š” ๋„๊ตฌ
  • healthcheck = ์„œ๋น„์Šค๊ฐ€ ์ค€๋น„๋๋Š”์ง€ ๊ฒ€์‚ฌ
  • one-shot service = ์‹คํ–‰ ํ›„ ์ข…๋ฃŒ๋˜๋Š” ์ž‘์—…
Where

docker-compose.prod.yml

Beginner trap

Compose๋ฅผ ์“ด๋‹ค๊ณ  ๊ณ ๊ฐ€์šฉ์„ฑ ์•„ํ‚คํ…์ฒ˜๊ฐ€ ๋˜๋Š” ๊ฑด ์•„๋‹ˆ๋‹ค.

8. InfraCore

Caddy reverse proxy

HTTPS ์ธ์ฆ์„œ์™€ ์™ธ๋ถ€ ์š”์ฒญ ์ „๋‹ฌ์„ ๋งก๋Š” reverse proxy๋‹ค.

Caddy keeps HTTPS and reverse proxying simple for a self-hosted single-server deployment.

What it does

80/443์„ ๋ฐ›๊ณ  ๋‚ด๋ถ€ server container์˜ :8080์œผ๋กœ proxyํ•œ๋‹ค.

Why this stack

Let's Encrypt ์ž๋™ ์ธ์ฆ์„œ์™€ ๋‹จ์ˆœ Caddyfile์ด self-hosted ๋ฐฐํฌ์— ์ž˜ ๋งž๋‹ค.

Trade-off

๋ณต์žกํ•œ enterprise routing์ด๋‚˜ WAF ๊ธฐ๋Šฅ์€ ๋ณ„๋„ ๊ณ„์ธต์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ๋‹ค.

Alternative

Nginx๋Š” ๋„๋ฆฌ ์“ฐ์ด์ง€๋งŒ cert ์ž๋™ํ™”๊ฐ€ ๋” ์ˆ˜๋™์ด๊ณ , ALB๋Š” managed์ง€๋งŒ cloud ์˜์กด์ด ์ƒ๊ธด๋‹ค.

Terms you must know
  • reverse proxy = ์•ž๋‹จ์—์„œ ์š”์ฒญ์„ ๋ฐ›์•„ ๋‚ด๋ถ€ ์„œ๋น„์Šค๋กœ ๋„˜๊ธฐ๋Š” ์„œ๋ฒ„
  • TLS termination = HTTPS ์•”ํ˜ธํ™” ์ฒ˜๋ฆฌ๋ฅผ proxy์—์„œ ๋๋‚ด๋Š” ๊ฒƒ
  • Caddyfile = Caddy ์„ค์ • ํŒŒ์ผ
Where

deploy/caddy/Caddyfile, docker-compose.prod.yml

Beginner trap

Caddy๊ฐ€ application authentication์„ ๋Œ€์‹ ํ•˜์ง€ ์•Š๋Š”๋‹ค.

9. Security

9
9. SecurityCore

Pre-shared key agent auth

agent๊ฐ€ ์„œ๋ฒ„์— ์ด๋ฒคํŠธ๋ฅผ ๋ณด๋‚ผ ๋•Œ ์“ฐ๋Š” ๊ณต์œ  ๋น„๋ฐ€ํ‚ค๋‹ค.

PSK is an intentionally simple enrollment/auth mechanism, but the honest upgrade path is per-agent mTLS.

What it does

X-Agent-PSK ๋˜๋Š” X-Osquery-PSK header๋ฅผ constant-time compare๋กœ ๊ฒ€์ฆํ•œ๋‹ค.

Why this stack

์ดˆ๊ธฐ ์„ค์น˜์™€ ์ž‘์€ ํŒ€ ์šด์˜์—์„œ๋Š” ๋‹จ์ˆœํ•˜๊ณ  ๋น ๋ฅด๋‹ค.

Trade-off

ํ‚ค๊ฐ€ ์œ ์ถœ๋˜๋ฉด ๋ชจ๋“  agent๊ฐ€ ์˜ํ–ฅ๋ฐ›๊ณ  ๊ฐœ๋ณ„ ์ทจ์†Œ/ํšŒ์ „์ด ์–ด๋ ต๋‹ค.

Alternative

mTLS certificate๋Š” agent๋ณ„ ์‹๋ณ„/์ทจ์†Œ๊ฐ€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ๋ฐœ๊ธ‰/๋ฐฐํฌ/ํšŒ์ „์ด ๋ณต์žกํ•˜๋‹ค.

Terms you must know
  • PSK = ๋ฏธ๋ฆฌ ๋‚˜๋ˆ  ๊ฐ€์ง„ ๋น„๋ฐ€ํ‚ค
  • constant-time compare = timing leak์„ ์ค„์ด๋Š” ๋น„๊ต
  • mTLS = client certificate๋กœ agent๋ฅผ ์ธ์ฆํ•˜๋Š” ๋ฐฉ์‹
Where

internal/endpoint/handler.go, docs/LIMITATIONS.md

Beginner trap

PSK๊ฐ€ ์žˆ์œผ๋‹ˆ endpoint identity๊ฐ€ ์™„๋ฒฝํ•˜๋‹ค๊ณ  ๋งํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.

9. SecurityCore

DB trigger hash chain

๋กœ๊ทธ ํ–‰๋งˆ๋‹ค ์ด์ „ ํ–‰ hash๋ฅผ ์—ฐ๊ฒฐํ•ด ๋ณ€์กฐ๋ฅผ ํƒ์ง€ํ•˜๋Š” ๊ตฌ์กฐ๋‹ค.

The hash chain is an application-level tamper-evidence mechanism, not a legal-grade immutable ledger.

What it does

audit_logs์™€ endpoint_events INSERT trigger๊ฐ€ prev_hash์™€ row_hash๋ฅผ ๊ณ„์‚ฐํ•˜๊ณ  update/delete trigger๊ฐ€ ์ˆ˜์ •์„ ๋ง‰๋Š”๋‹ค.

Why this stack

application code๋ฅผ ์šฐํšŒํ•ด๋„ DB insert ์‹œ ์ž๋™ ์ ์šฉ๋˜๋ฏ€๋กœ audit integrity๊ฐ€ ๊ฐ•ํ•ด์ง„๋‹ค.

Trade-off

DB superuser๊ฐ€ trigger๋ฅผ ๋„๊ณ  ์žฌ๊ณ„์‚ฐํ•˜๋ฉด ์šฐํšŒํ•  ์ˆ˜ ์žˆ์–ด ๋ฒ•์  ์ฆ๊ฑฐ ์ˆ˜์ค€์€ ์•„๋‹ˆ๋‹ค.

Alternative

์™ธ๋ถ€ timestamping, WORM storage, ๋ณ„๋„ hash mirror๊ฐ€ ๋” ๊ฐ•ํ•œ ์ฆ๊ฑฐ์„ฑ์„ ์ค€๋‹ค.

Terms you must know
  • hash chain = ์ด์ „ hash์™€ ๋‚ด ๋ฐ์ดํ„ฐ๋ฅผ ์—ฐ๊ฒฐํ•œ ์‚ฌ์Šฌ
  • trigger = DB ์ด๋ฒคํŠธ์— ์ž๋™ ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜
  • tamper-evident = ๋ณ€์กฐ๋˜๋ฉด ํ”์ ์ด ๋‚จ๋Š” ์„ฑ์งˆ
Where

migrations/008_log_integrity.up.sql, 013_audit_advisory_lock.up.sql

Beginner trap

ํ•ด์‹œ์ฒด์ธ์„ ๋ธ”๋ก์ฒด์ธ์ด๋‚˜ ๋ฒ•์  ๋ถˆ๋ณ€ ์ €์žฅ์†Œ์ฒ˜๋Ÿผ ๊ณผ์žฅํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.

9. SecurityCore

JWT access and refresh tokens

๋กœ๊ทธ์ธ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์„œ๋ช…๋œ token pair๋‹ค.

JWT gives DocVault a simple signed identity mechanism for both web and API flows.

What it does

15๋ถ„ access token, 24์‹œ๊ฐ„ refresh token, pending 2FA token์„ HMAC ์„œ๋ช…์œผ๋กœ ๊ฒ€์ฆํ•œ๋‹ค.

Why this stack

๊ด€๋ฆฌ์ž UI์™€ JSON API๊ฐ€ statelessํ•˜๊ฒŒ identity๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

Trade-off

ํ† ํฐ ํƒˆ์ทจ ์‹œ ๋งŒ๋ฃŒ ์ „๊นŒ์ง€ ์œ„ํ—˜ํ•˜๊ณ  server-side immediate revoke๋Š” ์•ฝํ•˜๋‹ค.

Alternative

์„œ๋ฒ„ ์„ธ์…˜์€ revoke๊ฐ€ ์‰ฝ์ง€๋งŒ ์ €์žฅ์†Œ๊ฐ€ ํ•„์š”ํ•˜๊ณ , opaque token์€ ์กฐํšŒ ๋น„์šฉ์ด ์žˆ๋‹ค.

Terms you must know
  • access token = API ์ ‘๊ทผ์šฉ ์งง์€ ํ† ํฐ
  • refresh token = ์ƒˆ access token์„ ๋ฐ›๋Š” ๊ธด ํ† ํฐ
  • claim = ํ† ํฐ ์•ˆ์˜ ์ •๋ณด
Where

internal/auth/jwt.go

Beginner trap

JWT payload๋Š” ์•”ํ˜ธํ™”๋œ ๋น„๋ฐ€ ๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹ˆ๋‹ค.

9. SecurityCore

TOTP 2FA

์•ฑ์—์„œ ์ƒ์„ฑ๋˜๋Š” 6์ž๋ฆฌ ์ผํšŒ์šฉ ์ฝ”๋“œ๋กœ 2์ฐจ ์ธ์ฆ์„ ํ•œ๋‹ค.

TOTP adds a second authentication factor for admin access without relying on SMS.

What it does

๋น„๋ฐ€๋ฒˆํ˜ธ ํ™•์ธ ํ›„ pending_2fa token์„ ์ฃผ๊ณ  TOTP ๊ฒ€์ฆ์ด ์„ฑ๊ณตํ•ด์•ผ ์ตœ์ข… token์„ ๋ฐœ๊ธ‰ํ•œ๋‹ค.

Why this stack

๊ด€๋ฆฌ์ž ๋ณด์•ˆ ์ œํ’ˆ์—์„œ๋Š” password ํ•˜๋‚˜๋งŒ์œผ๋กœ๋Š” ๋ถ€์กฑํ•˜๋‹ค.

Trade-off

๋ณต๊ตฌ ์ฝ”๋“œ์™€ secret ๋ณด๊ด€, ์‹œ๊ฐ„ drift, ์‚ฌ์šฉ์ž onboarding ๋ถ€๋‹ด์ด ์žˆ๋‹ค.

Alternative

WebAuthn/passkey๋Š” phishing resistance๊ฐ€ ๋” ์ข‹์ง€๋งŒ ๊ตฌํ˜„/์‚ฌ์šฉ์ž ์žฅ๋ฒฝ์ด ๋†’๋‹ค.

Terms you must know
  • TOTP = time-based one-time password
  • HOTP = counter ๊ธฐ๋ฐ˜ one-time password
  • skew = ์‹œ๊ฐ„ ์˜ค์ฐจ ํ—ˆ์šฉ ๋ฒ”์œ„
Where

internal/auth/totp.go, login_2fa templates

Beginner trap

2FA๊ฐ€ ์žˆ๋‹ค๊ณ  ์„ธ์…˜ ํƒˆ์ทจ๋‚˜ recovery code ๋ณด๊ด€ ๋ฌธ์ œ๊ฐ€ ์‚ฌ๋ผ์ง€๋Š” ๊ฑด ์•„๋‹ˆ๋‹ค.

9. SecurityCore

SecretProtector

TOTP secret ๊ฐ™์€ ์ž‘์€ ์ธ์ฆ ๋น„๋ฐ€์„ master key๋กœ ์•”ํ˜ธํ™”ํ•œ๋‹ค.

SecretProtector encrypts new authentication secrets while still allowing legacy values until users rotate them.

What it does

enc:v1 prefix๊ฐ€ ์žˆ๋Š” ๊ฐ’์€ AES-GCM์œผ๋กœ ์—ด๊ณ , legacy plaintext๋Š” rotation ์ „๊นŒ์ง€ ์œ ์ง€ํ•œ๋‹ค.

Why this stack

๊ธฐ์กด ์‚ฌ์šฉ์ž๋ฅผ ๊นจ์ง€ ์•Š์œผ๋ฉด์„œ ์ƒˆ secret์€ ์•”ํ˜ธํ™”ํ•  ์ˆ˜ ์žˆ๋Š” migration-safe ๊ตฌ์กฐ๋‹ค.

Trade-off

legacy plaintext๊ฐ€ ๋‚จ์•„ ์žˆ๊ณ  recovery code ๋ณด๊ด€์€ ๋ณ„๋„ ๊ฐœ์„ ์ด ํ•„์š”ํ•˜๋‹ค.

Alternative

์ „์šฉ KMS๋ฅผ ์“ฐ๋ฉด ํ‚ค ๊ด€๋ฆฌ๊ฐ€ ์ข‹์•„์ง€์ง€๋งŒ self-hosted ๋‹จ์ˆœ์„ฑ์ด ๋–จ์–ด์ง„๋‹ค.

Terms you must know
  • secret = ์ธ์ฆ์— ์“ฐ์ด๋Š” ๋ฏผ๊ฐ๊ฐ’
  • legacy plaintext = ์˜ˆ์ „ ๋ฐฉ์‹์œผ๋กœ ์•”ํ˜ธํ™”๋˜์ง€ ์•Š์€ ๊ฐ’
  • prefix = ์ €์žฅ ํ˜•์‹์„ ๊ตฌ๋ถ„ํ•˜๋Š” ์•ž๋ถ€๋ถ„ ๋ฌธ์ž์—ด
Where

internal/auth/secret.go, docs/DEPLOY.md open items

Beginner trap

์ƒˆ secret ์•”ํ˜ธํ™”์™€ ๊ธฐ์กด secret ์™„์ „ ์ •๋ฆฌ๋Š” ๋‹ค๋ฅธ ์ž‘์—…์ด๋‹ค.

9. SecurityCore

CSRF protection

๋กœ๊ทธ์ธ๋œ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋‹ค๋ฅธ ์‚ฌ์ดํŠธ์— ์†์•„ ์š”์ฒญํ•˜๋Š” ๊ฒƒ์„ ๋ง‰๋Š” ์žฅ์น˜๋‹ค.

CSRF protection is necessary because DocVault has cookie-authenticated admin forms that mutate state.

What it does

๋ณดํ˜ธ๋œ web form POST์—์„œ cookie token๊ณผ submitted token์„ ๋น„๊ตํ•œ๋‹ค.

Why this stack

์„œ๋ฒ„ ๋ Œ๋” form๊ณผ htmx POST๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— CSRF ๋ฐฉ์–ด๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

Trade-off

ํ˜„์žฌ ๊ตฌํ˜„์€ double-submit ํ˜•ํƒœ๋ผ cookie scope์™€ SameSite ์„ค์ •์— ์˜์กดํ•œ๋‹ค.

Alternative

server-side synchronizer token์€ ๋” ๊ฐ•ํ•˜์ง€๋งŒ session storage๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

Terms you must know
  • CSRF = ๋‹ค๋ฅธ ์‚ฌ์ดํŠธ๊ฐ€ ๋„ค ๋กœ๊ทธ์ธ ์ƒํƒœ๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๊ณต๊ฒฉ
  • SameSite = cookie๊ฐ€ cross-site ์š”์ฒญ์— ๋ถ™๋Š” ์กฐ๊ฑด
  • double-submit = cookie token๊ณผ form token์„ ๋น„๊ตํ•˜๋Š” ๋ฐฉ์‹
Where

internal/web/csrf.go

Beginner trap

CSRF token์ด ์žˆ๋‹ค๊ณ  XSS๊ฐ€ ๋ง‰ํžˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

9. SecurityCore

Login rate limiter

๋กœ๊ทธ์ธ ์‹คํŒจ๋ฅผ IP๋ณ„๋กœ ์ œํ•œํ•˜๋Š” in-memory ๋ณดํ˜ธ ์žฅ์น˜๋‹ค.

The login rate limiter is a local defense against repeated password guessing, not a complete abuse platform.

What it does

10๋ถ„ ๋™์•ˆ 5ํšŒ ์‹คํŒจํ•˜๋ฉด 15๋ถ„ lockํ•˜๊ณ  ์„ฑ๊ณตํ•˜๋ฉด record๋ฅผ ์ง€์šด๋‹ค.

Why this stack

admin login brute force๋ฅผ ์ตœ์†Œํ•œ์œผ๋กœ ๋ง‰์•„์•ผ ์ธํ„ฐ๋„ท ๋…ธ์ถœ ์‹œ ๊ธฐ๋ณธ ๋ฐฉ์–ด๊ฐ€ ๋œ๋‹ค.

Trade-off

๋ฉ”๋ชจ๋ฆฌ ๊ธฐ๋ฐ˜์ด๋ผ ์„œ๋ฒ„ ์žฌ์‹œ์ž‘/๋ฉ€ํ‹ฐ ์ธ์Šคํ„ด์Šค์—์„œ๋Š” ์ƒํƒœ๊ฐ€ ์‚ฌ๋ผ์ง€๊ฑฐ๋‚˜ ๋ถ„์‚ฐ๋˜์ง€ ์•Š๋Š”๋‹ค.

Alternative

Redis-backed limiter, reverse proxy/WAF, account-level lockout์ด ํ™•์žฅ ๋Œ€์•ˆ์ด๋‹ค.

Terms you must know
  • brute force = ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋ฐ˜๋ณต ๋Œ€์ž…ํ•˜๋Š” ๊ณต๊ฒฉ
  • lockout = ์ผ์ • ์‹œ๊ฐ„ ์ฐจ๋‹จ
  • X-Forwarded-For = proxy๊ฐ€ ์ „๋‹ฌํ•œ ์›๋ž˜ IP header
Where

internal/web/ratelimit.go

Beginner trap

IP ๊ธฐ๋ฐ˜ ์ œํ•œ๋งŒ์œผ๋กœ credential stuffing์„ ์™„์ „ํžˆ ๋ง‰๋Š”๋‹ค๊ณ  ๋งํ•˜์ง€ ๋ง๋ผ.

9. SecurityCore

Chunked AES-256-GCM

ํŒŒ์ผ์„ 64KiB ๋‹จ์œ„๋กœ ๋‚˜๋ˆ  ์•”ํ˜ธํ™”์™€ ๋ฌด๊ฒฐ์„ฑ ๊ฒ€์ฆ์„ ๊ฐ™์ด ํ•œ๋‹ค.

Chunked AES-GCM is the corrected design because file confidentiality without integrity is not enough for a security product.

What it does

๊ฐ chunk์— GCM tag๊ฐ€ ๋ถ™๊ณ  final flag/chunk index nonce๋กœ truncation/reorder๋ฅผ ํƒ์ง€ํ•œ๋‹ค.

Why this stack

ํฐ ํŒŒ์ผ์„ ๋ฉ”๋ชจ๋ฆฌ์— ์ „๋ถ€ ์˜ฌ๋ฆฌ์ง€ ์•Š๊ณ ๋„ ๋ณ€์กฐ ํƒ์ง€๊ฐ€ ๋˜๋Š” vault storage๊ฐ€ ํ•„์š”ํ–ˆ๋‹ค.

Trade-off

CTR๋ณด๋‹ค ์•ฝ๊ฐ„ ๋ฌด๊ฒ๊ณ  chunk format/version migration์„ ๊ด€๋ฆฌํ•ด์•ผ ํ•œ๋‹ค.

Alternative

CTR+HMAC์€ ์ „์ฒด ํŒŒ์ผ ๊ฒ€์ฆ์ด ํ•„์š”ํ•˜๊ณ , ๋‹จ์ผ GCM์€ ํฐ ํŒŒ์ผ streaming์— ๋ถˆํŽธํ•˜๋‹ค.

Terms you must know
  • AEAD = ์•”ํ˜ธํ™”์™€ ์ธ์ฆ์„ ํ•จ๊ป˜ ์ œ๊ณตํ•˜๋Š” ๋ฐฉ์‹
  • GCM tag = ๋ณ€์กฐ๋ฅผ ๊ฐ์ง€ํ•˜๋Š” ์ธ์ฆ ํƒœ๊ทธ
  • nonce = ๊ฐ™์€ key์—์„œ ์žฌ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ ๋˜๋Š” ๊ฐ’
Where

internal/vault/encryption.go, docs/LIMITATIONS.md

Beginner trap

AES๋ผ๊ณ ๋งŒ ๋งํ•˜๋ฉด ์•ˆ ๋˜๊ณ  mode์™€ integrity๋ฅผ ๊ฐ™์ด ๋งํ•ด์•ผ ํ•œ๋‹ค.

9. SecurityCore

Envelope encryption

ํŒŒ์ผ๋ณ„ key๋กœ ํŒŒ์ผ์„ ์•”ํ˜ธํ™”ํ•˜๊ณ  ๊ทธ key๋ฅผ master key๋กœ ๋ด‰์ธํ•œ๋‹ค.

Envelope encryption separates file data keys from the master key so each file can be protected independently.

What it does

DB์—๋Š” encrypted_key/key_nonce๊ฐ€ ์žˆ๊ณ  disk์—๋Š” encrypted blob์ด ์ €์žฅ๋œ๋‹ค.

Why this stack

ํŒŒ์ผ๋งˆ๋‹ค key๋ฅผ ๋ถ„๋ฆฌํ•˜๊ณ  master key๋งŒ ์•ˆ์ „ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•˜๋Š” ํ‘œ์ค€ KMS-like ํŒจํ„ด์ด๋‹ค.

Trade-off

master key rotation tool์€ ์•„์ง ๋ฏธ๊ตฌํ˜„์ด๋ผ ์šด์˜ ์ ˆ์ฐจ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

Alternative

ํŒŒ์ผ์„ master key ํ•˜๋‚˜๋กœ ์ง์ ‘ ์•”ํ˜ธํ™”ํ•˜๋ฉด ๋‹จ์ˆœํ•˜์ง€๋งŒ ๊ฒฉ๋ฆฌ์™€ rotation์ด ์•ฝํ•˜๋‹ค.

Terms you must know
  • data key = ์‹ค์ œ ํŒŒ์ผ์„ ์•”ํ˜ธํ™”ํ•˜๋Š” key
  • master key = data key๋ฅผ ๋ณดํ˜ธํ•˜๋Š” ์ƒ์œ„ key
  • key rotation = key๋ฅผ ์ƒˆ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ๋Š” ์ž‘์—…
Where

internal/vault/keymanager.go, vault repository/migrations

Beginner trap

๋ด‰ํˆฌ ์•”ํ˜ธํ™”๊ฐ€ ์žˆ๋‹ค๊ณ  master key ์šด์˜ ๋ฌธ์ œ๊ฐ€ ์‚ฌ๋ผ์ง€๋Š” ๊ฑด ์•„๋‹ˆ๋‹ค.

10. Safety

2
10. SafetyCore

Mutating tool confirmation

AI action tool ์‹คํ–‰ ์ „์— ์‚ฌ๋žŒ์˜ ๋ช…์‹œ ํ™•์ธ์„ ์š”๊ตฌํ•˜๋Š” gate๋‹ค.

Mutating AI tools are server-gated behind an explicit human confirmation turn.

What it does

create_user, assign_host, acknowledge_alert ๊ฐ™์€ mutating tools๋Š” assistant๊ฐ€ confirmation prompt๋ฅผ ๋จผ์ € ๋ฐ˜ํ™˜ํ•œ๋‹ค.

Why this stack

๊ฐ์‹œ ๋Œ€์ƒ PC์˜ ํŒŒ์ผ๋ช…/์ฐฝ์ œ๋ชฉ์ด tool output์œผ๋กœ ๋“ค์–ด์™€๋„ ๊ทธ๊ฒƒ์„ ์‹คํ–‰ ์Šน์ธ์œผ๋กœ ์ธ์ •ํ•˜์ง€ ์•Š๊ฒŒ ํ•œ๋‹ค.

Trade-off

ํ™•์ธ ๋ฌธ๊ตฌ UX๊ฐ€ ๋ฒˆ๊ฑฐ๋กญ๊ณ  ์™„์ „ํ•œ policy engine์€ ์•„๋‹ˆ๋‹ค.

Alternative

separate approval queue, signed action intent, role-based policy engine์ด ๋” ๊ฐ•ํ•œ ๋Œ€์•ˆ์ด๋‹ค.

Terms you must know
  • mutating tool = ์‹œ์Šคํ…œ ์ƒํƒœ๋ฅผ ๋ฐ”๊พธ๋Š” ๋„๊ตฌ
  • confirmation turn = ์‹คํ–‰ ์ „ ์‚ฌ์šฉ์ž๊ฐ€ ์Šน์ธํ•˜๋Š” ๋Œ€ํ™” ๋‹จ๊ณ„
  • untrusted output = ๊ณต๊ฒฉ์ž๊ฐ€ ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ
Where

internal/agent/agent.go hasActionConfirmation/historyHasPendingConfirmation

Beginner trap

LLM์ด ์กฐ์‹ฌํ•˜๊ฒ ๋‹ค๊ณ  ๋งํ•˜๋Š” ๊ฒƒ๊ณผ ์„œ๋ฒ„๊ฐ€ ์‹คํ–‰์„ ๋ง‰๋Š” ๊ฒƒ์€ ๋‹ค๋ฅด๋‹ค.

10. SafetyCore

Agent action rollback

AI๊ฐ€ ์ˆ˜ํ–‰ํ•œ ๋ณ€๊ฒฝ์„ ๋˜๋Œ๋ฆด ์ˆ˜ ์žˆ๊ฒŒ action ๊ธฐ๋ก์„ ๋‚จ๊ธฐ๋Š” ๊ตฌ์กฐ๋‹ค.

Rollback makes AI-assisted administration less risky by recording enough previous state to undo supported actions.

What it does

agent_actions table์— action_type, target_id, prev_state, performed_by๋ฅผ ์ €์žฅํ•˜๊ณ  rollback handler๊ฐ€ ๋ณต๊ตฌํ•œ๋‹ค.

Why this stack

AI action์˜ blast radius๋ฅผ ์ค„์ด๋ ค๋ฉด ์‹คํ–‰ ๊ธฐ๋ก๊ณผ inverse operation์ด ํ•„์š”ํ•˜๋‹ค.

Trade-off

๋ชจ๋“  ์™ธ๋ถ€ ๋ถ€์ž‘์šฉ์„ ์™„๋ฒฝํžˆ ๋˜๋Œ๋ฆด ์ˆ˜๋Š” ์—†๊ณ  DB ์ƒํƒœ ๋ณต๊ตฌ ์ค‘์‹ฌ์ด๋‹ค.

Alternative

event sourcing์€ ๋” ์ฒด๊ณ„์ ์ด์ง€๋งŒ ๊ตฌํ˜„๋Ÿ‰์ด ํฌ๊ณ , manual undo๋Š” ์šด์˜ ๋ถ€๋‹ด์ด ํฌ๋‹ค.

Terms you must know
  • rollback = ์ด์ „ ์ƒํƒœ๋กœ ๋˜๋Œ๋ฆผ
  • prev_state = ๋ณ€๊ฒฝ ์ „ ์ƒํƒœ
  • blast radius = ์‹คํŒจ/์˜ค์ž‘๋™์ด ํผ์ง€๋Š” ๋ฒ”์œ„
Where

internal/agent/actions.go, migration 015

Beginner trap

rollback์ด ์žˆ๋‹ค๊ณ  ์œ„ํ—˜ํ•œ action์„ ๋งˆ์Œ๋Œ€๋กœ ์‹คํ–‰ํ•ด๋„ ๋˜๋Š” ๊ฑด ์•„๋‹ˆ๋‹ค.

11. Testing

1
11. TestingCore

Go tests, vet, Windows CI

Go package test์™€ ์ •์  ๊ฒ€์‚ฌ, Windows agent ๊ฒ€์ฆ์„ ๋ฌถ์€ ๊ฒ€์ฆ ์ฒด๊ณ„๋‹ค.

The test suite covers core packages, but the honest gap is load testing and real osquery end-to-end verification.

What it does

Makefile test-all์ด build/vet/internal package tests๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ๋Œ๋ฆฌ๊ณ  Windows ๊ด€๋ จ CI๊ฐ€ agent onboarding์„ ๊ฒ€์ฆํ•œ๋‹ค.

Why this stack

๋ณด์•ˆ ์ œํ’ˆ์€ ์•”ํ˜ธํ™”, auth, endpoint parsing, audit middleware๋ฅผ ์ž๋™ ํ…Œ์ŠคํŠธ๋กœ ์ง€์ผœ์•ผ ํ•œ๋‹ค.

Trade-off

๋ถ€ํ•˜ ํ…Œ์ŠคํŠธ์™€ ์‹ค์ œ osquery daemon end-to-end ๊ฒ€์ฆ์€ ์•„์ง ํ•œ๊ณ„๋กœ ๋‚จ์•„ ์žˆ๋‹ค.

Alternative

Playwright/e2e, load test, real Windows hardware smoke test๊ฐ€ ๋ณด์™„์ฑ…์ด๋‹ค.

Terms you must know
  • go test = Go ํ…Œ์ŠคํŠธ ์‹คํ–‰
  • go vet = ์˜์‹ฌ์Šค๋Ÿฌ์šด Go ์ฝ”๋“œ ์ •์  ๊ฒ€์‚ฌ
  • CI = ์ฝ”๋“œ ๋ณ€๊ฒฝ๋งˆ๋‹ค ์ž๋™ ๊ฒ€์ฆ
Where

Makefile, internal/*/*_test.go, docs/WINDOWS_VM_TEST.md

Beginner trap

ํ…Œ์ŠคํŠธ ํ†ต๊ณผ๋ฅผ ์šด์˜ ์„ฑ๋Šฅ ๊ฒ€์ฆ์œผ๋กœ ์ฐฉ๊ฐํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.

12. Ops

6
12. OpsCore

Agent heartbeat and self-test

agent๊ฐ€ ์‚ด์•„์žˆ๋Š”์ง€์™€ clipboard ์บก์ฒ˜ ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋ฅผ ์•Œ๋ ค์ฃผ๋Š” ์‹ ํ˜ธ๋‹ค.

Heartbeat-based liveness prevents idle machines from looking dead just because no clipboard event occurred.

What it does

heartbeat๋Š” last_checkin์„ ๊ฐฑ์‹ ํ•˜๊ณ  self-test๋Š” interactive mode์™€ clipboard availability๋ฅผ ๊ธฐ๋กํ•œ๋‹ค.

Why this stack

ํด๋ฆฝ๋ณด๋“œ ๋ณ€ํ™”๊ฐ€ ์—†์–ด๋„ PC๊ฐ€ ๋ณด๊ณ  ์ค‘์ธ์ง€ ๊ด€๋ฆฌ์ž์—๊ฒŒ ๋ณด์—ฌ์ค˜์•ผ ํ•œ๋‹ค.

Trade-off

heartbeat๋Š” agent๊ฐ€ ๋–  ์žˆ๋‹ค๋Š” ์ฆ๊ฑฐ์ด์ง€ ์‹ค์ œ ํƒ์ง€ ํ’ˆ์งˆ ์ „์ฒด๋ฅผ ๋ณด์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค.

Alternative

์ด๋ฒคํŠธ timestamp๋งŒ์œผ๋กœ liveness๋ฅผ ํŒ๋‹จํ•˜๋ฉด idle PC๊ฐ€ offline์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค.

Terms you must know
  • liveness = ์‚ด์•„์žˆ๋Š”์ง€ ์ƒํƒœ
  • self-test = agent๊ฐ€ ์ž๊ธฐ ๊ธฐ๋Šฅ์„ ๊ฒ€์‚ฌํ•ด ๋ณด๊ณ 
  • last_checkin = ๋งˆ์ง€๋ง‰ ๋ณด๊ณ  ์‹œ๊ฐ
Where

ReceiveHeartbeat, ReceiveSelfTest, endpoint_agents

Beginner trap

heartbeat๊ฐ€ ์žˆ๋‹ค๊ณ  ๋ชจ๋“  event๊ฐ€ ๋น ์ง์—†์ด ์ˆ˜์ง‘๋๋‹ค๊ณ  ๋งํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.

12. OpsCore

pg_dump and vault backup

Postgres์™€ vault blob์„ ๋ณต๊ตฌ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋ณด๊ด€ํ•˜๋Š” ์šด์˜ ์ ˆ์ฐจ๋‹ค.

For a single-box product, backup and restore discipline is the real reliability story.

What it does

deploy/backup/backup.sh์™€ rsync ๊ธฐ๋ฐ˜์œผ๋กœ DB dump์™€ encrypted files๋ฅผ ์™ธ๋ถ€๋กœ ์˜ฎ๊ธฐ๋Š” ๊ตฌ์ƒ์ด๋‹ค.

Why this stack

๋‹จ์ผ ์„œ๋ฒ„ ์ œํ’ˆ์—์„œ๋Š” backup/restore๊ฐ€ HA๋ณด๋‹ค ๋จผ์ €์ธ ์ƒ์กด ์กฐ๊ฑด์ด๋‹ค.

Trade-off

๋ฐฑ์—… ์•”ํ˜ธํ™”, off-host storage, restore drill์ด ์—†์œผ๋ฉด ์ ˆ๋ฐ˜์งœ๋ฆฌ๋‹ค.

Alternative

managed RDS snapshot/S3 lifecycle์€ ๊ฐ•ํ•˜์ง€๋งŒ self-hosted ๋‹จ์ˆœ์„ฑ์ด ์ค„์–ด๋“ ๋‹ค.

Terms you must know
  • backup = ๋ณต๊ตฌ์šฉ ์‚ฌ๋ณธ
  • restore drill = ์‹ค์ œ ๋ณต๊ตฌ ์—ฐ์Šต
  • off-host = ๊ฐ™์€ ์„œ๋ฒ„๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ์œ„์น˜
Where

deploy/backup/backup.sh, docs/LIMITATIONS.md

Beginner trap

๋ฐฑ์—… ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ๊ณผ ๋ณต๊ตฌ๊ฐ€ ๊ฒ€์ฆ๋๋‹ค๋Š” ๊ฒƒ์€ ๋‹ค๋ฅด๋‹ค.

12. OpsCore

slog JSON logging

Go ํ‘œ์ค€ structured logger๋กœ ์„œ๋ฒ„ ์ด๋ฒคํŠธ๋ฅผ ๋‚จ๊ธด๋‹ค.

slog gives a structured log trail, but DocVault still lacks full metrics and tracing.

What it does

startup, agent enrollment, endpoint processing, AI/tool errors๋ฅผ key-value log๋กœ ์ถœ๋ ฅํ•œ๋‹ค.

Why this stack

container stdout๊ณผ ์ž˜ ๋งž๊ณ  ๋ฌธ์ œ ์›์ธ ์ถ”์ ์— ํ•„์š”ํ•œ context๋ฅผ ๋ถ™์ด๊ธฐ ์‰ฝ๋‹ค.

Trade-off

Prometheus/OpenTelemetry ๊ฐ™์€ metric/trace๋Š” ์•„์ง ์—†์–ด์„œ ์šด์˜ ๊ด€์ธก์„ฑ์€ ์•ฝํ•˜๋‹ค.

Alternative

zap/zerolog๋Š” ๋” ๋น ๋ฅด๊ณ , OpenTelemetry๋Š” trace/metrics correlation์— ๊ฐ•ํ•˜๋‹ค.

Terms you must know
  • structured log = key-value ํ˜•ํƒœ์˜ ๋กœ๊ทธ
  • stdout = container๊ฐ€ ๋‚ด๋ณด๋‚ด๋Š” ๊ธฐ๋ณธ ์ถœ๋ ฅ
  • observability = ์‹œ์Šคํ…œ ์ƒํƒœ๋ฅผ ๋ฐ–์—์„œ ์ดํ•ดํ•˜๋Š” ๋Šฅ๋ ฅ
Where

cmd/server/main.go, docs/LIMITATIONS.md

Beginner trap

๋กœ๊ทธ๊ฐ€ ์žˆ๋‹ค๊ณ  p95/p99๋‚˜ alerting์ด ์ค€๋น„๋œ ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

12. OpsCore

Health endpoint

์„œ๋ฒ„๊ฐ€ ์‚ด์•„์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฐ„๋‹จํ•œ HTTP endpoint๋‹ค.

The health endpoint is a minimal liveness check, not a complete production readiness probe.

What it does

/health๊ฐ€ JSON ok๋ฅผ ๋ฐ˜ํ™˜ํ•ด reverse proxy๋‚˜ smoke test๊ฐ€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

Why this stack

๋ฐฐํฌ/์šด์˜์—์„œ ์ตœ์†Œํ•œ process liveness๋ฅผ ํ™•์ธํ•˜๋Š” ๊ธฐ์ค€์ ์ด๋‹ค.

Trade-off

DB ์—ฐ๊ฒฐ, migration ์ƒํƒœ, queue ์ƒํƒœ๊นŒ์ง€ ๊นŠ๊ฒŒ ๊ฒ€์ฆํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค.

Alternative

readiness/liveness๋ฅผ ๋‚˜๋ˆ„๊ณ  DB ping/critical dependency check๋ฅผ ๋„ฃ๋Š” ๊ฒƒ์ด ๋” ์ข‹๋‹ค.

Terms you must know
  • health check = ์„œ๋น„์Šค ์ƒํƒœ ํ™•์ธ ์š”์ฒญ
  • liveness = ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‚ด์•„์žˆ๋Š”์ง€
  • readiness = ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ค€๋น„๊ฐ€ ๋๋Š”์ง€
Where

internal/web/router.go /health

Beginner trap

health 200๋งŒ ๋ณด๊ณ  ์ „์ฒด ๊ธฐ๋Šฅ์ด ์ •์ƒ์ด๋ผ๊ณ  ๋งํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.

12. OpsCore

Windows code signing

Windows agent ์‹คํ–‰ํŒŒ์ผ์— ์‹ ๋ขฐ ๊ฐ€๋Šฅํ•œ ๋””์ง€ํ„ธ ์„œ๋ช…์„ ๋ถ™์ด๋Š” ๋ฐฐํฌ ๋‹จ๊ณ„๋‹ค.

Code signing is a shipping problem, not a coding problem: unsigned agents create user trust and install friction.

What it does

make sign-windows๋Š” osslsigncode์™€ ์œ ๋ฃŒ Authenticode cert๋กœ agent binary๋ฅผ ์„œ๋ช…ํ•˜๋„๋ก ์ค€๋น„ํ•œ๋‹ค.

Why this stack

SmartScreen friction์„ ์ค„์ด๊ณ  ๋น„์ „๋ฌธ ์‚ฌ์šฉ์ž ์„ค์น˜ ์„ฑ๊ณต๋ฅ ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•˜๋‹ค.

Trade-off

์ง„์งœ ์‹ ๋ขฐ ์ธ์ฆ์„œ๋Š” ๋น„์šฉ๊ณผ ์‹ ์› ๊ฒ€์ฆ์ด ํ•„์š”ํ•˜๋ฉฐ self-signed๋กœ ํ•ด๊ฒฐ๋˜์ง€ ์•Š๋Š”๋‹ค.

Alternative

์›๊ฒฉ ์„ค์น˜ ์ง€์›์€ ๋น ๋ฅด์ง€๋งŒ ํ™•์žฅ์„ฑ์ด ๋‚ฎ๊ณ , Microsoft Store/MDM ๋ฐฐํฌ๋Š” ์‹ ๋ขฐ์„ฑ์€ ๋†’์ง€๋งŒ ์ ˆ์ฐจ๊ฐ€ ๋ฌด๊ฒ๋‹ค.

Terms you must know
  • Authenticode = Windows ์‹คํ–‰ํŒŒ์ผ ์„œ๋ช… ๋ฐฉ์‹
  • SmartScreen = Windows ๋‹ค์šด๋กœ๋“œ ์‹คํ–‰ ๊ฒฝ๊ณ 
  • timestamp server = ์„œ๋ช… ์‹œ์ ์„ ์ฆ๋ช…ํ•˜๋Š” ์„œ๋ฒ„
Where

Makefile sign-windows, docs/CODE_SIGNING.md

Beginner trap

์ž์ฒด ์„œ๋ช…์œผ๋กœ SmartScreen ๋ฌธ์ œ๊ฐ€ ์™„์ „ํžˆ ํ•ด๊ฒฐ๋œ๋‹ค๊ณ  ๋งํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.

12. OpsCore

Portfolio demo isolation

์‹ค์ œ ๊ณ ๊ฐ/์นœ๊ตฌ DB์™€ ๋ถ„๋ฆฌ๋œ demo stack์ด๋‹ค.

The demo stack is intentionally isolated so portfolio access never touches the real product database.

What it does

docker-compose.demo.yml์€ ๋ณ„๋„ project/volume/seed/demo login์„ ์‚ฌ์šฉํ•ด public portfolio demo๋ฅผ ๋งŒ๋“ ๋‹ค.

Why this stack

ํฌํŠธํด๋ฆฌ์˜ค ๊ฒ€์ฆ์„ ์œ„ํ•ด ์‹ค์ œ ๋ฐ์ดํ„ฐ์™€ demo ๋ฐ์ดํ„ฐ๋ฅผ ์ ˆ๋Œ€ ์„ž์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.

Trade-off

demo convenience๊ฐ€ product instance์— ์ผœ์ง€๋ฉด ๋ณด์•ˆ ์‚ฌ๊ณ ๊ฐ€ ๋œ๋‹ค.

Alternative

snapshot anonymization์ด๋‚˜ staging environment๋„ ๋Œ€์•ˆ์ด์ง€๋งŒ ๊ฒฉ๋ฆฌ ์›์น™์€ ๊ฐ™์•„์•ผ ํ•œ๋‹ค.

Terms you must know
  • demo seed = ์ƒ˜ํ”Œ ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋™ ์ƒ์„ฑ
  • isolation = ์„œ๋กœ ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๊ฒŒ ๋ถ„๋ฆฌ
  • volume = Docker๊ฐ€ ๋ณด์กดํ•˜๋Š” ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ
Where

docker-compose.demo.yml, docs/DEPLOY.md, content logs

Beginner trap

demo login ๊ธฐ๋Šฅ์„ production์— ์ผœ๋‘๋ฉด ์•ˆ ๋œ๋‹ค.

Start from zero path

์ด ์ˆœ์„œ๋Œ€๋กœ ๋งํ•˜๋ฉด product scope์—์„œ ์šด์˜ ํ•œ๊ณ„๊นŒ์ง€ ๋Š๊ธฐ์ง€ ์•Š๋Š”๋‹ค.

12
steps
1

Say what it is not

DRM/EDR/UEBA๊ฐ€ ์•„๋‹ˆ๋ผ๋Š” ์„ ์„ ๊ธ‹๋Š”๋‹ค.

DocVault๋Š” ํŒŒ์ผ ์œ ์ถœ์„ ๋ง‰๋Š” DRM์ด ์•„๋‹ˆ๋ผ ์ง์› PC ํ™œ๋™์„ ์ˆ˜์ง‘ํ•ด ์‚ฌํ›„ ํƒ์ง€์™€ ๊ฐ์‚ฌ๋ฅผ ๋•๋Š” ๋„๊ตฌ๋‹ค.

DocVault is a detection and audit tool, not a DRM or full EDR replacement.

detectionauditsmall-team

Code focus: README + LIMITATIONS ๋จผ์ € ์ฝ๊ธฐ

2

Explain the topology

PC agent -> Go server -> Postgres -> web UI ํ๋ฆ„์„ ๋งํ•œ๋‹ค.

์ง์› PC์˜ osquery์™€ clipboard agent๊ฐ€ HTTPS๋กœ ์ด๋ฒคํŠธ๋ฅผ ๋ณด๋‚ด๊ณ  ์„œ๋ฒ„๊ฐ€ ์ €์žฅ/๋ถ„์„/ํ‘œ์‹œํ•œ๋‹ค.

Endpoint agents send activity to a Go server, which stores it in Postgres and exposes it through an admin console.

osqueryclipboard agentPostgres

Code focus: docs/ARCHITECTURE topology

3

Defend Go

Go ์„ ํƒ ์ด์œ ๋ฅผ agent ๋ฐฐํฌ ์ค‘์‹ฌ์œผ๋กœ ๋งํ•œ๋‹ค.

Go๋ฅผ ์“ด ํ•ต์‹ฌ ์ด์œ ๋Š” ์„œ๋ฒ„๋ณด๋‹ค endpoint agent ๋ฐฐํฌ๋‹ค. Windows/macOS ๋‹จ์ผ ๋ฐ”์ด๋„ˆ๋ฆฌ๊ฐ€ ์ค‘์š”ํ–ˆ๋‹ค.

The main reason for Go was endpoint deployment: one static binary for the server and cross-platform agents.

Gostatic binarycross-platform

Code focus: go.mod, Makefile GOOS/GOARCH

4

Walk the web boundary

chi route group๊ณผ middleware ๊ฒฝ๊ณ„๋ฅผ ๋งํ•œ๋‹ค.

public, agent, protected API, protected web route๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ middleware ๊ฒฝ๊ณ„๋ฅผ ๊ฐ€์ง„๋‹ค.

The router separates public, agent, API, and web routes with different authentication and audit boundaries.

chiJWTaudit middlewareCSRF

Code focus: internal/web/router.go

5

Explain endpoint ingestion

clipboard์™€ osquery๋ฅผ ๊ตฌ๋ถ„ํ•œ๋‹ค.

osquery์™€ clipboard event๋Š” ๋“ค์–ด์˜ค๋Š” ํ˜•์‹์€ ๋‹ค๋ฅด์ง€๋งŒ endpoint_events schema๋กœ normalize๋œ๋‹ค.

Different endpoint payloads are normalized into one endpoint_events schema for timeline, alerts, and analysis.

PSKnormalizeendpoint_events

Code focus: internal/endpoint/handler.go

6

Explain hash-chain integrity

๋ฌด๊ฒฐ์„ฑ ๊ตฌ์กฐ์™€ ํ•œ๊ณ„๋ฅผ ๊ฐ™์ด ๋งํ•œ๋‹ค.

DB trigger๊ฐ€ prev_hash/row_hash๋ฅผ ๊ณ„์‚ฐํ•˜๊ณ  advisory lock์œผ๋กœ ๋™์‹œ์„ฑ ๋ถ„๊ธฐ๋ฅผ ๋ง‰์ง€๋งŒ DB superuser ์šฐํšŒ๋Š” ๊ฐ€๋Šฅํ•˜๋‹ค.

Database triggers make logs tamper-evident, while advisory locks prevent hash-chain fork races.

triggerhash chainadvisory lock

Code focus: migrations 008 and 013

7

Explain encrypted vault

envelope encryption๊ณผ chunked GCM์„ ๋งํ•œ๋‹ค.

ํŒŒ์ผ๋ณ„ key๋กœ ๋ณธ๋ฌธ์„ chunked AES-GCM ์•”ํ˜ธํ™”ํ•˜๊ณ  ๊ทธ key๋ฅผ master key๋กœ ๋ด‰์ธํ•œ๋‹ค.

The vault uses per-file keys sealed by a master key, and streams file contents through chunked AES-GCM.

file keymaster keyGCMstreaming

Code focus: internal/vault/encryption.go

8

Explain rule-based detection

UEBA ๊ณผ์žฅ์„ ํ”ผํ•œ๋‹ค.

์ด๊ฑด ML UEBA๊ฐ€ ์•„๋‹ˆ๋ผ 30์ผ baseline๊ณผ ์ž„๊ณ„๊ฐ’ rule๋กœ ์œ„ํ—˜ ์ ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๊ตฌ์กฐ๋‹ค.

The honest label is rule-based anomaly scoring, not machine-learning UEBA.

baselinerisk scorealert

Code focus: internal/ueba and internal/alert

9

Explain AI as helper

AI๊ฐ€ ํ•ต์‹ฌ ์ˆ˜์ง‘๊ธฐ๊ฐ€ ์•„๋‹ˆ๋ผ ์šด์˜ ๋ณด์กฐ์ž„์„ ๋งํ•œ๋‹ค.

AI๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” ํ•ต์‹ฌ์ด ์•„๋‹ˆ๋ผ ์š”์•ฝ๊ณผ ์ œํ•œ๋œ admin action์„ ๋•๋Š” ๋ณด์กฐ ๊ณ„์ธต์ด๋‹ค.

AI is an operations helper on top of the security system, not the core ingestion engine.

AI briefingtool-useconfirmation

Code focus: internal/insight and internal/agent

10

Explain deployment

Compose single host์™€ Caddy๋ฅผ ๋งํ•œ๋‹ค.

Compose๊ฐ€ db, migrate, seed, server, Caddy๋ฅผ ํ•œ host์—์„œ ๋„์šฐ๊ณ  Caddy๊ฐ€ HTTPS๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.

The deployment is a single-host Compose stack with Caddy in front of the Go server.

Docker ComposeCaddyvolumes

Code focus: docker-compose.prod.yml

11

Attack the limits

ํ•œ๊ณ„๋ฅผ ๋จผ์ € ๋งํ•ด ์‹ ๋ขฐ๋ฅผ ๋งŒ๋“ ๋‹ค.

ํ•œ๊ณ„๋Š” ๋ช…ํ™•ํ•˜๋‹ค. HA ์—†์Œ, PSK ๋‹จ๋…, ์ปค๋„ ๊ฐ€์‹œ์„ฑ ์—†์Œ, ๋ถ€ํ•˜ํ…Œ์ŠคํŠธ ๋ฏธ์‹ค์‹œ๋‹ค.

The key limits are no HA, PSK-based agent auth, no kernel visibility, and no load-test numbers.

no HAPSKno load testno kernel

Code focus: docs/LIMITATIONS.md

12

Give the 60-second interview answer

์ „์ฒด๋ฅผ ํ•œ ๋ฌธ๋‹จ์œผ๋กœ ๋งํ•œ๋‹ค.

DocVault๋Š” endpoint event collection, tamper-evident audit, encrypted vault, rule-based alerts๋ฅผ ํ•œ Go/Postgres self-hosted stack์œผ๋กœ ๋ฌถ์€ ์ œํ’ˆ์ด๋‹ค.

DocVault combines endpoint collection, tamper-evident audit logs, encrypted file storage, and rule-based alerts in a self-hosted Go/Postgres stack.

topologyintegrityencryptionlimits

Code focus: README 5-minute script + actual source

Architecture layers

๊ฐ layer๋Š” โ€œ์—ญํ• , ์™œ ์ด ๊ธฐ์ˆ , ์–ด๋”” ์ฝ”๋“œโ€๊นŒ์ง€ ๊ฐ™์ด ๋ด๋ผ.

1

Admin console

Admins inspect endpoint events, audit logs, files, alerts, agents, monitoring config, and AI summaries.

๊ด€๋ฆฌ์ž๊ฐ€ ๋ณด๋Š” ํ™”๋ฉด์ด๋‹ค. ์ง์›๋ณ„ ํ™œ๋™, ํŒŒ์ผ, ๊ฒฝ๋ณด, ์—์ด์ „ํŠธ ์ƒํƒœ, ์„ค์น˜ ๋งํฌ, AI ๋ธŒ๋ฆฌํ•‘์„ ํ•œ ๊ณณ์—์„œ ๋ณธ๋‹ค.

Why: ๊ด€๋ฆฌ์ž ๋„๊ตฌ๋ผ ๋ณต์žกํ•œ SPA๋ณด๋‹ค htmx + Go template๋กœ ์„œ๋ฒ„ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์ด ๋‹จ์ˆœํ•˜๊ณ  ๋ฐฐํฌ๊ฐ€ ์‰ฝ๋‹ค.

htmxGo templatesSSECSRF

internal/web

2

Go HTTP server

The single backend process serves web pages, APIs, agent receivers, background schedulers, and AI endpoints.

์„œ๋ฒ„ ํ•œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์›น UI, API, agent ์ด๋ฒคํŠธ ์ˆ˜์‹ , baseline ์žฌ๊ณ„์‚ฐ, AI endpoint๊นŒ์ง€ ์ฑ…์ž„์ง„๋‹ค.

Why: ์ž‘์€ self-hosted ์ œํ’ˆ์€ ์„œ๋น„์Šค ๋ถ„์‚ฐ๋ณด๋‹ค ๋‹จ์ผ Go binary๊ฐ€ ์„ค์น˜์™€ ์šด์˜์„ ๋‹จ์ˆœํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค.

cmd/servernet/httpchislog

cmd/server/main.go

3

Middleware chain

Authentication, audit logging, CSRF, role checks, rate limiting, and recovery are enforced around handlers.

์š”์ฒญ์ด handler์— ๋‹ฟ๊ธฐ ์ „ํ›„๋กœ ์ธ์ฆ, ๊ฐ์‚ฌ, CSRF, ๊ด€๋ฆฌ์ž ๊ถŒํ•œ ๊ฐ™์€ ๊ณตํ†ต ๊ฒ€๋ฌธ์†Œ๋ฅผ ํ†ต๊ณผํ•œ๋‹ค.

Why: ๋ณด์•ˆ/๊ฐ์‚ฌ๋Š” ๋ชจ๋“  route์— ๋ฐ˜๋ณต๋˜๋ฏ€๋กœ handler๋งˆ๋‹ค ํฉ๋ฟŒ๋ฆฌ๋ฉด ๋ˆ„๋ฝ๋œ๋‹ค. middleware๊ฐ€ ๊ณตํ†ต ๊ฒฝ๊ณ„๋‹ค.

JWTaudit middlewareCSRFRequireRole

internal/web/router.go

4

PostgreSQL core

Stores users, files, endpoint events, audit logs, alert state, baselines, install tokens, and agent actions.

์ œํ’ˆ์˜ ์‚ฌ์‹ค์„ ์ €์žฅํ•˜๋Š” ์ค‘์‹ฌ์ด๋‹ค. endpoint ์ด๋ฒคํŠธ, ๊ฐ์‚ฌ ๋กœ๊ทธ, ํŒŒ์ผ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ, ๊ฒฝ๋ณด, AI action ๊ธฐ๋ก์ด ๋“ค์–ด๊ฐ„๋‹ค.

Why: ํŠธ๋ฆฌ๊ฑฐ, transaction, index, constraint๊ฐ€ ํ•„์š”ํ•ด์„œ ๋‹จ์ผ Postgres๊ฐ€ ์ดˆ๊ธฐ ๊ทœ๋ชจ์— ๋งž๋‹ค.

pgxpoolmigrationstriggersindexes

internal/database/migrations

5

Endpoint collection layer

osquery and the custom clipboard agent collect host activity and send it to the server.

์ง์› PC์— ์žˆ๋Š” ์ˆ˜์ง‘ ๊ณ„์ธต์ด๋‹ค. ํŒŒ์ผ/USB/process๋Š” osquery, clipboard๋Š” ์ž์ฒด Go agent๊ฐ€ ๋งก๋Š”๋‹ค.

Why: ๊ฒ€์ฆ๋œ osquery๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๊ณ , osquery๊ฐ€ ์•ฝํ•œ clipboard๋งŒ ์ง์ ‘ ๋งŒ๋“ ๋‹ค.

osqueryclipboard agentheartbeatself-test

cmd/clipagent, deploy/osquery, internal/endpoint

6

Event normalization

Raw osquery and clipboard payloads are converted into the common endpoint_events schema.

์„œ๋กœ ๋‹ค๋ฅธ agent payload๋ฅผ ํ•˜๋‚˜์˜ ์ด๋ฒคํŠธ ํ…Œ์ด๋ธ” ๋ชจ์–‘์œผ๋กœ ๋งž์ถ˜๋‹ค.

Why: ํ†ตํ•ฉ timeline, alert, AI assistant, dashboard๊ฐ€ ๊ฐ™์€ schema๋ฅผ ์ฝ์–ด์•ผ ํ•œ๋‹ค.

NormalizeOsqueryEventsNormalizeClipboardEventhostname mappingevent_type

internal/endpoint

7

Audit and integrity layer

Every protected request is audited, and audit/event rows are chained with DB-trigger hashes.

๊ด€๋ฆฌ์ž ํ–‰๋™๊ณผ endpoint ์ด๋ฒคํŠธ๊ฐ€ ๋ณ€์กฐ ํ”์ ์„ ๋‚จ๊ธฐ๋„๋ก DB hash chain์œผ๋กœ ๋ฌถ์ธ๋‹ค.

Why: application code๋ณด๋‹ค DB trigger๊ฐ€ ๋ˆ„๋ฝ๊ณผ ์šฐํšŒ๋ฅผ ์ค„์ธ๋‹ค. advisory lock์œผ๋กœ ๋™์‹œ์„ฑ race๋„ ๋ง‰์•˜๋‹ค.

audit_logsendpoint_eventsprev_hashrow_hash

internal/audit, migrations 008/013

8

Encrypted vault storage

Files are encrypted with per-file keys and stored as encrypted blobs on disk.

ํŒŒ์ผ ๋ณธ๋ฌธ์€ ๋””์Šคํฌ์— ์•”ํ˜ธํ™” blob์œผ๋กœ ์ €์žฅ๋˜๊ณ , DB์—๋Š” key์™€ metadata๊ฐ€ ๋“ค์–ด๊ฐ„๋‹ค.

Why: ๋ฌธ์„œ ๋ณด์•ˆ ์ œํ’ˆ์—์„œ confidentiality์™€ integrity๋ฅผ ๊ฐ™์ด ๋งํ•ด์•ผ ํ•˜๋ฏ€๋กœ chunked AES-GCM์„ ์“ด๋‹ค.

Envelope encryptionAES-256-GCM64KiB chunksfile_versions

internal/vault

9

Detection and alert layer

Rule-based anomaly scoring and alert rules turn raw events into risk signals.

raw ์ด๋ฒคํŠธ๋ฅผ ๊ฒฝ๋ณด์™€ ์œ„ํ—˜ ์ ์ˆ˜๋กœ ๋ฐ”๊พธ๋Š” ๊ณ„์ธต์ด๋‹ค. ๋จธ์‹ ๋Ÿฌ๋‹์ด ์•„๋‹ˆ๋ผ ๊ทœ์น™ ๊ธฐ๋ฐ˜์ด๋‹ค.

Why: ์ž‘์€ ํŒ€์—์„œ๋Š” ์„ค๋ช… ๊ฐ€๋Šฅํ•œ ์ž„๊ณ„๊ฐ’ rule์ด ML๋ณด๋‹ค ๊ตฌํ˜„/์šด์˜/๋ถ„์Ÿ ์„ค๋ช…์— ํ˜„์‹ค์ ์ด๋‹ค.

ueba analyzeralert enginemonitoring configrisk scores

internal/ueba, internal/alert, internal/monitoring

10

AI operations layer

Optional AI briefing and tool-use assistant help admins understand and operate the system.

AI๋Š” ํ•ต์‹ฌ ์ˆ˜์ง‘๊ธฐ๊ฐ€ ์•„๋‹ˆ๋ผ ์šด์˜ ๋ณด์กฐ๋‹ค. ์ตœ๊ทผ ์ด๋ฒคํŠธ ์š”์•ฝ๊ณผ ์ œํ•œ๋œ admin action์„ ๋•๋Š”๋‹ค.

Why: ๋ฐ์ดํ„ฐ๊ฐ€ table์— ์žˆ์œผ๋ฏ€๋กœ ๋ฌธ์„œ RAG๋ณด๋‹ค SQL tool-use๊ฐ€ ๋” ์ •ํ™•ํ•œ grounding์„ ์ค€๋‹ค.

insight summarizeragent toolsconfirmation gateagent_actions

internal/insight, internal/agent

11

Single-host deployment

Docker Compose runs db, migrate, seed, server, and Caddy on one host.

์ž‘์€ ํŒ€์ด ํ•œ ์„œ๋ฒ„์— ์˜ฌ๋ ค ์ง์ ‘ ์šด์˜ํ•˜๋Š” ๊ตฌ์กฐ๋‹ค. Caddy๊ฐ€ HTTPS๋ฅผ ๋งก๊ณ  Go server๋Š” ๋‚ด๋ถ€์—์„œ ๋ˆ๋‹ค.

Why: ์ดˆ๊ธฐ self-hosted ์ œํ’ˆ์€ Kubernetes๋ณด๋‹ค Compose๊ฐ€ ์ดํ•ด์™€ ๋ณต๊ตฌ๊ฐ€ ์‰ฝ๋‹ค.

Dockerfiledocker-compose.prod.ymlCaddyvolumes

docker-compose.prod.yml, deploy

12

Known limitations

The product explicitly documents where it is not production security, HA, legal evidence, or full UEBA.

๊ณผ์žฅํ•˜๋ฉด ์•ˆ ๋˜๋Š” ํ•œ๊ณ„๋‹ค. ์ฐจ๋‹จ ๋ถˆ๊ฐ€, HA ์—†์Œ, PSK ํ•œ๊ณ„, ๋ฒ•์  ์ฆ๊ฑฐ ํ•œ๊ณ„, ๋ถ€ํ•˜ํ…Œ์ŠคํŠธ ๋ฏธ์‹ค์‹œ๊ฐ€ ์žˆ๋‹ค.

Why: ๋ฉด์ ‘์—์„œ๋Š” ๋งŒ๋“  ๊ฒƒ๋ณด๋‹ค ํ•œ๊ณ„๋ฅผ ์ •ํ™•ํžˆ ๋งํ•˜๋Š” ๊ฒƒ์ด ์‹ ๋ขฐ๋‹ค.

LIMITATIONS.mdrule-based scoringPSKno HA

docs/LIMITATIONS.md

Runtime flows

๊ตฌ์กฐ๋ณด๋‹ค ๋” ์ค‘์š”ํ•œ ๊ฑด ์š”์ฒญ๊ณผ ๋ฐ์ดํ„ฐ๊ฐ€ ์–ด๋””๋กœ ํ๋ฅด๋Š”์ง€๋‹ค.

Selected flow

Clipboard event ingestion

์ง์› PC์—์„œ ๋ณต์‚ฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด Go clipboard agent๊ฐ€ PSK์™€ ํ•จ๊ป˜ ์ด๋ฒคํŠธ๋ฅผ ๋ณด๋‚ด๊ณ  ์„œ๋ฒ„๊ฐ€ endpoint_events์— ์ €์žฅํ•œ ๋’ค alert/UEBA/SSE๋กœ fan-outํ•œ๋‹ค.

1clipboard changes
2agent POST /api/events/clipboard
3PSK check
4install token/user resolution
5normalize event
6insert endpoint_events
7hash trigger
8alert + scoring + SSE
Failure checks
  • PSK๊ฐ€ ์—†์œผ๋ฉด fail-closed ๋˜๋Š”๊ฐ€
  • Windows interactive session์—์„œ ์‹คํ–‰ ์ค‘์ธ๊ฐ€
  • hostname์ด ์ž˜๋ชป ๋งคํ•‘๋˜์ง€ ์•Š์•˜๋Š”๊ฐ€
  • clipboard event์™€ heartbeat๋ฅผ ํ˜ผ๋™ํ•˜์ง€ ์•Š๋Š”๊ฐ€
Say it

Clipboard collection is a custom Go agent path: authenticate, normalize, store, hash-chain, then evaluate alerts and risk.

Backend domains

๋„๋ฉ”์ธ์„ ์ฑ…์ž„, ํŒŒ์ผ, ํ…Œ์ด๋ธ”, ๋ฉด์ ‘ ๋ฌธ์žฅ์œผ๋กœ ์—ฐ๊ฒฐํ•œ๋‹ค.

auth

auth

JWT, refresh token, pending 2FA token, TOTP, secret protection, auth middleware.

Auth uses signed JWTs plus optional TOTP; new TOTP secrets are protected by the master key, while legacy plaintext remains an honest migration caveat.

Files: internal/auth/jwt.go, internal/auth/totp.go, internal/auth/secret.go, internal/auth/middleware.go
Tables: users
user

user

์ง์›/admin ๊ณ„์ •, role, password hashing, admin user management.

Users are the human identity layer; endpoint agents are mapped back to users for accountable timelines.

Files: internal/user, internal/web/form handlers
Tables: users
endpoint

endpoint

osquery/clipboard events, enrollment, heartbeat, self-test, hostname attribution.

Endpoint collection is split: osquery covers general host telemetry, and the custom Go agent covers clipboard capture and liveness.

Files: internal/endpoint, cmd/clipagent, deploy/osquery
Tables: endpoint_events, endpoint_agents, install_tokens
audit

audit

๋ชจ๋“  ๋ณดํ˜ธ route์˜ ๊ด€๋ฆฌ์ž ํ–‰๋™ ๊ธฐ๋ก, CSV export, integrity verification.

Audit logging is middleware because it is a cross-cutting requirement, not something each handler should remember manually.

Files: internal/audit, internal/web/router.go
Tables: audit_logs
vault

vault

ํŒŒ์ผ ์—…๋กœ๋“œ/๋‹ค์šด๋กœ๋“œ/๋ฒ„์ „/checkout/checkin, envelope encryption, storage.

The vault stores encrypted blobs on disk and metadata in Postgres, using envelope encryption and chunked GCM for integrity.

Files: internal/vault, internal/folder
Tables: files, file_versions, folders, folder_permissions, encryption_keys
monitoring

monitoring

๊ฐ์‹œ process/extension/path/disguise rule์„ DB ๊ธฐ๋ฐ˜์œผ๋กœ ๊ด€๋ฆฌ.

Monitoring config is data-driven so admins can tune detection policy without redeploying the server.

Files: internal/monitoring
Tables: monitored_process_groups, monitored_extensions, monitored_paths, disguise_rules
alert

alert

์ด๋ฒคํŠธ rule ํ‰๊ฐ€, alert ์ƒ์„ฑ, Slack/email notifier, acknowledge.

The alert engine turns stored telemetry into actionable signals, but inline evaluation is a simplicity trade-off.

Files: internal/alert
Tables: alerts, alert_rules
ueba

ueba

30์ผ baseline ์žฌ๊ณ„์‚ฐ, rule-based anomaly factors, risk scores.

The honest name is rule-based anomaly scoring, not ML-based UEBA.

Files: internal/ueba
Tables: user_behavior_baselines, anomaly_events, risk_scores
tracking

tracking

๋ฏผ๊ฐ ํŒŒ์ผ hash ๋“ฑ๋ก๊ณผ endpoint event hash match detection.

Hash-based file tracking can find renamed known files, but it will miss modified or unknown files.

Files: internal/tracking
Tables: tracked_files, tracked_file_detections
web

web

Server-rendered admin UI, templates, forms, SSE, CSRF, install pages.

The frontend is server-rendered HTML with htmx, which is appropriate for an internal admin console.

Files: internal/web
Tables: many read/write through handlers
insight

insight

์ตœ๊ทผ ์ด๋ฒคํŠธ digest๋ฅผ AI provider์— ๋ณด๋‚ด ์งง์€ ๋ณด์•ˆ ๋ธŒ๋ฆฌํ•‘ ์ƒ์„ฑ.

The AI summary sees a compact factual digest, not arbitrary database access.

Files: internal/insight
Tables: endpoint_events, alerts
agent-ai

agent AI

Tool-use AI assistant, read/action tools, confirmation gate, rollback.

Mutating AI tools require an explicit human confirmation turn and record rollback state.

Files: internal/agent
Tables: agent_actions, users, endpoint_agents, alerts

Concept cards

๋ชจ๋ฅด๋Š” ๋‹จ์–ด๋ฅผ ์—ด๋ฉด ์˜๋ฏธ, repo ์œ„์น˜, ์˜์–ด ๋‹ต๋ณ€, ํ•จ์ •์ด ๊ฐ™์ด ๋‚˜์˜จ๋‹ค.

49
visible
0. ProductBuilt

Detection, not prevention

DocVault๋Š” ๋ง‰๋Š” ์ œํ’ˆ์ด ์•„๋‹ˆ๋ผ ํƒ์ง€์™€ ๊ฐ์‚ฌ ์ œํ’ˆ์ด๋‹ค.

DocVault is positioned as detection and audit, not prevention or DRM.

Deeper

ํŒŒ์ผ ๋ณต์‚ฌ๋‚˜ USB ์‚ฌ์šฉ์„ ์‹ค์‹œ๊ฐ„ ์ฐจ๋‹จํ•˜์ง€ ์•Š๊ณ , ๋ฐœ์ƒํ•œ ํ™œ๋™์„ ๊ธฐ๋กํ•˜๊ณ  ์œ„ํ—˜ํ•œ ํŒจํ„ด์„ ๋ณด์—ฌ์ค€๋‹ค.

Why it matters

์ œํ’ˆ ํฌ์ง€์…”๋‹์„ ์ •ํ™•ํžˆ ํ•ด์•ผ DRM/EDR์™€ ๋น„๊ต ์งˆ๋ฌธ์—์„œ ๋ฒ„ํ‹ด๋‹ค.

Trap

์ฐจ๋‹จ์ด ์—†๋‹ค๋Š” ํ•œ๊ณ„๋ฅผ ์ˆจ๊ธฐ๋ฉด ๋ฐ”๋กœ ์‹ ๋ขฐ๋ฅผ ์žƒ๋Š”๋‹ค.

Where

README, LIMITATIONS, DECISIONS ADR-003

Related
DRMEDR
0. ProductBuilt

Small-team scope

์˜๋„ ๊ทœ๋ชจ๋Š” ๋Œ€๋žต 40๋ช…, 100 endpoint ์ˆ˜์ค€์ด๋‹ค.

The system is scoped for small teams, not internet-scale telemetry.

Deeper

๋ฌธ์„œ์ƒ 50K events/day ์ •๋„๋ฅผ ์ƒ์ •ํ•˜๊ณ  ๋‹จ์ผ Postgres์™€ ๋‹จ์ผ ์„œ๋ฒ„๋กœ ์„ค๊ณ„ํ–ˆ๋‹ค.

Why it matters

์Šค์ผ€์ผ ์งˆ๋ฌธ์—์„œ ์–ด๋–ค ๊ทœ๋ชจ๋ฅผ ๊ฒ€์ฆํ–ˆ๋Š”์ง€ ์†”์งํžˆ ๋งํ•ด์•ผ ํ•œ๋‹ค.

Trap

๊ฒ€์ฆํ•˜์ง€ ์•Š์€ 1M events/day๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค๊ณ  ๋งํ•˜์ง€ ๋ง๋ผ.

Where

README, LIMITATIONS L-SCALE

Related
scalescope
1. LanguageBuilt

Go static binary

Go๋Š” ์„œ๋ฒ„์™€ agent๋ฅผ ๋‹จ์ผ ์‹คํ–‰ํŒŒ์ผ๋กœ ๋งŒ๋“ค๊ธฐ ์‰ฝ๋‹ค.

Go was chosen largely because endpoint agents need simple cross-platform binary deployment.

Deeper

Windows/macOS endpoint agent ๋ฐฐํฌ๊ฐ€ ํ•ต์‹ฌ์ด๋ผ Python/Java runtime ์„ค์น˜ ๋ถ€๋‹ด์„ ํ”ผํ•œ๋‹ค.

Why it matters

์–ธ์–ด ์„ ํƒ ์ด์œ ์˜ ์ค‘์‹ฌ์€ backend ์ทจํ–ฅ์ด ์•„๋‹ˆ๋ผ endpoint ๋ฐฐํฌ๋‹ค.

Trap

์„œ๋ฒ„๋งŒ ์ƒ๊ฐํ•ด์„œ Go๋ฅผ ๊ณจ๋ž๋‹ค๊ณ  ๋งํ•˜๋ฉด ์–•๋‹ค.

Where

go.mod, DECISIONS ADR-001

Related
GOOSGOARCH
1. LanguagePartial

Legacy module path

Go module path๋Š” repo ์ด๋ฆ„๊ณผ ๋‹ค๋ฅด๊ฒŒ ๋‚จ์•„ ์žˆ๋‹ค.

The module path is legacy technical debt, and imports still use it consistently.

Deeper

go.mod๋Š” github.com/JasonAIFactory/Product024_JasonDRM์ด๊ณ  ๋ฌธ์„œ๋„ ์ด legacy path๋ฅผ ๋ช…์‹œํ•œ๋‹ค.

Why it matters

๋ฉด์ ‘์—์„œ repo hygiene์™€ technical debt๋ฅผ ์†”์งํžˆ ๋งํ•  ์ˆ˜ ์žˆ๋‹ค.

Trap

์ด๋ฆ„์ด ๋‹ค๋ฅด๋‹ค๊ณ  ๋นŒ๋“œ๊ฐ€ ํ‹€๋ฆฐ ๊ฑด ์•„๋‹ˆ๋‹ค.

Where

go.mod, HANDOFF.md

Related
go moduleimport path
2. BackendBuilt

chi route groups

๋ณดํ˜ธ route์™€ public route๋ฅผ ๊ทธ๋ฃน์œผ๋กœ ๋‚˜๋ˆ  middleware๋ฅผ ๋ถ™์ธ๋‹ค.

Route groups make authentication, audit, CSRF, and admin-only boundaries explicit.

Deeper

agent endpoint๋Š” PSK, protected API๋Š” JWT+audit, web form์€ JWT+audit+CSRF๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

Why it matters

์š”์ฒญ ๊ฒฝ๊ณ„๊ฐ€ route group์—์„œ ๋ถ„๋ช…ํžˆ ๋ณด์ด๋Š” ๊ฒƒ์ด ์žฅ์ ์ด๋‹ค.

Trap

route๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ๊ทธ๋ฃน ์‹ค์ˆ˜ ๊ฐ€๋Šฅ์„ฑ๋„ ๊ฐ™์ด ์ปค์ง„๋‹ค.

Where

internal/web/router.go

Related
middlewarerouter
2. BackendBuilt

Repository pattern

DB ์ ‘๊ทผ์„ internal/*/repository.go์— ๋ชจ์•„๋‘”๋‹ค.

Repositories isolate SQL access from HTTP handlers and domain orchestration.

Deeper

handler๋Š” HTTP boundary๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  repository๋Š” SQL query๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

Why it matters

๋„๋ฉ”์ธ๋ณ„ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ์ฑ…์ž„์ด ๋ถ„๋ฆฌ๋ผ ์ฝ”๋“œ ์ฐพ๊ธฐ๊ฐ€ ์‰ฌ์›Œ์ง„๋‹ค.

Trap

repository๊ฐ€ ์žˆ๋‹ค๊ณ  domain model์ด ์ž๋™์œผ๋กœ ๊นจ๋—ํ•ด์ง€๋Š” ๊ฑด ์•„๋‹ˆ๋‹ค.

Where

internal/*/repository.go

Related
pgxSQL
9. OpsBuilt

slog

Go ํ‘œ์ค€ structured logging์ด๋‹ค.

slog gives the server structured operational logs without an external logging framework.

Deeper

์„œ๋ฒ„ ์‹œ์ž‘, agent ๋“ฑ๋ก, event ์ฒ˜๋ฆฌ, AI tool error ๊ฐ™์€ ์šด์˜ ์ด๋ฒคํŠธ๋ฅผ key-value๋กœ ๋‚จ๊ธด๋‹ค.

Why it matters

container stdout๊ณผ ์ž˜ ๋งž๊ณ  incident review์— ํ•„์š”ํ•œ ํ•„๋“œ๋ฅผ ๋ถ™์ด๊ธฐ ์‰ฝ๋‹ค.

Trap

๋กœ๊ทธ๋งŒ ์žˆ๊ณ  metrics๊ฐ€ ์—†์œผ๋ฉด ๊ด€์ธก์„ฑ์€ ๋ถ€์กฑํ•˜๋‹ค.

Where

cmd/server/main.go

Related
loggingobservability
9. OpsBuilt

Graceful shutdown

SIGINT/SIGTERM์„ ๋ฐ›์œผ๋ฉด HTTP server๋ฅผ 10์ดˆ ์•ˆ์— ์ •์ƒ ์ข…๋ฃŒํ•œ๋‹ค.

The server handles SIGINT/SIGTERM and shuts down with a bounded context.

Deeper

baseline scheduler context๋„ cancelํ•ด์„œ goroutine ๋ˆ„์ˆ˜๋ฅผ ์ค„์ธ๋‹ค.

Why it matters

๋ฐฐํฌ์™€ ์žฌ์‹œ์ž‘ ์‹œ ์š”์ฒญ/์ž‘์—…์„ ๋ฌด์ž‘์ • ๋Š์ง€ ์•Š๋Š” ์šด์˜ ๊ฐ๊ฐ์„ ๋ณด์—ฌ์ค€๋‹ค.

Trap

SSE ๊ฐ™์€ long-lived connection์€ shutdown ๋™์ž‘์„ ๋”ฐ๋กœ ๋ด์•ผ ํ•œ๋‹ค.

Where

cmd/server/main.go

Related
signalcontext
3. FrontendBuilt

htmx admin console

React ์—†์ด ์„œ๋ฒ„ HTML ์กฐ๊ฐ์œผ๋กœ ๋™์  ํ™”๋ฉด์„ ๋งŒ๋“ ๋‹ค.

htmx is appropriate because DocVault is an internal admin console with server-owned state.

Deeper

๋‚ด๋ถ€ ๊ด€๋ฆฌ์ž ๋„๊ตฌ๋ผ build chain ์—†์ด forms, tables, search, admin pages๋ฅผ ๋น ๋ฅด๊ฒŒ ์ œ๊ณตํ•œ๋‹ค.

Why it matters

์™œ React๋ฅผ ์•ˆ ์ผ๋ƒ๋Š” ์งˆ๋ฌธ์— ๋‹ตํ•˜๋Š” ํ•ต์‹ฌ์ด๋‹ค.

Trap

htmx๋ฅผ ํ”„๋ก ํŠธ์—”๋“œ๊ฐ€ ์—†๋‹ค๊ณ  ํ‘œํ˜„ํ•˜๋ฉด ๋ถ€์ •ํ™•ํ•˜๋‹ค.

Where

internal/web/static/htmx.min.js, templates

Related
SSRtemplates
3. FrontendBuilt

Go templates

์„œ๋ฒ„๊ฐ€ data๋ฅผ HTML template์— ๋„ฃ์–ด ํ™”๋ฉด์„ ๋งŒ๋“ ๋‹ค.

Go templates keep rendering server-side and deployment simple.

Deeper

layout๊ณผ page template๊ฐ€ Go binary์™€ ํ•จ๊ป˜ ๋ฐฐํฌ๋˜์–ด ๋ณ„๋„ frontend build๊ฐ€ ์—†๋‹ค.

Why it matters

์ž‘์€ self-hosted admin UI์—์„œ ๋ฐฐํฌ ๋‹จ์ˆœ์„ฑ์„ ์ค€๋‹ค.

Trap

template๊ฐ€ ์ปค์ง€๋ฉด componentization ํ•œ๊ณ„๊ฐ€ ์ƒ๊ธด๋‹ค.

Where

internal/web/templates

Related
html/templateescaping
6. SecurityBuilt

CSRF token

์ฟ ํ‚ค ๋กœ๊ทธ์ธ ์ƒํƒœ๋ฅผ ์•…์šฉํ•œ ์™ธ๋ถ€ ์‚ฌ์ดํŠธ ์š”์ฒญ์„ ๋ง‰๋Š” ํ† ํฐ์ด๋‹ค.

CSRF protection is required for cookie-authenticated admin mutations.

Deeper

web form POST์™€ htmx mutation ์š”์ฒญ์—์„œ cookie token๊ณผ form/header token์„ ๋น„๊ตํ•œ๋‹ค.

Why it matters

๊ด€๋ฆฌ์ž UI๊ฐ€ cookie ๊ธฐ๋ฐ˜์ด๋ผ CSRF ๋ฐฉ์–ด๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

Trap

CSRF์™€ XSS ๋ฐฉ์–ด๋ฅผ ํ˜ผ๋™ํ•˜์ง€ ๋ง๋ผ.

Where

internal/web/csrf.go

Related
cookieSameSite
3. FrontendBuilt

SSE dashboard

์„œ๋ฒ„๊ฐ€ dashboard๋กœ ์ƒˆ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ€์–ด์ฃผ๋Š” ๋‹จ๋ฐฉํ–ฅ stream์ด๋‹ค.

SSE gives simple real-time dashboard updates without a full WebSocket layer.

Deeper

endpoint event๋‚˜ alert ๋ฐœ์ƒ ์‹œ ํŽ˜์ด์ง€๋ฅผ ์ƒˆ๋กœ๊ณ ์นจํ•˜์ง€ ์•Š๊ณ  ์•Œ๋ฆผ์„ ๋ฐ˜์˜ํ•œ๋‹ค.

Why it matters

WebSocket๋ณด๋‹ค ๋‹จ์ˆœํ•œ live update ์š”๊ตฌ์— ๋งž๋‹ค.

Trap

์–‘๋ฐฉํ–ฅ ์‹ค์‹œ๊ฐ„ ํ˜‘์—…์—๋Š” SSE๊ฐ€ ๋ถ€์กฑํ•  ์ˆ˜ ์žˆ๋‹ค.

Where

internal/web/sse.go

Related
streamdashboard
4. EndpointBuilt

osquery

ํŒŒ์ผ/USB/process telemetry๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์˜คํ”ˆ์†Œ์Šค agent๋‹ค.

osquery collects host telemetry; DocVault normalizes and analyzes it.

Deeper

DocVault๋Š” osquery๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๊ณ  ์„ค์ •๊ณผ server protocol๋กœ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›๋Š”๋‹ค.

Why it matters

๋ฐ”ํ€ด ์žฌ๋ฐœ๋ช… ๋Œ€์‹  ๊ฒ€์ฆ๋œ ๋„๊ตฌ๋ฅผ ํ™œ์šฉํ•œ ์„ ํƒ์ด๋‹ค.

Trap

osquery๋Š” ์ปค๋„ EDR์ด ์•„๋‹ˆ๋‹ค.

Where

deploy/osquery, internal/endpoint/osquery.go

Related
telemetryscheduled query
4. EndpointBuilt

Clipboard agent

ํด๋ฆฝ๋ณด๋“œ ๋ณต์‚ฌ ์ด๋ฒคํŠธ๋ฅผ ์žก๋Š” ์ž์ฒด Go agent๋‹ค.

The custom clipboard agent covers a signal that osquery does not own.

Deeper

Windows/macOS๋ณ„ ๊ตฌํ˜„์œผ๋กœ clipboard ๋ณ€๊ฒฝ์„ ๊ฐ์ง€ํ•˜๊ณ  ์„œ๋ฒ„์— ์ด๋ฒคํŠธ๋ฅผ ๋ณด๋‚ธ๋‹ค.

Why it matters

๋ฌธ์„œ ์œ ์ถœ์—์„œ ๋ณต์‚ฌ/๋ถ™์—ฌ๋„ฃ๊ธฐ๋Š” ์ค‘์š”ํ•œ ์‹ ํ˜ธ๋ผ ๋ณ„๋„ ๊ตฌํ˜„ ๊ฐ€์น˜๊ฐ€ ์žˆ๋‹ค.

Trap

ํ•ฉ๋ฒ•์  ๊ณ ์ง€ ์—†์ด ๊ฐœ์ธ PC ๊ฐ์‹œ์— ์“ฐ๋ฉด ์•ˆ ๋œ๋‹ค.

Where

cmd/clipagent

Related
clipboardagent
4. EndpointBuilt

Heartbeat liveness

agent๊ฐ€ ์‚ด์•„์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์ด๋ฒคํŠธ์™€ ๋ณ„๋„๋กœ ๋ณด๋‚ธ๋‹ค.

Heartbeat separates agent liveness from actual captured activity.

Deeper

ํด๋ฆฝ๋ณด๋“œ ๋ณ€ํ™”๊ฐ€ ์—†๋Š” PC๋„ last_checkin์œผ๋กœ ์˜จ๋ผ์ธ ์—ฌ๋ถ€๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.

Why it matters

idle ์ƒํƒœ์™€ offline์„ ๊ตฌ๋ถ„ํ•˜๋Š” ์šด์˜ ๊ธฐ๋Šฅ์ด๋‹ค.

Trap

heartbeat๋Š” event loss๊ฐ€ ์—†๋‹ค๋Š” ๋ณด์žฅ์ด ์•„๋‹ˆ๋‹ค.

Where

ReceiveHeartbeat, endpoint_agents

Related
last_checkinliveness
4. EndpointBuilt

Agent self-test

agent๊ฐ€ interactive session๊ณผ clipboard ์ ‘๊ทผ ๊ฐ€๋Šฅ์„ฑ์„ ์„œ๋ฒ„์— ๋ณด๊ณ ํ•œ๋‹ค.

Self-test tells the admin whether the agent can access clipboard APIs before real captures arrive.

Deeper

Windows Session 0 ๋ฌธ์ œ๋ฅผ ์ œํ’ˆ ํ™”๋ฉด์—์„œ ๋นจ๋ฆฌ ์ง„๋‹จํ•˜๊ธฐ ์œ„ํ•œ ์ƒํƒœ๋‹ค.

Why it matters

์„ค์น˜ ์„ฑ๊ณต๊ณผ ์‹ค์ œ ์บก์ฒ˜ ์„ฑ๊ณต์„ ๋ถ„๋ฆฌํ•ด ๋งํ•  ์ˆ˜ ์žˆ๋‹ค.

Trap

self-test OK์™€ ์‹ค์ œ ์œ ์ถœ ํƒ์ง€ OK๋Š” ๋‹ค๋ฅด๋‹ค.

Where

ReceiveSelfTest, install flow

Related
Session 0capture_waiting
4. EndpointBuilt

Install token

์ง์›๋ณ„ agent ์„ค์น˜ ๋งํฌ๋ฅผ ์œ„ํ•œ ์ผํšŒ์„ฑ ํ† ํฐ์ด๋‹ค.

Install tokens let admins onboard employees without exposing the shared agent PSK.

Deeper

์ง์› ํŽ˜์ด์ง€๋Š” PSK๋ฅผ ๋…ธ์ถœํ•˜์ง€ ์•Š๊ณ  installer ๋‹ค์šด๋กœ๋“œ/๋“ฑ๋ก ํ๋ฆ„์„ ์ œ๊ณตํ•œ๋‹ค.

Why it matters

๋น„์ „๋ฌธ ์‚ฌ์šฉ์ž onboarding๊ณผ secret ๋…ธ์ถœ ์ตœ์†Œํ™”๋ฅผ ๊ฐ™์ด ํ•ด๊ฒฐํ•œ๋‹ค.

Trap

ํ† ํฐ์ด ์žˆ๋‹ค๊ณ  code-signing ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜๋Š” ๊ฑด ์•„๋‹ˆ๋‹ค.

Where

migration 018, PageHandler install

Related
onboardingPSK
4. EndpointBuilt

Hostname attribution

PC hostname์„ ์‚ฌ์šฉ์ž์™€ ์—ฐ๊ฒฐํ•ด ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ๋žŒ timeline์— ๋ถ™์ธ๋‹ค.

Hostname attribution turns raw host telemetry into accountable user timelines.

Deeper

endpoint_agents.user_id๊ฐ€ ์žˆ์œผ๋ฉด endpoint_events๋ฅผ ํŠน์ • ์ง์›์—๊ฒŒ ๊ท€์†ํ•  ์ˆ˜ ์žˆ๋‹ค.

Why it matters

๋ณด์•ˆ ์ด๋ฒคํŠธ๋Š” ์‚ฌ๋žŒ/์žฅ๋น„ ๋งฅ๋ฝ์ด ์žˆ์–ด์•ผ ์šด์˜์ž๊ฐ€ ์ดํ•ดํ•œ๋‹ค.

Trap

hostname๋งŒ ๋งน์‹ ํ•˜๋ฉด ๊ณต์œ  PC/์ด๋ฆ„ ๋ณ€๊ฒฝ์—์„œ ํ‹€๋ฆด ์ˆ˜ ์žˆ๋‹ค.

Where

endpoint handler, admin agents

Related
user mappingtimeline
5. DataBuilt

endpoint_events

endpoint telemetry์˜ ์ค‘์‹ฌ table์ด๋‹ค.

endpoint_events is the shared schema for all endpoint activity.

Deeper

osquery์™€ clipboard๊ฐ€ normalize๋œ ๋’ค event_type, hostname, file, process, time์œผ๋กœ ์ €์žฅ๋œ๋‹ค.

Why it matters

๊ฒ€์ƒ‰, timeline, alert, AI assistant๊ฐ€ ์ด table์„ ๋งŽ์ด ์ฝ๋Š”๋‹ค.

Trap

row ์ˆ˜๊ฐ€ ์ปค์ง€๋ฉด partitioning/retention์ด ํ•„์š”ํ•˜๋‹ค.

Where

migration 004, endpoint repository

Related
indextelemetry
5. DataBuilt

audit_logs

๊ด€๋ฆฌ์ž ํ–‰๋™ ๊ฐ์‚ฌ table์ด๋‹ค.

audit_logs records admin activity as a first-class security artifact.

Deeper

๋ณดํ˜ธ๋œ route๋ฅผ ๋ˆ„๊ฐ€ ์–ด๋–ค status๋กœ ํ˜ธ์ถœํ–ˆ๋Š”์ง€ ๋ฏธ๋“ค์›จ์–ด๊ฐ€ ์ž๋™ ๊ธฐ๋กํ•œ๋‹ค.

Why it matters

๋ณด์•ˆ ์ œํ’ˆ์—์„œ ์‚ฌ์šฉ์ž ํ–‰๋™๋ฟ ์•„๋‹ˆ๋ผ ๊ด€๋ฆฌ์ž ํ–‰๋™๋„ ๊ฐ์‹œํ•ด์•ผ ํ•œ๋‹ค.

Trap

๊ฐ์‚ฌ action derivation์ด path ๊ธฐ๋ฐ˜์ด๋ผ๋Š” ํ•œ๊ณ„๋ฅผ ๋งํ•ด์•ผ ํ•œ๋‹ค.

Where

internal/audit, migration 003

Related
auditmiddleware
5. DataBuilt

Critical indexes

์ฃผ์š” ์กฐํšŒ ํŒจํ„ด์„ ๋ฒ„ํ‹ฐ๊ธฐ ์œ„ํ•œ DB index๋“ค์ด๋‹ค.

Indexes are designed around the dashboard and audit query patterns.

Deeper

user timeline, filename search, event type/time, alert unacked ๊ฐ™์€ query์— ๋งž์ถฐ index๋ฅผ ๋‘”๋‹ค.

Why it matters

์ด๋ฒคํŠธ table์€ ๋ช‡ ์ฃผ๋งŒ ์ง€๋‚˜๋„ scan์ด ์น˜๋ช…์ ์ด๋ฏ€๋กœ index๊ฐ€ ์ƒ์กด ์กฐ๊ฑด์ด๋‹ค.

Trap

index๊ฐ€ ๋งŽ์œผ๋ฉด write cost์™€ storage๋„ ๋Š˜์–ด๋‚œ๋‹ค.

Where

docs/SPEC.md, migrations

Related
query patternperformance
6. SecurityBuilt

Hash chain

๊ฐ ๋กœ๊ทธ ํ–‰์ด ์ด์ „ ํ–‰ hash๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋ณ€์กฐ ํƒ์ง€ ์‚ฌ์Šฌ์ด๋‹ค.

The hash chain makes log tampering detectable at the application/database trigger level.

Deeper

prev_hash์™€ row_hash๋กœ ์—ฐ๊ฒฐ๋˜์–ด ํ•œ ํ–‰์„ ๋ฐ”๊พธ๋ฉด ์ดํ›„ ์ฒด์ธ ๊ฒ€์ฆ์ด ์‹คํŒจํ•œ๋‹ค.

Why it matters

๊ฐ์‚ฌ ๋กœ๊ทธ์˜ ์‹ ๋ขฐ์„ฑ์„ ์„ค๋ช…ํ•˜๋Š” ๋Œ€ํ‘œ ์„ค๊ณ„๋‹ค.

Trap

DB superuser ์šฐํšŒ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ ๋ฒ•์  ๋ถˆ๋ณ€์„ฑ์€ ์•„๋‹ˆ๋‹ค.

Where

migrations 008/013

Related
prev_hashrow_hash
6. SecurityBuilt

Advisory lock

๋™์‹œ INSERT๊ฐ€ hash chain์„ ๋ถ„๊ธฐ์‹œํ‚ค์ง€ ์•Š๊ฒŒ ํ•˜๋Š” transaction lock์ด๋‹ค.

The advisory lock serializes hash-chain inserts and prevents forked prev_hash values.

Deeper

trigger๊ฐ€ pg_advisory_xact_lock์„ ์žก์€ ๋’ค ์ตœ์‹  row_hash๋ฅผ ์ฝ๋Š”๋‹ค.

Why it matters

๊ฒฝ์Ÿ ์กฐ๊ฑด์„ ๋ฐœ๊ฒฌํ•˜๊ณ  ์‹ค์ œ๋กœ ๊ณ ์นœ ์ข‹์€ incident/story ํฌ์ธํŠธ๋‹ค.

Trap

์ดˆ๋‹น ๋งŽ์€ insert์—์„œ๋Š” ๋ณ‘๋ชฉ์ด ๋  ์ˆ˜ ์žˆ๋‹ค.

Where

migration 013

Related
race conditionserialization
6. SecurityBuilt

Immutable trigger

audit/event row์˜ UPDATE์™€ DELETE๋ฅผ DB trigger๋กœ ๋ง‰๋Š”๋‹ค.

Database triggers reject UPDATE and DELETE on audit/event rows.

Deeper

application bug๋‚˜ ์ž„์˜ client๊ฐ€ ๋กœ๊ทธ๋ฅผ ์ˆ˜์ •/์‚ญ์ œํ•˜์ง€ ๋ชปํ•˜๊ฒŒ DB ๋ ˆ๋ฒจ์—์„œ ์ฐจ๋‹จํ•œ๋‹ค.

Why it matters

๋ฌด๊ฒฐ์„ฑ ์ •์ฑ…์„ application layer๋ณด๋‹ค ์•„๋ž˜๋กœ ๋‚ด๋ฆฐ ์„ ํƒ์ด๋‹ค.

Trap

superuser๋Š” trigger๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

Where

migration 008

Related
triggerimmutability
6. SecurityBuilt

Envelope encryption

ํŒŒ์ผ๋ณ„ key์™€ master key๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ์•”ํ˜ธํ™” ๊ตฌ์กฐ๋‹ค.

Envelope encryption protects each file with its own data key sealed by the master key.

Deeper

ํŒŒ์ผ ๋ณธ๋ฌธ์€ file key๋กœ ์•”ํ˜ธํ™”ํ•˜๊ณ , file key๋Š” master key๋กœ ๋ด‰์ธํ•ด DB์— ์ €์žฅํ•œ๋‹ค.

Why it matters

ํŒŒ์ผ ๋‹จ์œ„ ๊ฒฉ๋ฆฌ์™€ future key rotation์„ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค.

Trap

master key rotation tool์€ ์•„์ง ๋ฏธ๊ตฌํ˜„์ด๋‹ค.

Where

internal/vault/keymanager.go

Related
master keydata key
6. SecurityBuilt

Chunked AES-GCM

ํŒŒ์ผ์„ ์ฒญํฌ๋ณ„๋กœ ์ธ์ฆ ์•”ํ˜ธํ™”ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

Chunked GCM fixes the old confidentiality-without-integrity problem.

Deeper

64KiB chunk๋งˆ๋‹ค GCM tag๋ฅผ ๋ถ™์—ฌ tamper/truncation/reorder๋ฅผ ํƒ์ง€ํ•œ๋‹ค.

Why it matters

์ดˆ๊ธฐ CTR ๊ฒฐํ•จ์„ ๊ณ ์นœ ์‹ค์ œ ๋ณด์•ˆ ๊ฐœ์„  ์‚ฌ๋ก€๋‹ค.

Trap

AES๋ผ๋Š” ์ด๋ฆ„๋งŒ ๋งํ•˜๊ณ  mode๋ฅผ ๋นผ๋จน์œผ๋ฉด ์•ˆ ๋œ๋‹ค.

Where

internal/vault/encryption.go

Related
AEADintegrity
2. BackendBuilt

Streaming I/O

ํฐ ํŒŒ์ผ์„ ํ•œ ๋ฒˆ์— ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ฆฌ์ง€ ์•Š๊ณ  ํ๋ฆ„์œผ๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค.

Streaming keeps large encrypted files from becoming memory spikes.

Deeper

io.Reader/Writer์™€ chunk encryption์œผ๋กœ ์—…๋กœ๋“œ/๋‹ค์šด๋กœ๋“œ๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.

Why it matters

CAD ๊ฐ™์€ ํฐ ํŒŒ์ผ์—์„œ memory spike๋ฅผ ๋ง‰๋Š” ์‹ค๋ฌด ํฌ์ธํŠธ๋‹ค.

Trap

streaming ์‹คํŒจ ์‹œ partial file cleanup๋„ ๊ณ ๋ คํ•ด์•ผ ํ•œ๋‹ค.

Where

internal/vault/encryption.go

Related
io.Copybackpressure
6. SecurityBuilt

JWT

๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž๋ฅผ ์ฆ๋ช…ํ•˜๋Š” ์„œ๋ช… ํ† ํฐ์ด๋‹ค.

JWT gives DocVault signed identity tokens for web and API access.

Deeper

access, refresh, pending_2fa token type์„ ๊ตฌ๋ถ„ํ•œ๋‹ค.

Why it matters

cookie/API ์ธ์ฆ์„ ๋‹จ์ˆœํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค.

Trap

JWT๋Š” ์•”ํ˜ธํ™”๋œ ์„ธ์…˜ ์ €์žฅ์†Œ๊ฐ€ ์•„๋‹ˆ๋‹ค.

Where

internal/auth/jwt.go

Related
access tokenrefresh token
6. SecurityBuilt

TOTP

์‹œ๊ฐ„ ๊ธฐ๋ฐ˜ 6์ž๋ฆฌ ์ฝ”๋“œ๋กœ 2์ฐจ ์ธ์ฆ์„ ํ•œ๋‹ค.

TOTP adds a second factor for administrator login.

Deeper

๋น„๋ฐ€๋ฒˆํ˜ธ ํ™•์ธ ํ›„ pending token์„ ์ฃผ๊ณ  TOTP๊ฐ€ ๋งž์œผ๋ฉด ์ตœ์ข… token pair๋ฅผ ๋ฐœ๊ธ‰ํ•œ๋‹ค.

Why it matters

admin ๋ณด์•ˆ ์ œํ’ˆ์—์„œ password ๋‹จ๋… ๋กœ๊ทธ์ธ์„ ๋ณด์™„ํ•œ๋‹ค.

Trap

๋ณต๊ตฌ ์ฝ”๋“œ ๋ณด๊ด€๊ณผ secret rotation์€ ๋ณ„๋„ ๋ฌธ์ œ๋‹ค.

Where

internal/auth/totp.go

Related
2FAHOTP
6. SecurityBuilt

Login rate limit

๋กœ๊ทธ์ธ ์‹คํŒจ๋ฅผ IP๋ณ„๋กœ ์ž ๊ทธ๋Š” in-memory ์ œํ•œ์ด๋‹ค.

The login rate limiter slows down password guessing against admin endpoints.

Deeper

5ํšŒ ์‹คํŒจ ํ›„ lockํ•˜๊ณ  ์„ฑ๊ณต ์‹œ ๊ธฐ๋ก์„ ์‚ญ์ œํ•œ๋‹ค.

Why it matters

brute force์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ๋ฐฉ์–ด๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.

Trap

๋ฉ€ํ‹ฐ ์ธ์Šคํ„ด์Šค์—์„œ๋Š” Redis ๊ฐ™์€ ๊ณต์œ  ์ €์žฅ์†Œ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

Where

internal/web/ratelimit.go

Related
brute forcelockout
6. SecurityRisk

PSK auth

agent endpoint๊ฐ€ ๊ณต์œ  ๋น„๋ฐ€ํ‚ค๋กœ ์ธ์ฆ๋œ๋‹ค.

The PSK path is simple but should evolve into per-agent mTLS for stronger identity.

Deeper

constant-time compare๋กœ header ๊ฐ’์„ ํ™•์ธํ•˜๊ณ  ์—†์œผ๋ฉด fail-closed ํ•œ๋‹ค.

Why it matters

์ดˆ๊ธฐ ์„ค์น˜๋Š” ๋‹จ์ˆœํ•˜์ง€๋งŒ mTLS๋กœ ๊ฐ€์•ผ ํ•  ํ•œ๊ณ„๋ฅผ ๋ช…ํ™•ํžˆ ์•ˆ๋‹ค.

Trap

PSK ํ•˜๋‚˜๊ฐ€ ๋…ธ์ถœ๋˜๋ฉด ์ „์ฒด agent trust๊ฐ€ ํ”๋“ค๋ฆฐ๋‹ค.

Where

internal/endpoint/handler.go

Related
mTLSagent identity
2. BackendBuilt

Rule-based scoring

ML์ด ์•„๋‹ˆ๋ผ ๊ทœ์น™๊ณผ ๊ฐ€์ค‘์น˜๋กœ ์ด์ƒํ–‰์œ„๋ฅผ ์ ์ˆ˜ํ™”ํ•œ๋‹ค.

This is rule-based anomaly scoring, not machine-learning UEBA.

Deeper

์•ผ๊ฐ„/์ฃผ๋ง/์ƒˆ IP/๋Œ€๋Ÿ‰/๋ฉ”์‹ ์ € ๋“ฑ ์กฐ๊ฑด์„ ํ‰๊ฐ€ํ•ด risk score๋ฅผ ๋งŒ๋“ ๋‹ค.

Why it matters

์ž‘์€ ํŒ€์—์„  ์„ค๋ช… ๊ฐ€๋Šฅํ•œ ๋ฃฐ์ด ์‹ค์šฉ์ ์ด๋‹ค.

Trap

UEBA๋ผ๊ณ  ๊ณผ์žฅํ•˜๋ฉด ๋ฐ”๋กœ ๊ณต๊ฒฉ๋ฐ›๋Š”๋‹ค.

Where

internal/ueba, docs/LIMITATIONS.md

Related
baselinerisk score
2. BackendBuilt

Behavior baseline

์‚ฌ์šฉ์ž ํ‰์†Œ ํ–‰๋™ ๊ธฐ์ค€์„ ์„ 30์ผ ๋ฐ์ดํ„ฐ๋กœ ๊ณ„์‚ฐํ•œ๋‹ค.

Baselines make rule-based scoring more contextual than fixed global rules.

Deeper

์ƒˆ ์ด๋ฒคํŠธ๊ฐ€ ํ‰์†Œ ์‹œ๊ฐ„๋Œ€/IP/hostname/ํ™•์žฅ์ž์™€ ๋‹ค๋ฅธ์ง€ ๋น„๊ตํ•œ๋‹ค.

Why it matters

์ด์ƒํ–‰์œ„ ํŒ๋‹จ์— ๊ฐœ์ธ๋ณ„ ๋งฅ๋ฝ์„ ๋”ํ•œ๋‹ค.

Trap

baseline์ด ์—†๋Š” ์‹ ๊ทœ ์‚ฌ์šฉ์ž ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

Where

internal/ueba/analyzer.go

Related
30-day windowUPSERT
2. BackendBuilt

Alert rules

์กฐ๊ฑด์ด ๋งž์œผ๋ฉด ๊ฒฝ๋ณด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ทœ์น™์ด๋‹ค.

Alert rules turn raw telemetry into actionable review items.

Deeper

endpoint event๋ฅผ ํ‰๊ฐ€ํ•ด alerts table๊ณผ notifier๋กœ ์—ฐ๊ฒฐํ•œ๋‹ค.

Why it matters

์šด์˜์ž๊ฐ€ raw event๋ฅผ ๋‹ค ๋ณด์ง€ ์•Š์•„๋„ ์ค‘์š”ํ•œ ์ผ์„ ๋ณด๊ฒŒ ํ•œ๋‹ค.

Trap

alert flooding๊ณผ false positive ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

Where

internal/alert

Related
severityacknowledge
2. BackendBuilt

Monitoring config

๊ฐ์‹œ ๊ธฐ์ค€์„ DB์™€ admin UI์—์„œ ์กฐ์ •ํ•œ๋‹ค.

Monitoring config makes detection policy adjustable without code changes.

Deeper

process group, extension, path, disguise rule์„ hardcodeํ•˜์ง€ ์•Š๋Š”๋‹ค.

Why it matters

์žฌ๋ฐฐํฌ ์—†์ด ๊ฐ์‹œ ์ •์ฑ…์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค.

Trap

์„ค์ • ์ž์œ ๋„๊ฐ€ ํƒ์ง€ ํ’ˆ์งˆ์„ ์ž๋™ ๋ณด์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค.

Where

internal/monitoring

Related
process groupdisguise rule
2. BackendBuilt

Hash file tracking

์ค‘์š” ํŒŒ์ผ hash๋ฅผ ๋“ฑ๋กํ•ด ์ด๋ฆ„ ๋ณ€๊ฒฝ ํ›„์—๋„ ์ถ”์ ํ•œ๋‹ค.

Hash tracking can detect known sensitive files even when filenames change.

Deeper

endpoint event detail์˜ SHA256/MD5์™€ tracked file์„ ๋น„๊ตํ•œ๋‹ค.

Why it matters

ํŒŒ์ผ๋ช… ๊ธฐ๋ฐ˜ ํƒ์ง€๋ณด๋‹ค ๊ทผ๊ฑฐ๊ฐ€ ๊ฐ•ํ•˜๋‹ค.

Trap

ํŒŒ์ผ ๋‚ด์šฉ์ด ๋ฐ”๋€Œ๋ฉด hash match๊ฐ€ ๊นจ์ง„๋‹ค.

Where

internal/tracking

Related
SHA256DLP
7. AIPartial

AI briefing

์ตœ๊ทผ ์ด๋ฒคํŠธ digest๋ฅผ ์ž์—ฐ์–ด ๋ณด์•ˆ ์š”์•ฝ์œผ๋กœ ๋ฐ”๊พผ๋‹ค.

The AI briefing summarizes a compact factual digest for a non-expert admin.

Deeper

event counts, notable events, unacked alerts๋ฅผ ๋ชจ์•„ provider์— ๋ณด๋‚ธ๋‹ค.

Why it matters

๋น„์ „๋ฌธ ๊ด€๋ฆฌ์ž๊ฐ€ raw table๋ณด๋‹ค ๋นจ๋ฆฌ ์ดํ•ดํ•˜๊ฒŒ ๋•๋Š”๋‹ค.

Trap

AI๊ฐ€ ์—†๋Š” ์‚ฌ๊ฑด์„ ๋งŒ๋“ค์ง€ ์•Š๊ฒŒ digest์™€ prompt๊ฐ€ ์ค‘์š”ํ•˜๋‹ค.

Where

internal/insight

Related
ClaudeGemini
7. AIPartial

Tool-use agent

AI๊ฐ€ DB ์กฐํšŒ tool๊ณผ ์ผ๋ถ€ admin action tool์„ ํ˜ธ์ถœํ•œ๋‹ค.

The AI assistant uses function-calling tools over live structured data.

Deeper

read tools์™€ action tools๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ณ  mutating tool์€ confirmation์ด ํ•„์š”ํ•˜๋‹ค.

Why it matters

์ •ํ˜• ๋ฐ์ดํ„ฐ ์šด์˜์—๋Š” RAG๋ณด๋‹ค tool-use๊ฐ€ ๋” ์ง์ ‘์ ์ด๋‹ค.

Trap

tool output์€ attacker-influenced data์ผ ์ˆ˜ ์žˆ๋‹ค.

Where

internal/agent

Related
function callingSQL
7. AIBuilt

Confirmation gate

AI action ์‹คํ–‰ ์ „ ์‚ฌ๋žŒ์ด ์‹คํ–‰ ์Šน์ธ์„ ํ•ด์•ผ ํ•œ๋‹ค.

Mutating tools are server-gated by an explicit human confirmation turn.

Deeper

ํŒŒ์ผ๋ช…/์ฐฝ์ œ๋ชฉ ๊ฐ™์€ tool output์— ์ ํžŒ ๋ช…๋ น์€ ์Šน์ธ์œผ๋กœ ์ธ์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค.

Why it matters

prompt injection ๋Œ€์‘์„ ๋ชจ๋ธ ์ง€์‹œ๊ฐ€ ์•„๋‹ˆ๋ผ ์„œ๋ฒ„ ๋กœ์ง์— ๋‘” ์ ์ด ์ค‘์š”ํ•˜๋‹ค.

Trap

ํ™•์ธ ๋ฌธ๊ตฌ๋งŒ์œผ๋กœ ์™„์ „ํ•œ policy engine์ด ๋˜๋Š” ๊ฑด ์•„๋‹ˆ๋‹ค.

Where

internal/agent/agent.go

Related
prompt injectionapproval
7. AIPartial

Rollback

AI action์„ ๋˜๋Œ๋ฆด ์ด์ „ ์ƒํƒœ๋ฅผ ์ €์žฅํ•œ๋‹ค.

Rollback stores previous state so supported AI actions can be undone.

Deeper

agent_actions์— prev_state๋ฅผ ๋‚จ๊ธฐ๊ณ  rollback endpoint๊ฐ€ ๋ณต๊ตฌํ•œ๋‹ค.

Why it matters

AI ์šด์˜ ์ž๋™ํ™”์˜ blast radius๋ฅผ ์ค„์ธ๋‹ค.

Trap

์™ธ๋ถ€ ๋ถ€์ž‘์šฉ ์ „์ฒด๋ฅผ ๋˜๋Œ๋ฆฌ๋Š” ๋งŒ๋Šฅ ๊ธฐ๋Šฅ์€ ์•„๋‹ˆ๋‹ค.

Where

internal/agent/actions.go

Related
agent_actionsundo
8. InfraBuilt

Docker Compose

db/migrate/seed/server/caddy๋ฅผ ํ•œ ํŒŒ์ผ๋กœ ๋„์šด๋‹ค.

Compose keeps the single-host deployment understandable and reproducible.

Deeper

healthcheck์™€ depends_on์œผ๋กœ ์‹œ์ž‘ ์ˆœ์„œ๋ฅผ ์ œ์–ดํ•œ๋‹ค.

Why it matters

์ž‘์€ self-hosted deployment์—๋Š” ์ดํ•ด ๊ฐ€๋Šฅํ•œ ์šด์˜ ๋ชจ๋ธ์ด๋‹ค.

Trap

HA์™€ autoscaling์€ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค.

Where

docker-compose.prod.yml

Related
containervolume
8. InfraBuilt

Caddy

HTTPS์™€ reverse proxy๋ฅผ ๋งก๋Š”๋‹ค.

Caddy handles HTTPS termination and reverse proxying for the Go server.

Deeper

์™ธ๋ถ€ 80/443 ์š”์ฒญ์„ ๋‚ด๋ถ€ Go server๋กœ ์ „๋‹ฌํ•œ๋‹ค.

Why it matters

์ธ์ฆ์„œ ์ž๋™ํ™”๊ฐ€ self-hosted ์„ค์น˜๋ฅผ ์‰ฝ๊ฒŒ ํ•œ๋‹ค.

Trap

Caddy๊ฐ€ app auth๋ฅผ ๋Œ€์‹ ํ•˜์ง€ ์•Š๋Š”๋‹ค.

Where

deploy/caddy/Caddyfile

Related
TLSreverse proxy
9. OpsBuilt

Demo isolation

ํฌํŠธํด๋ฆฌ์˜ค demo์™€ ์‹ค์ œ product DB๋ฅผ ๋ถ„๋ฆฌํ•œ๋‹ค.

The demo stack is isolated so public portfolio access never touches real operational data.

Deeper

demo compose๋Š” ๋ณ„๋„ project, volume, seed, demo login์„ ์‚ฌ์šฉํ•œ๋‹ค.

Why it matters

์‹ค์ œ ๊ณ ๊ฐ/์นœ๊ตฌ ๋ฐ์ดํ„ฐ๊ฐ€ demo์— ์„ž์ด๋ฉด ์•ˆ ๋œ๋‹ค.

Trap

demo login์„ production์— ์ผœ๋ฉด ๋ณด์•ˆ ์‚ฌ๊ณ ๋‹ค.

Where

docker-compose.demo.yml, DEPLOY.md

Related
seedvolume
9. OpsPartial

Backup and restore

๋‹จ์ผ ์„œ๋ฒ„ ์šด์˜์—์„œ ์‹ค์ œ ์ƒ์กด ์กฐ๊ฑด์ด๋‹ค.

For this architecture, backup and restore discipline matters more than pretending there is HA.

Deeper

DB dump์™€ vault blob ๋ฐฑ์—…์ด ํ•„์š”ํ•˜๊ณ  off-host restore drill์ด ์žˆ์–ด์•ผ ํ•œ๋‹ค.

Why it matters

HA๊ฐ€ ์—†์œผ๋ฉด backup/restore๊ฐ€ ๊ฐ€์žฅ ์ค‘์š”ํ•œ reliability story๋‹ค.

Trap

backup script ์กด์žฌ์™€ ๋ณต๊ตฌ ๊ฒ€์ฆ์€ ๋‹ค๋ฅด๋‹ค.

Where

deploy/backup, LIMITATIONS

Related
pg_dumprsync
9. OpsPartial

Code signing

Windows agent ์„ค์น˜ ๊ฒฝ๊ณ ๋ฅผ ์ค„์ด๋Š” ๋ฐฐํฌ ๋ฌธ์ œ๋‹ค.

Code signing is required to make Windows agent installation less scary for non-technical users.

Deeper

Authenticode ์ธ์ฆ์„œ๋กœ agent binary๋ฅผ ์„œ๋ช…ํ•ด์•ผ SmartScreen friction์ด ์ค„์–ด๋“ ๋‹ค.

Why it matters

๋น„์ „๋ฌธ ์‚ฌ์šฉ์ž๊ฐ€ ์„ค์น˜๋ฅผ ๋ฉˆ์ถ”์ง€ ์•Š๊ฒŒ ํ•˜๋Š” ์ œํ’ˆํ™” ๋‹จ๊ณ„๋‹ค.

Trap

self-signed cert๋กœ SmartScreen์„ ์—†์•จ ์ˆ˜ ์—†๋‹ค.

Where

Makefile sign-windows, CODE_SIGNING.md

Related
SmartScreenAuthenticode
10. LimitsRisk

No HA

๋‹จ์ผ ์„œ๋ฒ„๊ฐ€ ์ฃฝ์œผ๋ฉด ์ „์ฒด ์„œ๋น„์Šค๊ฐ€ ๋ฉˆ์ถ˜๋‹ค.

DocVault is a single-host system with no high-availability story yet.

Deeper

DB, server, vault, Caddy๊ฐ€ ํ•œ host์— ์žˆ์–ด์„œ failover๊ฐ€ ์—†๋‹ค.

Why it matters

์•„ํ‚คํ…์ฒ˜ ํ•œ๊ณ„๋ฅผ ์†”์งํžˆ ๋งํ•ด์•ผ ์‹ ๋ขฐ๊ฐ€ ์ƒ๊ธด๋‹ค.

Trap

Compose๋ฅผ ์ผ๋‹ค๊ณ  HA๊ฐ€ ๋˜๋Š” ๊ฑด ์•„๋‹ˆ๋‹ค.

Where

LIMITATIONS L-SCALE-2

Related
SPOFfailover
10. LimitsRisk

No kernel visibility

์ปค๋„ ๋“œ๋ผ์ด๋ฒ„๋‚˜ eBPF ๊ฐ€์‹œ์„ฑ์€ ์—†๋‹ค.

DocVault does not have kernel-level EDR visibility.

Deeper

osquery user-mode ๊ธฐ๋ฐ˜์ด๋ผ ์‹œ์Šคํ…œ์ฝœ ํ›„ํ‚น์ด๋‚˜ direct disk I/O ๊ฐ™์€ ๊ณต๊ฒฉ์€ ๋ชป ๋ณธ๋‹ค.

Why it matters

EDR์™€ ๋น„๊ตํ•  ๋•Œ ๋ฐ˜๋“œ์‹œ ๋งํ•ด์•ผ ํ•˜๋Š” ํ•œ๊ณ„๋‹ค.

Trap

EDR ๋Œ€์ฒดํ’ˆ์ด๋ผ๊ณ  ๋งํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.

Where

LIMITATIONS L-FUNC-3

Related
EDReBPF
10. LimitsMissing

No load test

์‹ค์ œ ๋ถ€ํ•˜ ์ฒ˜๋ฆฌ๋Ÿ‰์€ ์ธก์ •๋˜์ง€ ์•Š์•˜๋‹ค.

The honest answer is that throughput and p99 latency have not been load-tested yet.

Deeper

ํ…Œ์ŠคํŠธ๋Š” ํ†ต๊ณผํ•˜์ง€๋งŒ ๋™์‹œ agent POST, trigger overhead, GC, disk I/O๋Š” ์ˆ˜์น˜๊ฐ€ ์—†๋‹ค.

Why it matters

p95/p99 ์งˆ๋ฌธ์— ์ •์งํ•˜๊ฒŒ ๋‹ตํ•ด์•ผ ํ•œ๋‹ค.

Trap

์ˆซ์ž ์—†์ด ์ฒ˜๋ฆฌ๋Ÿ‰์„ ์ฃผ์žฅํ•˜์ง€ ๋ง๋ผ.

Where

LIMITATIONS L-SCALE-4

Related
p99load test
10. LimitsRisk

Limited observability

Prometheus/OpenTelemetry ๊ฐ™์€ metric/trace๋Š” ์—†๋‹ค.

The system has logs but not a full metrics and tracing stack.

Deeper

slog ๋กœ๊ทธ์™€ health endpoint๋Š” ์žˆ์ง€๋งŒ p95/p99, alerting, dashboard๋Š” ๋ถ€์กฑํ•˜๋‹ค.

Why it matters

์šด์˜ ์„ฑ์ˆ™๋„ ์งˆ๋ฌธ์—์„œ ๋น ์งˆ ์ˆ˜ ์—†๋Š” ํ•œ๊ณ„๋‹ค.

Trap

๋กœ๊ทธ๋ฅผ ๊ด€์ธก์„ฑ ์™„์„ฑ์œผ๋กœ ๋งํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.

Where

LIMITATIONS L-OPS-1

Related
metricstracing

Source map

์ด ํŽ˜์ด์ง€๊ฐ€ ์–ด๋–ค docvault ๋ฌธ์„œ/์ฝ”๋“œ์—์„œ ์™”๋Š”์ง€ ๊ธฐ์–ตํ•ด๋ผ.

Product README
docvault/README.md

Product definition, stack, quick start, honest non-goals

Architecture
docvault/docs/ARCHITECTURE.md

Topology, flows, core patterns, 5-minute script

Decisions
docvault/docs/DECISIONS.md

Why Go, Postgres-only, htmx, detection not prevention

Limitations
docvault/docs/LIMITATIONS.md

Security, scale, ops, UI, scope caveats

Beginner guide
docvault/docs/STUDY_GUIDE_BEGINNER.ko.md

Zero-jargon technology explanations

Server entry
docvault/cmd/server/main.go

Runtime wiring, schedulers, AI, shutdown

Router
docvault/internal/web/router.go

Auth, audit, CSRF, agent endpoints, protected pages

Endpoint domain
docvault/internal/endpoint

osquery, clipboard, heartbeat, enrollment, normalization

Vault domain
docvault/internal/vault

Envelope encryption and chunked AES-GCM

Infra
docvault/docker-compose.prod.yml + deploy

Compose, Caddy, migration, seed, backup, install