@wooojin/forgen 0.4.8 → 0.4.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/assets/dev-guide/be/README.md +226 -0
- package/assets/dev-guide/be/adapters/build-agents-md.sh +63 -0
- package/assets/dev-guide/be/principles/common.md +433 -0
- package/assets/dev-guide/be/principles/go.md +469 -0
- package/assets/dev-guide/be/principles/node.md +388 -0
- package/assets/dev-guide/be/skills/go/be-build/SKILL.md +262 -0
- package/assets/dev-guide/be/skills/go/be-perf/SKILL.md +308 -0
- package/assets/dev-guide/be/skills/go/be-review/SKILL.md +119 -0
- package/assets/dev-guide/be/skills/go/be-security/SKILL.md +362 -0
- package/assets/dev-guide/be/skills/node/be-build/SKILL.md +239 -0
- package/assets/dev-guide/be/skills/node/be-perf/SKILL.md +272 -0
- package/assets/dev-guide/be/skills/node/be-review/SKILL.md +118 -0
- package/assets/dev-guide/be/skills/node/be-security/SKILL.md +355 -0
- package/assets/dev-guide/be/sources/12factor/INDEX.md +53 -0
- package/assets/dev-guide/be/sources/api-design/INDEX.md +56 -0
- package/assets/dev-guide/be/sources/ddia/INDEX.md +55 -0
- package/assets/dev-guide/be/sources/go-runtime/INDEX.md +62 -0
- package/assets/dev-guide/be/sources/node-runtime/INDEX.md +60 -0
- package/assets/dev-guide/be/sources/otel/INDEX.md +53 -0
- package/assets/dev-guide/be/sources/owasp-api/INDEX.md +52 -0
- package/assets/dev-guide/be/sources/postgres/INDEX.md +55 -0
- package/assets/dev-guide/be/sources/sre-book/INDEX.md +48 -0
- package/assets/dev-guide/fe/README.md +197 -0
- package/assets/dev-guide/fe/adapters/build-agents-md.sh +63 -0
- package/assets/dev-guide/fe/adapters/refresh.sh +68 -0
- package/assets/dev-guide/fe/principles/common.md +160 -0
- package/assets/dev-guide/fe/principles/react.md +183 -0
- package/assets/dev-guide/fe/principles/vue.md +196 -0
- package/assets/dev-guide/fe/skills/react/fe-build/SKILL.md +139 -0
- package/assets/dev-guide/fe/skills/react/fe-perf/SKILL.md +179 -0
- package/assets/dev-guide/fe/skills/react/fe-review/SKILL.md +141 -0
- package/assets/dev-guide/fe/skills/vue/fe-build/SKILL.md +148 -0
- package/assets/dev-guide/fe/skills/vue/fe-perf/SKILL.md +163 -0
- package/assets/dev-guide/fe/skills/vue/fe-review/SKILL.md +136 -0
- package/assets/dev-guide/fe/sources/a11y-dx/INDEX.md +41 -0
- package/assets/dev-guide/fe/sources/a11y-dx/chrome-devtools-memory.md +150 -0
- package/assets/dev-guide/fe/sources/a11y-dx/chrome-devtools-performance.md +99 -0
- package/assets/dev-guide/fe/sources/a11y-dx/lighthouse-audits.md +146 -0
- package/assets/dev-guide/fe/sources/a11y-dx/react-devtools-profiler.md +128 -0
- package/assets/dev-guide/fe/sources/a11y-dx/wcag22-new-criteria.md +174 -0
- package/assets/dev-guide/fe/sources/perf/01-core-web-vitals.md +58 -0
- package/assets/dev-guide/fe/sources/perf/02-inp.md +83 -0
- package/assets/dev-guide/fe/sources/perf/03-lcp-cls.md +130 -0
- package/assets/dev-guide/fe/sources/perf/04-speculation-rules.md +148 -0
- package/assets/dev-guide/fe/sources/perf/05-view-transitions.md +153 -0
- package/assets/dev-guide/fe/sources/perf/06-nextjs-caching.md +188 -0
- package/assets/dev-guide/fe/sources/perf/07-server-components.md +181 -0
- package/assets/dev-guide/fe/sources/perf/08-ppr.md +133 -0
- package/assets/dev-guide/fe/sources/perf/09-nextjs-image.md +200 -0
- package/assets/dev-guide/fe/sources/perf/10-optimize-lcp.md +201 -0
- package/assets/dev-guide/fe/sources/perf/INDEX.md +88 -0
- package/assets/dev-guide/fe/sources/react/INDEX.md +41 -0
- package/assets/dev-guide/fe/sources/react/keeping-components-pure.md +135 -0
- package/assets/dev-guide/fe/sources/react/no-effect-patterns.md +183 -0
- package/assets/dev-guide/fe/sources/react/react-compiler.md +182 -0
- package/assets/dev-guide/fe/sources/react/server-components.md +194 -0
- package/assets/dev-guide/fe/sources/react/server-functions.md +192 -0
- package/assets/dev-guide/fe/sources/react/suspense.md +218 -0
- package/assets/dev-guide/fe/sources/react/use-action-state.md +123 -0
- package/assets/dev-guide/fe/sources/react/use-form-status.md +158 -0
- package/assets/dev-guide/fe/sources/react/use-hook.md +153 -0
- package/assets/dev-guide/fe/sources/react/use-optimistic.md +194 -0
- package/assets/dev-guide/fe/sources/toss-ff/INDEX.md +58 -0
- package/assets/dev-guide/fe/sources/toss-ff/cohesion-code-directory.md +79 -0
- package/assets/dev-guide/fe/sources/toss-ff/cohesion-form-fields.md +110 -0
- package/assets/dev-guide/fe/sources/toss-ff/cohesion-magic-number.md +47 -0
- package/assets/dev-guide/fe/sources/toss-ff/coupling-item-edit-modal.md +124 -0
- package/assets/dev-guide/fe/sources/toss-ff/coupling-use-bottom-sheet.md +57 -0
- package/assets/dev-guide/fe/sources/toss-ff/coupling-use-page-state.md +71 -0
- package/assets/dev-guide/fe/sources/toss-ff/overview-4-principles.md +77 -0
- package/assets/dev-guide/fe/sources/toss-ff/predictability-hidden-logic.md +59 -0
- package/assets/dev-guide/fe/sources/toss-ff/predictability-http.md +77 -0
- package/assets/dev-guide/fe/sources/toss-ff/predictability-use-user.md +110 -0
- package/assets/dev-guide/fe/sources/toss-ff/readability-comparison-order.md +52 -0
- package/assets/dev-guide/fe/sources/toss-ff/readability-condition-name.md +64 -0
- package/assets/dev-guide/fe/sources/toss-ff/readability-login-start-page.md +183 -0
- package/assets/dev-guide/fe/sources/toss-ff/readability-magic-number.md +53 -0
- package/assets/dev-guide/fe/sources/toss-ff/readability-submit-button.md +73 -0
- package/assets/dev-guide/fe/sources/toss-ff/readability-ternary-operator.md +38 -0
- package/assets/dev-guide/fe/sources/toss-ff/readability-use-page-state.md +77 -0
- package/assets/dev-guide/fe/sources/toss-ff/readability-user-policy.md +98 -0
- package/assets/dev-guide/fe/sources/vue/INDEX.md +17 -0
- package/assets/dev-guide/fe/sources/vue/composition-api.md +251 -0
- package/assets/dev-guide/fe/sources/vue/nuxt-data-fetching.md +232 -0
- package/assets/dev-guide/fe/sources/vue/pinia-state-management.md +134 -0
- package/assets/dev-guide/fe/sources/vue/reactivity-pitfalls.md +261 -0
- package/assets/dev-guide/fe/sources/vue/style-guide-priority-a.md +117 -0
- package/assets/dev-guide/fe/sources/vue/style-guide-priority-b.md +231 -0
- package/assets/dev-guide/fe/sources/vue/style-guide-priority-c.md +86 -0
- package/assets/dev-guide/fe/sources/vue/style-guide-priority-d.md +72 -0
- package/dist/cli.js +42 -0
- package/dist/core/dashboard-cli.d.ts +12 -0
- package/dist/core/dashboard-cli.js +226 -0
- package/dist/core/dev-guide-injector.d.ts +26 -0
- package/dist/core/dev-guide-injector.js +137 -0
- package/dist/core/init.js +53 -0
- package/dist/core/lifecycle-classifier.d.ts +23 -0
- package/dist/core/lifecycle-classifier.js +104 -0
- package/dist/core/observability-backfill.d.ts +31 -0
- package/dist/core/observability-backfill.js +178 -0
- package/dist/core/observability-store.d.ts +58 -0
- package/dist/core/observability-store.js +195 -0
- package/dist/core/session-store.js +4 -0
- package/dist/core/spawn.d.ts +17 -0
- package/dist/core/spawn.js +179 -2
- package/dist/core/statusline-cli.js +34 -1
- package/dist/engine/compound-extractor.js +39 -0
- package/dist/engine/compound-loop.js +6 -0
- package/dist/engine/compound-retire.d.ts +20 -0
- package/dist/engine/compound-retire.js +85 -0
- package/dist/hooks/context-guard.js +25 -1
- package/dist/hooks/post-tool-use.js +48 -0
- package/dist/hooks/solution-injector.js +93 -0
- package/dist/host/install-claude.d.ts +6 -2
- package/dist/host/install-claude.js +74 -2
- package/dist/host/install-codex.d.ts +4 -0
- package/dist/host/install-codex.js +71 -0
- package/dist/host/install-orchestrator.js +1 -0
- package/package.json +6 -6
- package/plugin.json +1 -1
- package/scripts/postinstall.js +134 -0
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: be-security-node
|
|
3
|
+
description: Node.js/TypeScript 서비스를 OWASP API Security Top 10 기준으로 진단. 카테고리별 체크리스트와 픽스 패턴을 제공한다.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# be-security (Node.js)
|
|
7
|
+
|
|
8
|
+
> **호출 시점**: "이 핸들러 보안 검토해줘", "OWASP 관점에서 체크해줘", "보안 감사 준비해줘".
|
|
9
|
+
> **선행 로딩**: `principles/common.md` (E섹션 Security Baseline) + `principles/node.md` 필수.
|
|
10
|
+
|
|
11
|
+
## 0. 절대 금지
|
|
12
|
+
|
|
13
|
+
1. "보안은 나중에" 금지 — 설계 단계부터 체크리스트 적용.
|
|
14
|
+
2. 보안 이슈를 [LOW]로 다운그레이드 금지 — OWASP Top 10은 모두 [HIGH].
|
|
15
|
+
3. 취약점 발견 후 "일단 배포" 금지 — 패치 후 배포.
|
|
16
|
+
|
|
17
|
+
## 1. 워크플로우
|
|
18
|
+
|
|
19
|
+
### Step 1 — 공격 표면 파악
|
|
20
|
+
|
|
21
|
+
```markdown
|
|
22
|
+
## 공격 표면 목록
|
|
23
|
+
- 공개 엔드포인트: GET /api/orders, POST /api/payments, ...
|
|
24
|
+
- 인증 필요: PUT /api/orders/:id, DELETE /api/...
|
|
25
|
+
- 관리자 전용: POST /api/admin/...
|
|
26
|
+
- 외부 입력: req.body, req.params, req.query, req.headers
|
|
27
|
+
- 파일 업로드: POST /api/uploads
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Step 2 — OWASP Top 10 순서로 진단
|
|
31
|
+
|
|
32
|
+
각 카테고리를 순서대로 실행. 발견 즉시 기록.
|
|
33
|
+
|
|
34
|
+
### Step 3 — 취약점 보고
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
[HIGH] src/orders/order.controller.ts:42 — API1: 소유권 검증 없음, req.user.id vs params.userId 비교 누락
|
|
38
|
+
[HIGH] src/auth/auth.controller.ts:88 — API6: 로그인 엔드포인트에 rate limit 없음
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Step 4 — 픽스 + 검증
|
|
42
|
+
|
|
43
|
+
픽스 후 해당 패턴 재검증. 테스트 케이스 추가 권장.
|
|
44
|
+
|
|
45
|
+
## 2. OWASP API Top 10 체크리스트 (2023)
|
|
46
|
+
|
|
47
|
+
### API1 — Broken Object Level Authorization
|
|
48
|
+
|
|
49
|
+
**"내 리소스만 접근 가능한가?"**
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// WRONG: URL params userId를 그대로 신뢰
|
|
53
|
+
app.get('/api/orders/:orderId', async (req, res) => {
|
|
54
|
+
const order = await orderRepo.findById(req.params.orderId);
|
|
55
|
+
res.json(order); // 다른 유저 주문도 접근 가능!
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// RIGHT: 요청자 소유권 확인
|
|
59
|
+
app.get('/api/orders/:orderId', authenticate, async (req, res) => {
|
|
60
|
+
const order = await orderRepo.findById(req.params.orderId);
|
|
61
|
+
if (!order) return res.status(404).json({ error: { code: 'NOT_FOUND' } });
|
|
62
|
+
if (order.userId !== req.user.id) { // 소유권 검증 필수
|
|
63
|
+
return res.status(403).json({ error: { code: 'FORBIDDEN' } });
|
|
64
|
+
}
|
|
65
|
+
res.json(order);
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
체크:
|
|
70
|
+
```
|
|
71
|
+
[ ] 모든 리소스 접근에 소유권 검증 존재
|
|
72
|
+
[ ] JWT에서 userId 추출 (req.params.userId 신뢰 금지)
|
|
73
|
+
[ ] 관리자 우회 경로에도 권한 검증
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### API2 — Broken Authentication
|
|
77
|
+
|
|
78
|
+
**"토큰이 진짜인가? 만료됐는가?"**
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import jwt from 'jsonwebtoken';
|
|
82
|
+
|
|
83
|
+
// WRONG: 알고리즘 명시 안 함 (none 알고리즘 공격 위험)
|
|
84
|
+
jwt.verify(token, secret);
|
|
85
|
+
|
|
86
|
+
// RIGHT: 알고리즘 명시
|
|
87
|
+
jwt.verify(token, process.env.JWT_PUBLIC_KEY!, {
|
|
88
|
+
algorithms: ['RS256'], // HS256도 가능하지만 RS256 권장 (비대칭)
|
|
89
|
+
issuer: 'auth.example.com',
|
|
90
|
+
audience: 'api.example.com',
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
체크:
|
|
95
|
+
```
|
|
96
|
+
[ ] JWT 알고리즘 명시 (algorithms: ['RS256'])
|
|
97
|
+
[ ] 토큰 만료 검증 (exp claim)
|
|
98
|
+
[ ] 시크릿/키가 env에서 로드 (하드코딩 금지)
|
|
99
|
+
[ ] Refresh token rotation 구현 (refresh 후 구 토큰 무효화)
|
|
100
|
+
[ ] 로그아웃 시 토큰 블랙리스트 또는 단기 만료
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### API3 — Broken Object Property Level Authorization
|
|
104
|
+
|
|
105
|
+
**"응답에 불필요한 필드가 포함되는가?"**
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
// WRONG: DB 모델 그대로 반환
|
|
109
|
+
const user = await prisma.user.findUnique({ where: { id } });
|
|
110
|
+
res.json(user); // password hash, internal flags 등 노출!
|
|
111
|
+
|
|
112
|
+
// RIGHT: allowlist projection
|
|
113
|
+
const user = await prisma.user.findUnique({
|
|
114
|
+
where: { id },
|
|
115
|
+
select: { id: true, name: true, email: true }, // 필요한 것만
|
|
116
|
+
});
|
|
117
|
+
res.json(user);
|
|
118
|
+
|
|
119
|
+
// 또는 직렬화 레이어
|
|
120
|
+
function serializeUser(user: User): PublicUser {
|
|
121
|
+
const { passwordHash, internalFlags, ...publicFields } = user;
|
|
122
|
+
return publicFields;
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
체크:
|
|
127
|
+
```
|
|
128
|
+
[ ] 응답 스키마 allowlist 정의 (전체 모델 반환 금지)
|
|
129
|
+
[ ] password, hash, secret, internal 필드 응답 제외
|
|
130
|
+
[ ] mass assignment 방지 (req.body를 DB에 spread 금지)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### API4 — Unrestricted Resource Consumption
|
|
134
|
+
|
|
135
|
+
**"무한 요청/대용량 페이로드를 막는가?"**
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
import rateLimit from 'express-rate-limit';
|
|
139
|
+
|
|
140
|
+
// Rate limiting
|
|
141
|
+
const limiter = rateLimit({
|
|
142
|
+
windowMs: 15 * 60 * 1000, // 15분
|
|
143
|
+
max: 100, // 최대 100 요청
|
|
144
|
+
standardHeaders: true,
|
|
145
|
+
legacyHeaders: false,
|
|
146
|
+
handler: (req, res) => {
|
|
147
|
+
res.status(429).json({
|
|
148
|
+
error: { code: 'TOO_MANY_REQUESTS', message: '요청 한도 초과' },
|
|
149
|
+
});
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// 페이로드 크기 제한
|
|
154
|
+
app.use(express.json({ limit: '1mb' }));
|
|
155
|
+
app.use(express.urlencoded({ extended: true, limit: '1mb' }));
|
|
156
|
+
|
|
157
|
+
// 파일 업로드 크기 제한
|
|
158
|
+
import multer from 'multer';
|
|
159
|
+
const upload = multer({ limits: { fileSize: 10 * 1024 * 1024 } }); // 10MB
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
체크:
|
|
163
|
+
```
|
|
164
|
+
[ ] Rate limiting — 전역 + 민감 엔드포인트별 강화
|
|
165
|
+
[ ] Request body 크기 제한 (1MB 이하 권장)
|
|
166
|
+
[ ] 파일 업로드 크기 제한
|
|
167
|
+
[ ] 페이지네이션 limit 상한 (limit=10000 같은 무한 요청 방지)
|
|
168
|
+
[ ] Retry-After 헤더 (429 응답 시)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### API5 — Broken Function Level Authorization
|
|
172
|
+
|
|
173
|
+
**"관리자 기능을 일반 유저가 호출할 수 없는가?"**
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
// 역할 기반 미들웨어
|
|
177
|
+
function requireRole(...roles: string[]) {
|
|
178
|
+
return (req: Request, res: Response, next: NextFunction) => {
|
|
179
|
+
if (!roles.includes(req.user.role)) {
|
|
180
|
+
return res.status(403).json({ error: { code: 'FORBIDDEN' } });
|
|
181
|
+
}
|
|
182
|
+
next();
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
app.delete('/api/admin/users/:id', authenticate, requireRole('admin'), deleteUser);
|
|
187
|
+
app.get('/api/admin/stats', authenticate, requireRole('admin', 'analyst'), getStats);
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
체크:
|
|
191
|
+
```
|
|
192
|
+
[ ] 관리자 엔드포인트 별도 인가 미들웨어
|
|
193
|
+
[ ] HTTP 메서드별 권한 분리 (GET vs DELETE 다른 권한)
|
|
194
|
+
[ ] 숨겨진 관리자 경로 (/api/internal, /debug) 외부 노출 여부
|
|
195
|
+
[ ] 권한 검사를 비즈니스 로직 내부에도 (미들웨어 우회 가능성 고려)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### API6 — Unrestricted Access to Sensitive Flows
|
|
199
|
+
|
|
200
|
+
**"로그인/OTP/비밀번호 재설정에 무차별 대입 방어가 있는가?"**
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
// 로그인 전용 강화 rate limit
|
|
204
|
+
const authLimiter = rateLimit({
|
|
205
|
+
windowMs: 15 * 60 * 1000,
|
|
206
|
+
max: 10, // 15분에 10회
|
|
207
|
+
skipSuccessfulRequests: true,
|
|
208
|
+
keyGenerator: (req) => req.ip + ':' + req.body?.email, // IP + 이메일 조합
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
app.post('/api/auth/login', authLimiter, loginHandler);
|
|
212
|
+
app.post('/api/auth/forgot-password', authLimiter, forgotPasswordHandler);
|
|
213
|
+
|
|
214
|
+
// 계정 잠금 (DB에서 실패 횟수 추적)
|
|
215
|
+
async function loginHandler(req: Request, res: Response) {
|
|
216
|
+
const user = await userRepo.findByEmail(req.body.email);
|
|
217
|
+
if (user && user.failedAttempts >= 5 && user.lockedUntil > new Date()) {
|
|
218
|
+
return res.status(429).json({ error: { code: 'ACCOUNT_LOCKED' } });
|
|
219
|
+
}
|
|
220
|
+
// ...
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
체크:
|
|
225
|
+
```
|
|
226
|
+
[ ] 로그인 엔드포인트 rate limit (IP + 이메일 조합)
|
|
227
|
+
[ ] OTP/인증코드 rate limit
|
|
228
|
+
[ ] 계정 잠금 정책 (N회 실패 → 잠금)
|
|
229
|
+
[ ] 비밀번호 재설정 토큰 단기 만료 (15분)
|
|
230
|
+
[ ] 비밀번호 재설정 토큰 1회 사용 후 무효화
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### API7 — Server Side Request Forgery (SSRF)
|
|
234
|
+
|
|
235
|
+
**"사용자가 지정한 URL로 서버가 요청을 보내는가?"**
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
import { URL } from 'node:url';
|
|
239
|
+
|
|
240
|
+
const ALLOWED_HOSTS = new Set(['api.trustedpartner.com', 'webhooks.example.com']);
|
|
241
|
+
|
|
242
|
+
function validateWebhookUrl(url: string): boolean {
|
|
243
|
+
try {
|
|
244
|
+
const parsed = new URL(url);
|
|
245
|
+
if (!['https:'].includes(parsed.protocol)) return false;
|
|
246
|
+
if (!ALLOWED_HOSTS.has(parsed.hostname)) return false;
|
|
247
|
+
// private IP 차단
|
|
248
|
+
const ip = await resolveHostname(parsed.hostname);
|
|
249
|
+
if (isPrivateIP(ip)) return false;
|
|
250
|
+
return true;
|
|
251
|
+
} catch {
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
체크:
|
|
258
|
+
```
|
|
259
|
+
[ ] 사용자 입력 URL fetch 전 allowlist 검증
|
|
260
|
+
[ ] private IP (10.x, 172.16.x, 192.168.x, 127.x) 접근 차단
|
|
261
|
+
[ ] protocol 검증 (https만 허용)
|
|
262
|
+
[ ] redirect follow 제한
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### API8 — Security Misconfiguration
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
// Helmet.js — 보안 헤더 자동 설정
|
|
269
|
+
import helmet from 'helmet';
|
|
270
|
+
app.use(helmet()); // CSP, HSTS, X-Frame-Options 등
|
|
271
|
+
|
|
272
|
+
// CORS — allowlist 기반
|
|
273
|
+
import cors from 'cors';
|
|
274
|
+
app.use(cors({
|
|
275
|
+
origin: ['https://app.example.com', 'https://admin.example.com'],
|
|
276
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE'],
|
|
277
|
+
credentials: true,
|
|
278
|
+
}));
|
|
279
|
+
|
|
280
|
+
// 개발 전용 엔드포인트 프로덕션 노출 금지
|
|
281
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
282
|
+
app.get('/debug/health-detail', debugHandler);
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
체크:
|
|
287
|
+
```
|
|
288
|
+
[ ] CORS origin이 * 아님 (allowlist)
|
|
289
|
+
[ ] Helmet.js 또는 동등한 보안 헤더
|
|
290
|
+
[ ] 스택 trace가 에러 응답에 포함되지 않음 (production)
|
|
291
|
+
[ ] 디버그/내부 엔드포인트 프로덕션 비활성화
|
|
292
|
+
[ ] 불필요한 HTTP 메서드 비활성화
|
|
293
|
+
[ ] X-Powered-By 헤더 제거 (프레임워크 노출)
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### API9 — Improper Inventory Management
|
|
297
|
+
|
|
298
|
+
```
|
|
299
|
+
[ ] API 버전 목록 문서화 (deprecated 포함)
|
|
300
|
+
[ ] 구 버전 /v0, /v1 폐기 계획 및 Sunset 날짜
|
|
301
|
+
[ ] 스테이징/개발 엔드포인트 인터넷 노출 여부
|
|
302
|
+
[ ] API 게이트웨이에서 활성 엔드포인트 목록 관리
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### API10 — Unsafe Consumption of APIs
|
|
306
|
+
|
|
307
|
+
**"외부 API 응답을 그대로 신뢰하는가?"**
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
// WRONG: 외부 응답 신뢰
|
|
311
|
+
const externalData = await fetch(externalApiUrl).then(r => r.json());
|
|
312
|
+
await db.insert(externalData); // 외부 데이터를 검증 없이 삽입!
|
|
313
|
+
|
|
314
|
+
// RIGHT: 외부 응답도 Zod로 검증
|
|
315
|
+
const ExternalResponseSchema = z.object({
|
|
316
|
+
id: z.string(),
|
|
317
|
+
amount: z.number().positive(),
|
|
318
|
+
status: z.enum(['pending', 'completed', 'failed']),
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
const raw = await fetch(externalApiUrl).then(r => r.json());
|
|
322
|
+
const validated = ExternalResponseSchema.parse(raw); // 검증 후 사용
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
체크:
|
|
326
|
+
```
|
|
327
|
+
[ ] 외부 API 응답 스키마 검증 (Zod 등)
|
|
328
|
+
[ ] 외부 API 타임아웃 설정
|
|
329
|
+
[ ] 외부 API 실패 시 fallback 또는 에러 전파
|
|
330
|
+
[ ] 외부 API SSL 인증서 검증 (rejectUnauthorized: false 금지)
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## 3. 출력 형식
|
|
334
|
+
|
|
335
|
+
```
|
|
336
|
+
## 보안 감사 결과
|
|
337
|
+
|
|
338
|
+
### 공격 표면: N개 엔드포인트
|
|
339
|
+
|
|
340
|
+
### 발견된 취약점
|
|
341
|
+
[HIGH] API1 src/orders/order.controller.ts:42 — 소유권 검증 없음
|
|
342
|
+
[HIGH] API6 src/auth/auth.controller.ts:15 — 로그인 rate limit 없음
|
|
343
|
+
|
|
344
|
+
### 통과한 항목
|
|
345
|
+
- API2: JWT RS256 + 만료 검증 ✅
|
|
346
|
+
- API4: Rate limit (전역 100/15min) ✅
|
|
347
|
+
|
|
348
|
+
### 권고 사항
|
|
349
|
+
- API8: helmet.js 미적용 → 즉시 적용 권장
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
## 4. 관련 문서
|
|
353
|
+
|
|
354
|
+
- 원칙: [`principles/common.md`](../../../principles/common.md) E섹션
|
|
355
|
+
- 코퍼스: `sources/owasp-api/`
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 12-Factor App 문서 인덱스
|
|
3
|
+
fetched: 예정 (2026-05-18 스캐폴드)
|
|
4
|
+
license: CC BY 4.0 (https://12factor.net)
|
|
5
|
+
priority: 1 (출처 우선순위 최상위)
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 12-Factor App
|
|
9
|
+
|
|
10
|
+
> 클라우드 네이티브 애플리케이션을 위한 12가지 방법론.
|
|
11
|
+
> 이식성, 운영 안정성, 스케일 아웃 설계의 기준.
|
|
12
|
+
|
|
13
|
+
## 출처
|
|
14
|
+
|
|
15
|
+
| URL | 설명 |
|
|
16
|
+
|-----|------|
|
|
17
|
+
| https://12factor.net/ko/ | 한국어 공식 번역 |
|
|
18
|
+
| https://12factor.net/ | 영문 원본 |
|
|
19
|
+
|
|
20
|
+
## 라이선스
|
|
21
|
+
|
|
22
|
+
Creative Commons Attribution 4.0 (CC BY 4.0)
|
|
23
|
+
|
|
24
|
+
## 수집일
|
|
25
|
+
|
|
26
|
+
예정 (2026-05-18 스캐폴드)
|
|
27
|
+
|
|
28
|
+
## 참조 우선순위
|
|
29
|
+
|
|
30
|
+
1 (common.md 출처 우선순위 최상위)
|
|
31
|
+
|
|
32
|
+
## 문서 목록 (수집 예정)
|
|
33
|
+
|
|
34
|
+
| 파일명 (예정) | Factor | 제목 |
|
|
35
|
+
|--------------|--------|------|
|
|
36
|
+
| 01-codebase.md | I | Codebase — 하나의 코드베이스, 다수 배포 |
|
|
37
|
+
| 02-dependencies.md | II | Dependencies — 의존성 명시 및 격리 |
|
|
38
|
+
| 03-config.md | III | Config — 환경변수에 설정 저장 |
|
|
39
|
+
| 04-backing-services.md | IV | Backing Services — 부착된 리소스로 취급 |
|
|
40
|
+
| 05-build-release-run.md | V | Build/Release/Run — 엄격한 단계 분리 |
|
|
41
|
+
| 06-processes.md | VI | Processes — 무상태(stateless) 프로세스 |
|
|
42
|
+
| 07-port-binding.md | VII | Port Binding — 포트 바인딩으로 서비스 노출 |
|
|
43
|
+
| 08-concurrency.md | VIII | Concurrency — 프로세스 모델로 스케일 아웃 |
|
|
44
|
+
| 09-disposability.md | IX | Disposability — 빠른 시작 + 우아한 종료 |
|
|
45
|
+
| 10-dev-prod-parity.md | X | Dev/Prod Parity — 개발/스테이징/프로덕션 일관성 |
|
|
46
|
+
| 11-logs.md | XI | Logs — 이벤트 스트림으로 취급 (stdout) |
|
|
47
|
+
| 12-admin-processes.md | XII | Admin Processes — 일회성 프로세스 실행 |
|
|
48
|
+
|
|
49
|
+
## 핵심 참조 원칙 (principles/common.md 연결)
|
|
50
|
+
|
|
51
|
+
- Factor III (Config) → Security E.3 비밀 관리 (env 기반)
|
|
52
|
+
- Factor IX (Disposability) → Node N2 graceful shutdown
|
|
53
|
+
- Factor XI (Logs) → Observability C.1 구조화 로그 (stdout 출력)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: API 설계 가이드 문서 인덱스
|
|
3
|
+
fetched: 예정 (2026-05-18 스캐폴드)
|
|
4
|
+
license: 복합 (항목별 명시)
|
|
5
|
+
priority: 6 (출처 우선순위)
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# API 설계 — Stripe API + GitHub API + Google AIP
|
|
9
|
+
|
|
10
|
+
> 실전 API 설계 기준. Stripe(결제), GitHub(개발자 API), Google AIP(대규모 API 표준).
|
|
11
|
+
|
|
12
|
+
## 출처
|
|
13
|
+
|
|
14
|
+
| URL | 설명 | 라이선스 |
|
|
15
|
+
|-----|------|----------|
|
|
16
|
+
| https://stripe.com/docs/api | Stripe API Reference | Stripe 저작권 (공개 문서) |
|
|
17
|
+
| https://docs.github.com/en/rest | GitHub REST API | CC BY 4.0 |
|
|
18
|
+
| https://google.aip.dev/ | Google API Improvement Proposals | Apache-2.0 |
|
|
19
|
+
| https://opensource.google/documentation/reference/thirdparty/licenses | Google 오픈소스 라이선스 | — |
|
|
20
|
+
|
|
21
|
+
## 라이선스
|
|
22
|
+
|
|
23
|
+
- Stripe 문서: 공개 참조 가능, 재배포 금지
|
|
24
|
+
- GitHub 문서: CC BY 4.0
|
|
25
|
+
- Google AIP: Apache-2.0
|
|
26
|
+
|
|
27
|
+
## 수집일
|
|
28
|
+
|
|
29
|
+
예정 (2026-05-18 스캐폴드)
|
|
30
|
+
|
|
31
|
+
## 참조 우선순위
|
|
32
|
+
|
|
33
|
+
6 (common.md 출처 우선순위)
|
|
34
|
+
|
|
35
|
+
## 문서 목록 (수집 예정)
|
|
36
|
+
|
|
37
|
+
| 파일명 (예정) | 출처 | 주제 |
|
|
38
|
+
|--------------|------|------|
|
|
39
|
+
| stripe-pagination.md | Stripe | 커서 기반 페이지네이션 |
|
|
40
|
+
| stripe-idempotency.md | Stripe | Idempotency-Key 멱등성 패턴 |
|
|
41
|
+
| stripe-errors.md | Stripe | 구조화 에러 응답 (code/type/param) |
|
|
42
|
+
| stripe-versioning.md | Stripe | API 버전 관리 (날짜 기반) |
|
|
43
|
+
| github-rest-conventions.md | GitHub | RESTful 리소스 명명 규칙 |
|
|
44
|
+
| github-pagination.md | GitHub | Link 헤더 기반 페이지네이션 |
|
|
45
|
+
| aip-0121-resource-names.md | Google AIP-121 | 리소스 이름 표준 |
|
|
46
|
+
| aip-0131-standard-methods.md | Google AIP-131 | 표준 메서드 (List/Get/Create/...) |
|
|
47
|
+
| aip-0180-backwards-compat.md | Google AIP-180 | 하위 호환성 정책 |
|
|
48
|
+
| aip-0193-errors.md | Google AIP-193 | 에러 모델 표준 |
|
|
49
|
+
|
|
50
|
+
## 핵심 참조 원칙 (principles/common.md 연결)
|
|
51
|
+
|
|
52
|
+
- Stripe 에러 → Error Model B.1 구조화 에러
|
|
53
|
+
- Stripe 멱등성 → Idempotency D.1 Idempotency-Key
|
|
54
|
+
- GitHub 명명 → API 설계 A.2 일관성 (복수형 명사)
|
|
55
|
+
- Google AIP-180 → API 설계 A.4 진화가능성 (하위 호환)
|
|
56
|
+
- Google AIP-193 → Error Model B.2 4xx/5xx 경계
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: DDIA (Designing Data-Intensive Applications) 문서 인덱스
|
|
3
|
+
fetched: 예정 (2026-05-18 스캐폴드)
|
|
4
|
+
license: O'Reilly 저작권 — 공개 발췌 없음. 요약/원칙만 수록
|
|
5
|
+
priority: 5 (출처 우선순위)
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Designing Data-Intensive Applications — Martin Kleppmann
|
|
9
|
+
|
|
10
|
+
> 데이터 집약적 애플리케이션 설계. 복제, 파티셔닝, 트랜잭션, 분산 시스템 기초.
|
|
11
|
+
|
|
12
|
+
## 출처
|
|
13
|
+
|
|
14
|
+
| URL | 설명 |
|
|
15
|
+
|-----|------|
|
|
16
|
+
| https://dataintensive.net/ | 공식 사이트 |
|
|
17
|
+
| https://www.oreilly.com/library/view/designing-data-intensive/9781491903063/ | O'Reilly |
|
|
18
|
+
| https://github.com/ept/ddia-references | 챕터별 참조 논문 |
|
|
19
|
+
|
|
20
|
+
## 라이선스
|
|
21
|
+
|
|
22
|
+
O'Reilly 저작권 보호 도서. 직접 텍스트 수록 불가.
|
|
23
|
+
이 sources 디렉토리에는 **원칙 요약과 핵심 패턴만** 기록. 원문은 도서 구매 필요.
|
|
24
|
+
|
|
25
|
+
## 수집일
|
|
26
|
+
|
|
27
|
+
예정 (2026-05-18 스캐폴드)
|
|
28
|
+
|
|
29
|
+
## 참조 우선순위
|
|
30
|
+
|
|
31
|
+
5 (common.md 출처 우선순위)
|
|
32
|
+
|
|
33
|
+
## 문서 목록 (원칙 요약 예정 — 원문 미포함)
|
|
34
|
+
|
|
35
|
+
| 파일명 (예정) | 챕터 | 주제 |
|
|
36
|
+
|--------------|------|------|
|
|
37
|
+
| ch01-foundations.md | 1 | 신뢰성·확장성·유지보수성 정의 |
|
|
38
|
+
| ch02-data-models.md | 2 | 관계형 vs 문서 vs 그래프 |
|
|
39
|
+
| ch03-storage-retrieval.md | 3 | 인덱스 구조 (B-Tree, LSM) |
|
|
40
|
+
| ch04-encoding.md | 4 | 인코딩/스키마 진화 (Avro, Protobuf) |
|
|
41
|
+
| ch05-replication.md | 5 | 복제 — 리더/팔로워, 동기/비동기 |
|
|
42
|
+
| ch06-partitioning.md | 6 | 파티셔닝 (샤딩) |
|
|
43
|
+
| ch07-transactions.md | 7 | 트랜잭션 격리 수준, ACID vs BASE |
|
|
44
|
+
| ch08-trouble.md | 8 | 분산 시스템의 문제 (시계, 네트워크) |
|
|
45
|
+
| ch09-consistency.md | 9 | 일관성과 합의 (Linearizability, Paxos, Raft) |
|
|
46
|
+
| ch10-batch.md | 10 | 배치 처리 (MapReduce) |
|
|
47
|
+
| ch11-stream.md | 11 | 스트림 처리 (Kafka, 이벤트 소싱) |
|
|
48
|
+
| ch12-future.md | 12 | 데이터 시스템의 미래 |
|
|
49
|
+
|
|
50
|
+
## 핵심 참조 원칙 (principles/common.md 연결)
|
|
51
|
+
|
|
52
|
+
- Ch7 (Transactions) → DB G.1 트랜잭션 경계
|
|
53
|
+
- Ch4 (Schema Evolution) → DB G.2 Expand/Contract 마이그레이션
|
|
54
|
+
- Ch3 (Indexes) → DB G.3 인덱스 의도 주석
|
|
55
|
+
- Ch5 (Replication Lag) → 분산 시스템 일관성 주의사항
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Go 런타임 성능/진단 문서 인덱스
|
|
3
|
+
fetched: 예정 (2026-05-18 스캐폴드)
|
|
4
|
+
license: BSD-3-Clause (Go 공식) + 각 출처별
|
|
5
|
+
priority: 6 (출처 우선순위)
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Go 런타임 — 공식 문서 + Effective Go + 성능 가이드
|
|
9
|
+
|
|
10
|
+
> Go 스케줄러, 메모리 모델, GC, pprof 진단, goroutine 패턴.
|
|
11
|
+
|
|
12
|
+
## 출처
|
|
13
|
+
|
|
14
|
+
| URL | 설명 | 라이선스 |
|
|
15
|
+
|-----|------|----------|
|
|
16
|
+
| https://go.dev/doc/effective_go | Effective Go | BSD-3-Clause |
|
|
17
|
+
| https://go.dev/ref/spec | Go Language Specification | BSD-3-Clause |
|
|
18
|
+
| https://go.dev/doc/diagnostics | Diagnostics 가이드 | BSD-3-Clause |
|
|
19
|
+
| https://go.dev/blog/pprof | pprof 프로파일링 | BSD-3-Clause |
|
|
20
|
+
| https://go.dev/doc/gc-guide | GC 가이드 | BSD-3-Clause |
|
|
21
|
+
| https://go.dev/blog/concurrency-timeouts | Timeouts/Cancellation | BSD-3-Clause |
|
|
22
|
+
| https://github.com/dgryski/go-perfbook | Go 성능 최적화 북 | — |
|
|
23
|
+
| https://pkg.go.dev/golang.org/x/sync/errgroup | errgroup | BSD-3-Clause |
|
|
24
|
+
| https://go.dev/blog/race-detector | Race Detector | BSD-3-Clause |
|
|
25
|
+
| https://golangci-lint.run/ | golangci-lint | GPL-3.0 |
|
|
26
|
+
|
|
27
|
+
## 라이선스
|
|
28
|
+
|
|
29
|
+
BSD-3-Clause (Go 공식 문서)
|
|
30
|
+
|
|
31
|
+
## 수집일
|
|
32
|
+
|
|
33
|
+
예정 (2026-05-18 스캐폴드)
|
|
34
|
+
|
|
35
|
+
## 참조 우선순위
|
|
36
|
+
|
|
37
|
+
6 (common.md 출처 우선순위)
|
|
38
|
+
|
|
39
|
+
## 문서 목록 (수집 예정)
|
|
40
|
+
|
|
41
|
+
| 파일명 (예정) | 출처 | 주제 |
|
|
42
|
+
|--------------|------|------|
|
|
43
|
+
| effective-go.md | Effective Go | Go 관용 표현, 에러, 인터페이스 |
|
|
44
|
+
| scheduler.md | Go 공식 | GMP 스케줄러 동작 원리 |
|
|
45
|
+
| gc-guide.md | Go 공식 | GC 파라미터 (GOGC, GOMEMLIMIT) |
|
|
46
|
+
| pprof.md | Go 공식 | CPU / 메모리 / goroutine 프로파일 |
|
|
47
|
+
| race-detector.md | Go 공식 | -race 플래그, 레이스 컨디션 탐지 |
|
|
48
|
+
| memory-model.md | Go 공식 | Happens-before, sync 보장 |
|
|
49
|
+
| goroutine-patterns.md | 참조 | goroutine 생명주기 패턴 |
|
|
50
|
+
| context-patterns.md | 참조 | context.Context 전파 패턴 |
|
|
51
|
+
| errgroup.md | golang.org/x | errgroup 사용법 |
|
|
52
|
+
| golangci-lint-config.md | golangci-lint | .golangci.yml 권장 설정 |
|
|
53
|
+
| go-perf-book-summary.md | go-perfbook | 핵심 최적화 패턴 요약 |
|
|
54
|
+
|
|
55
|
+
## 핵심 참조 원칙 (principles/go.md 연결)
|
|
56
|
+
|
|
57
|
+
- Effective Go 에러 패턴 → G1 에러는 값
|
|
58
|
+
- context 패턴 → G2 context 전파
|
|
59
|
+
- goroutine 패턴 → G3 goroutine 생명주기
|
|
60
|
+
- pprof → be-perf Go 진단 절차
|
|
61
|
+
- gc-guide → be-perf GC pause 카테고리
|
|
62
|
+
- golangci-lint → G7 정적 분석
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Node.js 런타임 성능/진단 문서 인덱스
|
|
3
|
+
fetched: 예정 (2026-05-18 스캐폴드)
|
|
4
|
+
license: MIT (Node.js docs: https://github.com/nodejs/node/blob/main/LICENSE)
|
|
5
|
+
priority: 6 (출처 우선순위)
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Node.js 런타임 — 공식 문서 + Fastify + NestJS
|
|
9
|
+
|
|
10
|
+
> Event Loop, 메모리, 스트림, 성능 진단, 프레임워크 패턴.
|
|
11
|
+
|
|
12
|
+
## 출처
|
|
13
|
+
|
|
14
|
+
| URL | 설명 | 라이선스 |
|
|
15
|
+
|-----|------|----------|
|
|
16
|
+
| https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick | Event Loop 가이드 | MIT |
|
|
17
|
+
| https://nodejs.org/en/docs/guides/dont-block-the-event-loop | Event Loop 차단 방지 | MIT |
|
|
18
|
+
| https://nodejs.org/api/stream.html | Streams API | MIT |
|
|
19
|
+
| https://nodejs.org/api/worker_threads.html | Worker Threads | MIT |
|
|
20
|
+
| https://clinic.js.org/ | Clinic.js 진단 도구 | MIT |
|
|
21
|
+
| https://www.fastify.io/docs/latest/ | Fastify 공식 문서 | MIT |
|
|
22
|
+
| https://docs.nestjs.com/ | NestJS 공식 문서 | MIT |
|
|
23
|
+
| https://pino.js.org/ | Pino 로거 | MIT |
|
|
24
|
+
| https://github.com/nicolo-ribaudo/tc39-proposal-async-context | Async Context 제안 | — |
|
|
25
|
+
|
|
26
|
+
## 라이선스
|
|
27
|
+
|
|
28
|
+
MIT (Node.js, Fastify, Pino) / MIT (NestJS)
|
|
29
|
+
|
|
30
|
+
## 수집일
|
|
31
|
+
|
|
32
|
+
예정 (2026-05-18 스캐폴드)
|
|
33
|
+
|
|
34
|
+
## 참조 우선순위
|
|
35
|
+
|
|
36
|
+
6 (common.md 출처 우선순위)
|
|
37
|
+
|
|
38
|
+
## 문서 목록 (수집 예정)
|
|
39
|
+
|
|
40
|
+
| 파일명 (예정) | 출처 | 주제 |
|
|
41
|
+
|--------------|------|------|
|
|
42
|
+
| event-loop.md | Node.js | Event Loop 상세 (phases, timers) |
|
|
43
|
+
| dont-block.md | Node.js | Event Loop 차단 패턴과 해결 |
|
|
44
|
+
| streams.md | Node.js | Readable/Writable/Transform + backpressure |
|
|
45
|
+
| worker-threads.md | Node.js | CPU 병렬화 (worker_threads) |
|
|
46
|
+
| diagnostic-report.md | Node.js | 진단 리포트 생성 |
|
|
47
|
+
| clinic-setup.md | Clinic.js | Doctor / Flame / Heap profiler |
|
|
48
|
+
| fastify-lifecycle.md | Fastify | Request 생명주기 (hooks) |
|
|
49
|
+
| fastify-schema-validation.md | Fastify | JSON Schema 기반 입력 검증 |
|
|
50
|
+
| nestjs-modules.md | NestJS | 모듈/DI 패턴 |
|
|
51
|
+
| nestjs-interceptors.md | NestJS | 인터셉터 (로깅, 캐싱, 변환) |
|
|
52
|
+
| pino-setup.md | Pino | 구조화 로그 설정 (redact, transport) |
|
|
53
|
+
|
|
54
|
+
## 핵심 참조 원칙 (principles/node.md 연결)
|
|
55
|
+
|
|
56
|
+
- Event Loop 가이드 → N3 Event Loop 차단 금지
|
|
57
|
+
- Worker Threads → N3.2 CPU Heavy 격리
|
|
58
|
+
- Streams → N4 Backpressure
|
|
59
|
+
- Clinic.js → be-perf 진단 절차
|
|
60
|
+
- Pino → N8 구조화 로그
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: OpenTelemetry 문서 인덱스
|
|
3
|
+
fetched: 예정 (2026-05-18 스캐폴드)
|
|
4
|
+
license: Apache-2.0 (https://opentelemetry.io)
|
|
5
|
+
priority: 4 (출처 우선순위)
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# OpenTelemetry (OTel)
|
|
9
|
+
|
|
10
|
+
> 관찰가능성(Observability) 표준. Traces + Metrics + Logs 통합 계측.
|
|
11
|
+
|
|
12
|
+
## 출처
|
|
13
|
+
|
|
14
|
+
| URL | 설명 |
|
|
15
|
+
|-----|------|
|
|
16
|
+
| https://opentelemetry.io/docs/ | OTel 공식 문서 |
|
|
17
|
+
| https://opentelemetry.io/docs/languages/js/ | JavaScript/Node.js SDK |
|
|
18
|
+
| https://opentelemetry.io/docs/languages/go/ | Go SDK |
|
|
19
|
+
| https://opentelemetry.io/docs/concepts/signals/ | Signals 개념 (Traces/Metrics/Logs) |
|
|
20
|
+
| https://opentelemetry.io/docs/specs/otel/ | 명세 |
|
|
21
|
+
| https://w3c.github.io/trace-context/ | W3C TraceContext (traceparent 헤더) |
|
|
22
|
+
|
|
23
|
+
## 라이선스
|
|
24
|
+
|
|
25
|
+
Apache-2.0
|
|
26
|
+
|
|
27
|
+
## 수집일
|
|
28
|
+
|
|
29
|
+
예정 (2026-05-18 스캐폴드)
|
|
30
|
+
|
|
31
|
+
## 참조 우선순위
|
|
32
|
+
|
|
33
|
+
4 (common.md 출처 우선순위)
|
|
34
|
+
|
|
35
|
+
## 문서 목록 (수집 예정)
|
|
36
|
+
|
|
37
|
+
| 파일명 (예정) | 주제 |
|
|
38
|
+
|--------------|------|
|
|
39
|
+
| concepts-traces.md | Traces, Spans, TraceContext |
|
|
40
|
+
| concepts-metrics.md | Metrics — Counters, Histograms, Gauges |
|
|
41
|
+
| concepts-logs.md | Structured Logs + Log Correlation |
|
|
42
|
+
| sdk-node-setup.md | Node.js SDK 설정 + 자동 계측 |
|
|
43
|
+
| sdk-go-setup.md | Go SDK 설정 + 자동 계측 |
|
|
44
|
+
| propagation.md | Context Propagation (W3C TraceContext) |
|
|
45
|
+
| semantic-conventions.md | HTTP/DB 속성 명명 규칙 |
|
|
46
|
+
| exporters.md | OTLP, Jaeger, Prometheus exporter |
|
|
47
|
+
|
|
48
|
+
## 핵심 참조 원칙 (principles/common.md 연결)
|
|
49
|
+
|
|
50
|
+
- Traces → Observability C.3 분산 트레이스
|
|
51
|
+
- W3C TraceContext → C.3 traceparent 헤더 전파
|
|
52
|
+
- Metrics → C.2 RED Method 계측
|
|
53
|
+
- Semantic Conventions → 속성 이름 표준화
|