haechi 0.3.2
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/LICENSE +154 -0
- package/README.md +102 -0
- package/SECURITY.md +31 -0
- package/docs/README.md +35 -0
- package/docs/current/api-stability.ko.md +48 -0
- package/docs/current/api-stability.md +48 -0
- package/docs/current/expert-gap-review-ai-llm-mcp-encryption.ko.md +107 -0
- package/docs/current/expert-gap-review-ai-llm-mcp-encryption.md +107 -0
- package/docs/current/global-privacy-compliance-review.ko.md +110 -0
- package/docs/current/global-privacy-compliance-review.md +110 -0
- package/docs/current/initial-plan-ai-llm-mcp-encryption.ko.md +214 -0
- package/docs/current/initial-plan-ai-llm-mcp-encryption.md +214 -0
- package/docs/current/mvp-0.1-implementation-scope.ko.md +79 -0
- package/docs/current/mvp-0.1-implementation-scope.md +79 -0
- package/docs/current/open-source-modular-architecture.ko.md +387 -0
- package/docs/current/open-source-modular-architecture.md +387 -0
- package/docs/current/prd-ai-llm-mcp-encryption.ko.md +260 -0
- package/docs/current/prd-ai-llm-mcp-encryption.md +262 -0
- package/docs/current/privacy-filtering-policy-draft.ko.md +307 -0
- package/docs/current/privacy-filtering-policy-draft.md +307 -0
- package/docs/current/release-0.2-implementation-scope.ko.md +46 -0
- package/docs/current/release-0.2-implementation-scope.md +46 -0
- package/docs/current/release-0.3-implementation-scope.ko.md +86 -0
- package/docs/current/release-0.3-implementation-scope.md +86 -0
- package/docs/current/release-0.3.2-hardening-scope.ko.md +64 -0
- package/docs/current/release-0.3.2-hardening-scope.md +64 -0
- package/docs/current/release-0.4-implementation-scope.ko.md +121 -0
- package/docs/current/release-0.4-implementation-scope.md +121 -0
- package/docs/current/release-process.ko.md +48 -0
- package/docs/current/release-process.md +48 -0
- package/docs/current/risk-register-release-gate.ko.md +154 -0
- package/docs/current/risk-register-release-gate.md +154 -0
- package/docs/current/shared-responsibility.ko.md +38 -0
- package/docs/current/shared-responsibility.md +38 -0
- package/docs/current/threat-model.ko.md +68 -0
- package/docs/current/threat-model.md +68 -0
- package/examples/llm-prompt-filtering/input.json +13 -0
- package/examples/plugins/custom-filter.plugin.json +29 -0
- package/haechi.config.example.json +70 -0
- package/package.json +74 -0
- package/packages/audit/index.mjs +262 -0
- package/packages/cli/bin/haechi.mjs +341 -0
- package/packages/cli/runtime.mjs +287 -0
- package/packages/core/index.mjs +309 -0
- package/packages/crypto/index.mjs +142 -0
- package/packages/filter/index.mjs +189 -0
- package/packages/mcp-stdio/index.mjs +105 -0
- package/packages/plugin/index.mjs +83 -0
- package/packages/policy/index.mjs +165 -0
- package/packages/policy-bundle/index.mjs +91 -0
- package/packages/privacy-profiles/index.mjs +92 -0
- package/packages/protocol-adapters/index.mjs +111 -0
- package/packages/proxy/index.mjs +534 -0
- package/packages/token-vault/index.mjs +262 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Haechi 0.3.2 Hardening Scope
|
|
2
|
+
|
|
3
|
+
- Status: Final
|
|
4
|
+
- Date: 2026-06-10
|
|
5
|
+
- Target version: 0.3.2
|
|
6
|
+
- Type: Security hardening release; first npm developer preview distribution target
|
|
7
|
+
|
|
8
|
+
## 1. Background
|
|
9
|
+
|
|
10
|
+
This release resolves the 16 risks identified during the full 0.3.1 code review. The detailed risk list and closure evidence follow `risk-register-release-gate.md` section 5.2 (P0-SEC-016 through P2-DOC-005).
|
|
11
|
+
|
|
12
|
+
Because no version has ever been published to npm, 0.3.2 is the first published version. Separating the first publication from a feature release (0.4.0) allows package-name ownership to be confirmed and the publish pipeline (provenance, GitHub release workflow) to be validated in a low-risk release first.
|
|
13
|
+
|
|
14
|
+
## 2. Change Summary
|
|
15
|
+
|
|
16
|
+
### Blocking / Enforcement Path
|
|
17
|
+
- Ollama `/api/chat` and `/api/generate` are treated as streaming unless `stream: false` is explicitly set; default behavior is 501 fail-closed (protocol adapter `streamingDefault`)
|
|
18
|
+
- Unknown `target.type` values are rejected fail-closed at config validation time (only the `llm-http` alias is accepted as openai-compatible)
|
|
19
|
+
- Upstream fetch respects `limits.upstreamTimeoutMs` (default: 120000 ms); timeout returns `504 haechi_upstream_timeout`, connection failure returns `502 haechi_upstream_unreachable`
|
|
20
|
+
- Proxy internal error messages are generalized (details go to stderr)
|
|
21
|
+
|
|
22
|
+
### Detection / Transform
|
|
23
|
+
- JSON number leaves (e.g., card numbers) and object key names are now included in detection/transform scope (enforce mode renames keys; conflicts get a `#n` suffix)
|
|
24
|
+
- Masks of 8 characters or fewer are fully masked
|
|
25
|
+
- `assignment-secret` pattern converted to lookbehind — key name is preserved, only the value is replaced
|
|
26
|
+
- Privacy profile can only strengthen user-declared policy, never weaken it (`ACTION_STRENGTH` comparison)
|
|
27
|
+
|
|
28
|
+
### Keys / Cryptography
|
|
29
|
+
- `decrypt` selects the key by envelope `kid` (maintains decryption of legacy envelopes)
|
|
30
|
+
- `initLocalKeyFile --force` now performs a rotation that preserves the existing key as `retired` rather than overwriting it
|
|
31
|
+
- Policy bundle signing key is separated as a `haechi:policy-bundle:signing:v1` domain-separated derived key
|
|
32
|
+
|
|
33
|
+
### TokenVault / Audit
|
|
34
|
+
- reveal and purge decisions are recorded in audit (`reveal_allowed/denied/failed`, `purge`, `purge_expired` — token id only, no plaintext)
|
|
35
|
+
- Expired tokens are automatically deleted on vault mutation; `purgeExpired()` and `haechi token-purge --expired` are added
|
|
36
|
+
- Audit append is O(1) via tail-chunk read
|
|
37
|
+
- Audit/vault lock files older than 30 seconds are considered stale and automatically reclaimed
|
|
38
|
+
|
|
39
|
+
### UX / Visibility
|
|
40
|
+
- Non-enforcement mode (dry-run/report-only) and disabled responseProtection warnings are shown at proxy startup and in `protect` output
|
|
41
|
+
- `protect` output now includes `mode`, `enforced`, and `warnings` fields
|
|
42
|
+
|
|
43
|
+
### MCP
|
|
44
|
+
- Notifications (messages without an id) are dropped with no error response, per the JSON-RPC spec
|
|
45
|
+
- Batch arrays are explicitly rejected fail-closed
|
|
46
|
+
|
|
47
|
+
## 3. Compatibility Notes (vs. 0.3.1)
|
|
48
|
+
|
|
49
|
+
No users have received a published release, so no migration path is provided — this is recorded for reference only.
|
|
50
|
+
|
|
51
|
+
- Policy bundles signed with a 0.3.1 key will fail verification due to the signing key separation. Re-sign with `haechi policy-sign`.
|
|
52
|
+
- The expanded detection scope (numbers/keys) and changed mask behavior may produce different enforce-mode output compared to 0.3.1.
|
|
53
|
+
- A `kind` field has been added to `detection` entries in audit events.
|
|
54
|
+
|
|
55
|
+
## 4. Explicit Exclusions (0.4+ Backlog)
|
|
56
|
+
|
|
57
|
+
- Inspection of base64/URL-encoded values after decoding
|
|
58
|
+
- URL query string inspection
|
|
59
|
+
- Audit hash chain tail truncation detection (requires external anchoring)
|
|
60
|
+
- SSE/NDJSON stream inspection (0.5.0)
|
|
61
|
+
|
|
62
|
+
## 5. Release Gate
|
|
63
|
+
|
|
64
|
+
Follow the checklist in `risk-register-release-gate.md` section 7. After `npm run release:preflight` passes, publish from an authenticated account using `release:preflight:npm` and the GitHub release workflow.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Haechi 0.4 Implementation Scope
|
|
2
|
+
|
|
3
|
+
- 문서 상태: Draft 0.1
|
|
4
|
+
- 작성일: 2026-06-10
|
|
5
|
+
- 기준 버전: 0.4.0 (0.3.2 이후)
|
|
6
|
+
- 주제: token round-trip and adoption
|
|
7
|
+
|
|
8
|
+
## 1. 릴리스 목표
|
|
9
|
+
|
|
10
|
+
0.4는 두 가지를 완성한다.
|
|
11
|
+
|
|
12
|
+
1. **토큰 왕복(token round-trip)**: 모델은 토큰만 보고 사용자는 평문을 보는 구조. tokenize action이 실사용 의미를 갖게 한다.
|
|
13
|
+
2. **채택 장벽 축소**: MCP wrap 모드, audit 검증/status 명령으로 끼워넣기 UX와 운영 가시성을 확보한다.
|
|
14
|
+
|
|
15
|
+
추가로 0.6(auth)·0.7(dashboard) 확장의 전제가 되는 `identity` 스키마와 `authProvider` 계약을 **구현 없이 계약만** 예약한다.
|
|
16
|
+
|
|
17
|
+
## 2. 범위
|
|
18
|
+
|
|
19
|
+
### 2.1 결정적 토큰화 (deterministic tokenization)
|
|
20
|
+
|
|
21
|
+
- 동일 (type, value)는 동일 토큰으로 토큰화하는 opt-in 모드: `tokenVault.deterministic: true` (기본 false)
|
|
22
|
+
- 토큰 생성: `haechi:token-vault:deterministic:v1` domain-separated 파생 키로 `HMAC(derivedKey, type || value)` — 키 파일 없이는 역산/사전 공격 불가
|
|
23
|
+
- 기존 레코드가 있으면 재사용하고 expiry를 갱신한다
|
|
24
|
+
- **트레이드오프 문서화 필수**: 결정성은 동일값 연결성(linkability)을 만든다. 타입별 opt-in(`tokenVault.deterministicTypes`)을 지원한다
|
|
25
|
+
|
|
26
|
+
### 2.2 응답 detokenization (요청 스코프)
|
|
27
|
+
|
|
28
|
+
- 새 config: `tokenVault.detokenizeResponses: true` (기본 false, 명시 opt-in)
|
|
29
|
+
- **요청 스코프 원칙**: 요청 보호 단계에서 발급/재사용된 토큰 집합만 그 요청의 응답에서 복원한다. 세션 저장소·세션 ID 불필요
|
|
30
|
+
- 멀티턴은 결정적 토큰화로 해결된다: 클라이언트가 매 턴 보내는 대화 이력이 재토큰화되며 이전 턴 토큰이 현재 요청의 토큰 집합에 자동 포함된다
|
|
31
|
+
- **revealPolicy와 분리**: `revealPolicy: disabled`는 CLI/수동 reveal 통제이며 응답 복원과 무관하다. 복원 행위는 vault audit 이벤트(`detokenize` decision, 토큰 수만 기록)로 남긴다
|
|
32
|
+
- responseProtection이 활성일 때만 동작한다 (응답 본문을 이미 파싱하는 경로에서만 복원)
|
|
33
|
+
|
|
34
|
+
### 2.3 `haechi mcp-wrap`
|
|
35
|
+
|
|
36
|
+
- 형태: `haechi mcp-wrap --config haechi.config.json -- <command> [args...]`
|
|
37
|
+
- 자식 프로세스를 spawn하고 stdio 양방향을 필터링한다
|
|
38
|
+
- 클라이언트→서버: method allowlist + params 보호
|
|
39
|
+
- 서버→클라이언트: result 보호 (+ 2.6 injection 탐지)
|
|
40
|
+
- stderr는 투명 통과, 종료 코드·SIGINT/SIGTERM 전파
|
|
41
|
+
- notification drop·batch fail-closed 의미론은 0.3.2와 동일
|
|
42
|
+
|
|
43
|
+
### 2.4 `haechi audit-verify`
|
|
44
|
+
|
|
45
|
+
- `haechi audit-verify [--audit .haechi/audit.jsonl]`
|
|
46
|
+
- `verifyAuditChain()` 결과(valid/records/reason)와 chain head hash를 출력한다
|
|
47
|
+
- head hash는 외부 앵커링(tail truncation 대응)의 기초 자료다. 주기적 앵커 자동화는 0.6+ 범위
|
|
48
|
+
|
|
49
|
+
### 2.5 `haechi status`
|
|
50
|
+
|
|
51
|
+
- 현재 config의 유효 상태를 한눈에 출력: 유효 policy mode(enforce/dry-run/report-only), responseProtection on/off, streaming mode, revealPolicy, detokenization on/off, privacy profile, adapter/upstream, key file 존재·권한, audit chain 검증 요약
|
|
52
|
+
- dry-run 기본값 제품에서 "지금 보호되고 있는가"에 답하는 명령이다. JSON 출력 지원
|
|
53
|
+
|
|
54
|
+
### 2.6 injection detection type (preview)
|
|
55
|
+
|
|
56
|
+
- 새 detection type `injection`: tool result/응답 방향에 한정 적용하는 휴리스틱 룰셋 (지시문 패턴, 역할 전환 시도, 도구 호출 유도)
|
|
57
|
+
- **기본 action은 `allow`** — detection은 action과 무관하게 audit에 기록되므로 이것이 곧 report-only다. 신뢰가 쌓이면 사용자가 `actions.injection: "redact" | "block"`으로 격상한다
|
|
58
|
+
- 기본 block은 금지: 오탐이 보안 제품 신뢰를 깎는다
|
|
59
|
+
|
|
60
|
+
### 2.7 `identity` 스키마 예약 (구현 없음)
|
|
61
|
+
|
|
62
|
+
audit 이벤트와 protect context에 PII-safe identity 필드를 예약한다. 0.4에서는 항상 `null`이다.
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
identity: {
|
|
66
|
+
id: "...", // provider 발급 opaque id 또는 subjectHash와 동일
|
|
67
|
+
type: "anonymous" | "user" | "service" | "agent",
|
|
68
|
+
subjectHash: "...", // HMAC("haechi:identity:hash:v1" 파생 키, subject) — bare sha256 금지
|
|
69
|
+
issuerHash: "...", // 동일 방식
|
|
70
|
+
provider: "none" | "bearer" | "oidc" | "external",
|
|
71
|
+
scopes: ["..."],
|
|
72
|
+
labels: {} // allowlist된 키만 (config 선언), 값 길이 제한, PII 금지
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
- subject/email 등 **원문은 어떤 필드에도 금지**. 저엔트로피 식별자의 bare hash는 사전 공격으로 복원 가능하므로 keyed HMAC만 허용한다
|
|
77
|
+
- `labels`는 자유 형식 금지: config에 선언된 allowlist 키만 통과시키고 값 길이를 제한한다
|
|
78
|
+
- 표시용 이름은 audit 스키마가 아니라 dashboard 측 opt-in 설정이다
|
|
79
|
+
|
|
80
|
+
### 2.8 `authProvider` 계약 예약 (구현 없음)
|
|
81
|
+
|
|
82
|
+
- 계약: `authenticate(request) → identity | null` (null = 거부), 실패는 fail-closed
|
|
83
|
+
- 프록시 실행 순서 (0.6 구현 시):
|
|
84
|
+
|
|
85
|
+
```text
|
|
86
|
+
request target 검증 (assertRelativeProxyTarget)
|
|
87
|
+
route classify
|
|
88
|
+
authProvider.authenticate() ← body 읽기 전. 인증 실패 요청의 대용량 body DoS 차단
|
|
89
|
+
policy scope 결정 (identity 기반)
|
|
90
|
+
body read
|
|
91
|
+
protect/enforce
|
|
92
|
+
forward
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- 인증 실패는 `auth_denied` decision으로 audit 기록 (시도된 provider만, identity 원문 없음)
|
|
96
|
+
- 401 응답 시 request stream을 소비하지 않고 응답 후 연결을 닫는다
|
|
97
|
+
- `/__haechi/health`는 의도적으로 무인증 유지 (mode만 노출), 계약 문서에 명시
|
|
98
|
+
- `createRuntime(config, { authProvider })` 주입만 지원. **동적 npm 로딩은 1.0 plugin sandbox 이전까지 금지**
|
|
99
|
+
|
|
100
|
+
## 3. 명시적 비범위 (0.4에서 하지 않음)
|
|
101
|
+
|
|
102
|
+
- auth 구현 (bearer 포함) — 0.6
|
|
103
|
+
- SSE/NDJSON stream inspection — 0.5
|
|
104
|
+
- proxy auth, model allowlist, rate/budget, hot reload, metrics — 0.6
|
|
105
|
+
- dashboard, npm workspaces 전환 — 0.7
|
|
106
|
+
- 외부 package 동적 로딩 — 1.0
|
|
107
|
+
|
|
108
|
+
## 4. 테스트 기준
|
|
109
|
+
|
|
110
|
+
- detokenization: 요청에 없던 토큰은 응답에서 복원되지 않는다 (스코프 격리)
|
|
111
|
+
- deterministic: 동일 값 → 동일 토큰, 파생 키 변경 시 다른 토큰
|
|
112
|
+
- mcp-wrap: 양방향 보호, allowlist 거부, 자식 종료 코드 전파
|
|
113
|
+
- audit-verify: 정상/변조/절단 케이스 출력
|
|
114
|
+
- status: enforce/dry-run 각각에서 경고 정확성
|
|
115
|
+
- injection: 기본 allow에서 audit 기록만 되고 payload 불변
|
|
116
|
+
|
|
117
|
+
## 5. 문서 영향
|
|
118
|
+
|
|
119
|
+
- README: detokenization·mcp-wrap·status 사용법, deterministic linkability 트레이드오프
|
|
120
|
+
- threat-model: injection 휴리스틱의 한계(완전 방어 아님) 명시 유지, identity hash 방식 추가
|
|
121
|
+
- api-stability: authProvider/identity 계약은 0.4에서 experimental 표기
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Haechi 0.4 Implementation Scope
|
|
2
|
+
|
|
3
|
+
- Status: Draft 0.1
|
|
4
|
+
- Date: 2026-06-10
|
|
5
|
+
- Target version: 0.4.0 (after 0.3.2)
|
|
6
|
+
- Type: token round-trip and adoption
|
|
7
|
+
|
|
8
|
+
## 1. Release Goals
|
|
9
|
+
|
|
10
|
+
0.4 accomplishes two things.
|
|
11
|
+
|
|
12
|
+
1. **Token round-trip**: the model sees only tokens while the user sees plaintext. This makes the tokenize action meaningful in real use.
|
|
13
|
+
2. **Reducing adoption friction**: MCP wrap mode plus audit verify/status commands provide plug-in UX and operational visibility.
|
|
14
|
+
|
|
15
|
+
Additionally, the `identity` schema and `authProvider` contract — prerequisites for the 0.6 (auth) and 0.7 (dashboard) expansions — are **reserved as contracts only, without implementation**.
|
|
16
|
+
|
|
17
|
+
## 2. Scope
|
|
18
|
+
|
|
19
|
+
### 2.1 Deterministic Tokenization
|
|
20
|
+
|
|
21
|
+
- Opt-in mode where the same (type, value) pair always produces the same token: `tokenVault.deterministic: true` (default: false)
|
|
22
|
+
- Token generation: `HMAC(derivedKey, type || value)` using a `haechi:token-vault:deterministic:v1` domain-separated derived key — not reversible or dictionary-attackable without the key file
|
|
23
|
+
- If a matching record already exists, it is reused and its expiry is refreshed
|
|
24
|
+
- **Trade-off documentation required**: determinism introduces linkability for identical values. Per-type opt-in is supported via `tokenVault.deterministicTypes`
|
|
25
|
+
|
|
26
|
+
### 2.2 Response Detokenization (Request-Scoped)
|
|
27
|
+
|
|
28
|
+
- New config: `tokenVault.detokenizeResponses: true` (default: false, explicit opt-in)
|
|
29
|
+
- **Request-scope principle**: only the token set issued or reused during the protect phase of a given request is restored in that request's response. No session storage or session ID required.
|
|
30
|
+
- Multi-turn is handled by deterministic tokenization: conversation history sent by the client each turn is re-tokenized, so prior-turn tokens are automatically included in the current request's token set.
|
|
31
|
+
- **Decoupled from revealPolicy**: `revealPolicy: disabled` controls CLI/manual reveal and is unrelated to response restoration. Restoration is recorded as a vault audit event (`detokenize` decision, token count only — no plaintext).
|
|
32
|
+
- Only active when responseProtection is enabled (restoration only runs on paths that already parse the response body).
|
|
33
|
+
|
|
34
|
+
### 2.3 `haechi mcp-wrap`
|
|
35
|
+
|
|
36
|
+
- Usage: `haechi mcp-wrap --config haechi.config.json -- <command> [args...]`
|
|
37
|
+
- Spawns a child process and filters stdio in both directions:
|
|
38
|
+
- Client → server: method allowlist + params protection
|
|
39
|
+
- Server → client: result protection (+ 2.6 injection detection)
|
|
40
|
+
- stderr passes through transparently; exit codes and SIGINT/SIGTERM are propagated
|
|
41
|
+
- Notification drop and batch fail-closed semantics are identical to 0.3.2
|
|
42
|
+
|
|
43
|
+
### 2.4 `haechi audit-verify`
|
|
44
|
+
|
|
45
|
+
- `haechi audit-verify [--audit .haechi/audit.jsonl]`
|
|
46
|
+
- Outputs the `verifyAuditChain()` result (valid/records/reason) and the chain head hash
|
|
47
|
+
- The head hash serves as the foundation for external anchoring (defense against tail truncation). Periodic anchor automation is deferred to 0.6+.
|
|
48
|
+
|
|
49
|
+
### 2.5 `haechi status`
|
|
50
|
+
|
|
51
|
+
- Prints an at-a-glance view of the effective state of the current config: effective policy mode (enforce/dry-run/report-only), responseProtection on/off, streaming mode, revealPolicy, detokenization on/off, privacy profile, adapter/upstream, key file existence and permissions, audit chain verification summary
|
|
52
|
+
- Answers the question "am I protected right now?" for products that default to dry-run. JSON output supported.
|
|
53
|
+
|
|
54
|
+
### 2.6 Injection Detection Type (Preview)
|
|
55
|
+
|
|
56
|
+
- New detection type `injection`: a heuristic ruleset applied only on the tool result/response direction (instruction patterns, role-switch attempts, tool-call induction)
|
|
57
|
+
- **Default action is `allow`** — detection is recorded in audit regardless of action, making this effectively report-only. Users can escalate to `actions.injection: "redact" | "block"` once confidence grows.
|
|
58
|
+
- Default blocking is prohibited: false positives erode trust in a security product.
|
|
59
|
+
|
|
60
|
+
### 2.7 `identity` Schema Reservation (No Implementation)
|
|
61
|
+
|
|
62
|
+
PII-safe identity fields are reserved in audit events and the protect context. In 0.4 these are always `null`.
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
identity: {
|
|
66
|
+
id: "...", // opaque id issued by provider, or same as subjectHash
|
|
67
|
+
type: "anonymous" | "user" | "service" | "agent",
|
|
68
|
+
subjectHash: "...", // HMAC("haechi:identity:hash:v1" derived key, subject) — bare sha256 prohibited
|
|
69
|
+
issuerHash: "...", // same approach
|
|
70
|
+
provider: "none" | "bearer" | "oidc" | "external",
|
|
71
|
+
scopes: ["..."],
|
|
72
|
+
labels: {} // allowlisted keys only (declared in config), value length limited, PII prohibited
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
- Raw subject/email values are **prohibited in every field**. Bare hashes of low-entropy identifiers are recoverable by dictionary attack — keyed HMAC only.
|
|
77
|
+
- `labels` is not freeform: only allowlist keys declared in config are accepted, and values are length-limited.
|
|
78
|
+
- Display names are an opt-in dashboard-side setting, not part of the audit schema.
|
|
79
|
+
|
|
80
|
+
### 2.8 `authProvider` Contract Reservation (No Implementation)
|
|
81
|
+
|
|
82
|
+
- Contract: `authenticate(request) → identity | null` (null = deny); failure is fail-closed
|
|
83
|
+
- Proxy execution order (implemented in 0.6):
|
|
84
|
+
|
|
85
|
+
```text
|
|
86
|
+
request target validation (assertRelativeProxyTarget)
|
|
87
|
+
route classify
|
|
88
|
+
authProvider.authenticate() ← before reading body. Blocks large-body DoS from failed-auth requests
|
|
89
|
+
policy scope determination (identity-based)
|
|
90
|
+
body read
|
|
91
|
+
protect/enforce
|
|
92
|
+
forward
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- Authentication failures are recorded in audit as `auth_denied` decision (attempted provider only, no raw identity)
|
|
96
|
+
- On 401 response, the request stream is not consumed; the connection is closed after responding
|
|
97
|
+
- `/__haechi/health` is intentionally kept unauthenticated (exposes mode only); documented in the contract
|
|
98
|
+
- Only `createRuntime(config, { authProvider })` injection is supported. **Dynamic npm loading is prohibited until the 1.0 plugin sandbox.**
|
|
99
|
+
|
|
100
|
+
## 3. Explicit Out-of-Scope (Not in 0.4)
|
|
101
|
+
|
|
102
|
+
- Auth implementation (including bearer) — 0.6
|
|
103
|
+
- SSE/NDJSON stream inspection — 0.5
|
|
104
|
+
- Proxy auth, model allowlist, rate/budget limits, hot reload, metrics — 0.6
|
|
105
|
+
- Dashboard, npm workspaces migration — 0.7
|
|
106
|
+
- Dynamic external package loading — 1.0
|
|
107
|
+
|
|
108
|
+
## 4. Test Criteria
|
|
109
|
+
|
|
110
|
+
- Detokenization: tokens not issued during a request are not restored in that request's response (scope isolation)
|
|
111
|
+
- Deterministic: same value → same token; different derived key → different token
|
|
112
|
+
- mcp-wrap: bidirectional protection, allowlist rejection, child exit code propagation
|
|
113
|
+
- audit-verify: correct output for valid/tampered/truncated cases
|
|
114
|
+
- status: correct warnings under enforce and dry-run respectively
|
|
115
|
+
- injection: with default allow, only audit record is written and payload is unchanged
|
|
116
|
+
|
|
117
|
+
## 5. Documentation Impact
|
|
118
|
+
|
|
119
|
+
- README: usage for detokenization, mcp-wrap, and status; deterministic linkability trade-off
|
|
120
|
+
- threat-model: maintain explicit statement of injection heuristic limitations (not a complete defense); add identity hash approach
|
|
121
|
+
- api-stability: authProvider/identity contract marked experimental in 0.4
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Haechi Release Process
|
|
2
|
+
|
|
3
|
+
- 문서 상태: Draft 0.1
|
|
4
|
+
- 작성일: 2026-06-10
|
|
5
|
+
- 기준 버전: 0.3.2
|
|
6
|
+
|
|
7
|
+
## 1. 로컬 릴리즈 검증
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm run release:preflight
|
|
11
|
+
npm run sbom
|
|
12
|
+
npm run bench:payload
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`release:preflight`는 테스트, stale-name scan, pack dry-run을 실행한다. npm 계정 인증과 package ownership 확인까지 포함하려면 다음을 사용한다.
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm run release:preflight:npm
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
첫 publish 전에는 `npm view <package> version`이 `E404 Not Found`를 반환하는 것이 정상이다. 이 경우 preflight는 인증된 계정에서 이름을 claim할 준비가 된 상태로 통과한다. 단, `npm view <package>@<version> version`이 성공하면 같은 버전을 다시 배포할 수 없으므로 실패한다.
|
|
22
|
+
|
|
23
|
+
## 2. npm provenance
|
|
24
|
+
|
|
25
|
+
npm provenance는 GitHub Actions release workflow에서 생성한다. 공식 npm 문서의 요구사항에 맞춰 GitHub-hosted runner, `id-token: write`, `npm publish --provenance --access public`을 사용한다.
|
|
26
|
+
|
|
27
|
+
참고:
|
|
28
|
+
|
|
29
|
+
- https://docs.npmjs.com/generating-provenance-statements/
|
|
30
|
+
- https://docs.github.com/actions/publishing-packages/publishing-nodejs-packages
|
|
31
|
+
|
|
32
|
+
## 3. GitHub Actions
|
|
33
|
+
|
|
34
|
+
| Workflow | 목적 |
|
|
35
|
+
|---|---|
|
|
36
|
+
| `.github/workflows/ci.yml` | test, release preflight, SBOM artifact |
|
|
37
|
+
| `.github/workflows/npm-publish.yml` | GitHub release published 이벤트에서 npm provenance publish |
|
|
38
|
+
|
|
39
|
+
## 4. 배포 차단 조건
|
|
40
|
+
|
|
41
|
+
다음 중 하나라도 실패하면 npm publish를 하지 않는다.
|
|
42
|
+
|
|
43
|
+
- `npm run release:preflight` 실패
|
|
44
|
+
- `npm run release:preflight:npm` 실패
|
|
45
|
+
- GitHub Actions CI 실패
|
|
46
|
+
- SBOM 생성 실패
|
|
47
|
+
- npm package name ownership 불확실
|
|
48
|
+
- README/SECURITY가 developer preview와 production 제한을 명시하지 않음
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Haechi Release Process
|
|
2
|
+
|
|
3
|
+
- Status: Draft 0.1
|
|
4
|
+
- Date: 2026-06-10
|
|
5
|
+
- Target version: 0.3.2
|
|
6
|
+
|
|
7
|
+
## 1. Local Release Verification
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm run release:preflight
|
|
11
|
+
npm run sbom
|
|
12
|
+
npm run bench:payload
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`release:preflight` runs tests, a stale-name scan, and a pack dry-run. To also verify npm account authentication and package ownership, use:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm run release:preflight:npm
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Before the first publish, it is normal for `npm view <package> version` to return `E404 Not Found`. In that case, preflight passes with the package name ready to be claimed from an authenticated account. However, if `npm view <package>@<version> version` succeeds, the same version cannot be published again and preflight will fail.
|
|
22
|
+
|
|
23
|
+
## 2. npm provenance
|
|
24
|
+
|
|
25
|
+
npm provenance is generated by the GitHub Actions release workflow. Following the requirements in the official npm documentation, it uses a GitHub-hosted runner, `id-token: write`, and `npm publish --provenance --access public`.
|
|
26
|
+
|
|
27
|
+
References:
|
|
28
|
+
|
|
29
|
+
- https://docs.npmjs.com/generating-provenance-statements/
|
|
30
|
+
- https://docs.github.com/actions/publishing-packages/publishing-nodejs-packages
|
|
31
|
+
|
|
32
|
+
## 3. GitHub Actions
|
|
33
|
+
|
|
34
|
+
| Workflow | Purpose |
|
|
35
|
+
|---|---|
|
|
36
|
+
| `.github/workflows/ci.yml` | Tests, release preflight, SBOM artifact |
|
|
37
|
+
| `.github/workflows/npm-publish.yml` | npm provenance publish on GitHub release published event |
|
|
38
|
+
|
|
39
|
+
## 4. Deployment block conditions
|
|
40
|
+
|
|
41
|
+
npm publish is not performed if any of the following fail.
|
|
42
|
+
|
|
43
|
+
- `npm run release:preflight` fails
|
|
44
|
+
- `npm run release:preflight:npm` fails
|
|
45
|
+
- GitHub Actions CI fails
|
|
46
|
+
- SBOM generation fails
|
|
47
|
+
- npm package name ownership is uncertain
|
|
48
|
+
- README/SECURITY does not explicitly state developer preview and production restrictions
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# Haechi 리스크 레지스터 및 릴리스 게이트
|
|
2
|
+
|
|
3
|
+
- 문서 상태: Draft 0.3
|
|
4
|
+
- 작성일: 2026-06-10
|
|
5
|
+
- 기준 버전: 0.3.2
|
|
6
|
+
- 기준 브랜치: `irae/risk-resolution`
|
|
7
|
+
|
|
8
|
+
## 1. 현재 판단
|
|
9
|
+
|
|
10
|
+
0.3.2는 0.3.1 전체 코드 리뷰에서 식별된 추가 보안/운영 리스크를 developer preview 기준으로 해소했다. GitHub 공개와 npm developer preview 배포는 허용 가능하다. 단, 실제 npm publish는 npm 계정 인증, package ownership, GitHub release workflow 실행이라는 외부 운영자 게이트를 통과해야 한다.
|
|
11
|
+
|
|
12
|
+
| 구분 | 판단 | 이유 |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| GitHub public | 허용 | 보안 한계, threat model, shared responsibility, developer preview 문구가 문서화됨 |
|
|
15
|
+
| GitHub release/tag | 허용 | production-ready가 아닌 developer preview로 표현해야 함 |
|
|
16
|
+
| npm developer preview | 조건부 허용 | `npm run release:preflight` 통과 후, 인증된 계정에서 `release:preflight:npm` 및 provenance publish 필요 |
|
|
17
|
+
| npm stable | 보류 | 1.0 API 안정성, 운영 KMS/HSM/Vault reference adapter, stream-aware enforcement 전까지 stable 표현 금지 |
|
|
18
|
+
| production use | 금지 | 0.3.2는 self-hosted developer preview이며 운영 인증/인가/key custody는 사용자 책임 |
|
|
19
|
+
|
|
20
|
+
## 2. 릴리스 게이트
|
|
21
|
+
|
|
22
|
+
| Gate | 대상 | 기준 | 현재 상태 |
|
|
23
|
+
|---|---|---|---|
|
|
24
|
+
| G0 | GitHub source 공개 | 테스트 통과, 보안 한계 문서화, 평문 audit leak 없음 | Pass |
|
|
25
|
+
| G1 | GitHub pre-release | P0 코드 리스크 해결, production-ready 표현 없음 | Pass |
|
|
26
|
+
| G2 | npm developer preview | P0 해결, preflight/SBOM/provenance 경로 준비, npm auth 확인 | Conditional Pass |
|
|
27
|
+
| G3 | npm stable | P1 운영 reference, stream-aware enforcement, API stability 강화 | Blocked |
|
|
28
|
+
|
|
29
|
+
## 3. P0 배포 차단 리스크 상태
|
|
30
|
+
|
|
31
|
+
| ID | 기존 리스크 | 상태 | 해소 증거 |
|
|
32
|
+
|---|---|---|---|
|
|
33
|
+
| P0-REL-001 | npm 인증/권한 미해결 | External Gate | `release:preflight:npm`, GitHub release workflow, `npm publish --provenance --access public`로 게이트화. 실제 인증은 운영자 필요 |
|
|
34
|
+
| P0-REL-002 | proxy 외부 노출 위험 | Resolved | non-loopback bind는 기본 실패, `--allow-remote-bind` 필요 |
|
|
35
|
+
| P0-REL-003 | streaming 요청 처리 불명확 | Resolved | `stream: true` 기본 501 fail-closed, `streaming.requestMode: "pass-through"` 명시 필요 |
|
|
36
|
+
| P0-REL-004 | responseProtection 실패 모드 불명확 | Resolved | 비JSON/invalid JSON/압축/대용량 응답 fail-closed, 명시 allow 정책 분리 |
|
|
37
|
+
| P0-REL-005 | local dev key의 운영 오해 | Resolved | `init`, README, SECURITY에 dev-only key와 운영 key provider 부재 경고 |
|
|
38
|
+
| P0-REL-006 | npm package 신뢰 표현 과다 | Resolved | package description/README/SECURITY를 experimental developer preview로 조정 |
|
|
39
|
+
|
|
40
|
+
## 4. P1 보안 설계 리스크 상태
|
|
41
|
+
|
|
42
|
+
| ID | 기존 리스크 | 상태 | 해소 증거 |
|
|
43
|
+
|---|---|---|---|
|
|
44
|
+
| P1-SEC-001 | KMS/HSM/Vault 미지원 | Resolved for OSS core | `createRuntime(config, { cryptoProvider })` 외부 crypto provider injection, external provider 없으면 fail-closed |
|
|
45
|
+
| P1-SEC-002 | TokenVault 권한 모델 부족 | Resolved | `revealPolicy: "disabled"` 기본값, `--allow-dev-reveal`, metadata export, retention/purge timestamp |
|
|
46
|
+
| P1-SEC-003 | audit 무결성 부족 | Resolved | JSONL audit SHA-256 hash chain 및 `verifyAuditChain` |
|
|
47
|
+
| P1-SEC-004 | plugin runtime 없음 | Resolved by gating | dynamic runtime 거부, `manifest-only` plugin만 통과 |
|
|
48
|
+
| P1-SEC-005 | policy conflict 처리 부족 | Resolved | preset block 등 강한 action을 약한 action으로 낮추면 conflict fail-closed |
|
|
49
|
+
| P1-SEC-006 | regex 중심 필터 정확도 한계 | Resolved for preview | KR RRN checksum, Luhn, unsafe custom regex 제한. ML/classifier plugin은 stable backlog |
|
|
50
|
+
| P1-SEC-007 | AAD/replay/stream 확장 부족 | Resolved for preview | AAD hash mismatch 명시, streaming 기본 차단. stream sequence/replay cache는 stream support 도입 시 필요 |
|
|
51
|
+
| P1-SEC-008 | MCP security contract 미완성 | Resolved for preview | JSON-RPC 2.0 요구, method allowlist, params/result 보호 토글. OAuth resource binding은 외부 MCP layer 책임 |
|
|
52
|
+
|
|
53
|
+
## 5. P1 운영/배포 리스크 상태
|
|
54
|
+
|
|
55
|
+
| ID | 기존 리스크 | 상태 | 해소 증거 |
|
|
56
|
+
|---|---|---|---|
|
|
57
|
+
| P1-OPS-001 | CI 부재 | Resolved | `.github/workflows/ci.yml` |
|
|
58
|
+
| P1-OPS-002 | SBOM/provenance 부재 | Resolved | `npm run sbom`, `.github/workflows/npm-publish.yml`, `publishConfig.provenance` |
|
|
59
|
+
| P1-OPS-003 | 실제 vLLM/Ollama/llama.cpp 통합 테스트 부재 | Resolved for preview | env-gated optional local inference integration tests 추가. CI는 외부 모델 서버 없이 skip |
|
|
60
|
+
| P1-OPS-004 | 성능/대용량 payload 미측정 | Resolved for preview | request/response byte limit, `npm run bench:payload` |
|
|
61
|
+
| P1-OPS-005 | npm ownership 미확정 | External Gate | 인증된 npm 계정에서 `npm run release:preflight:npm`, publish 후 `npm view haechi version` 필요 |
|
|
62
|
+
|
|
63
|
+
## 5.1 추가 보안 검토 리스크 해소 상태
|
|
64
|
+
|
|
65
|
+
| ID | 추가 검출 리스크 | 상태 | 해소 증거 |
|
|
66
|
+
|---|---|---|---|
|
|
67
|
+
| P1-SEC-009 | proxy absolute-form request target으로 upstream 우회/SSRF 가능 | Resolved | absolute/protocol-relative request target을 `haechi_invalid_proxy_target`으로 거부하고, upstream URL은 path/search만 고정 upstream에 결합 |
|
|
68
|
+
| P1-SEC-010 | `responseProtection.maxBytes`가 full buffer 이후 검사되어 메모리 DoS 가능 | Resolved | upstream body를 stream reader로 제한 읽기하고 초과 즉시 cancel/fail-closed. `failureMode: "allow"`도 hard byte cap은 우회 불가 |
|
|
69
|
+
| P1-SEC-011 | audit hash chain이 동시 기록에서 sequence/previousHash 충돌 가능 | Resolved | JSONL audit sink 단위 write queue와 lock file로 hash-chain record build와 append를 직렬화 |
|
|
70
|
+
| P1-SEC-012 | JSON object key에 포함된 PII/secret이 audit path 또는 token metadata에 노출 가능 | Resolved | detection `pathText`를 raw key 대신 `key_<hash>` 구조 path로 기록 |
|
|
71
|
+
| P1-SEC-013 | local TokenVault 동시 tokenization/purge에서 update lost 가능 | Resolved | vault mutation queue, lock file, temp-file 후 rename 방식의 atomic write 적용 |
|
|
72
|
+
| P1-SEC-014 | `streaming.requestMode: "pass-through"` 및 `responseProtection.failureMode: "allow"` 우회 결정 audit 부재 | Resolved | raw payload 없이 `streaming_request_pass_through`, `response_unprotected_allowed/blocked` decision audit 기록 |
|
|
73
|
+
| P1-SEC-015 | MCP `allowedMethods` 원소 타입 검증 부족 | Resolved | non-empty string만 허용하도록 config validation 강화 |
|
|
74
|
+
| P1-OPS-006 | GitHub Actions major tag pinning으로 supply-chain drift 가능 | Resolved | `checkout`, `setup-node`, `upload-artifact`를 확인된 commit SHA로 고정 |
|
|
75
|
+
|
|
76
|
+
## 5.2 2차 전체 코드 리뷰 리스크 해소 상태 (0.3.2)
|
|
77
|
+
|
|
78
|
+
| ID | 검출 리스크 | 상태 | 해소 증거 |
|
|
79
|
+
|---|---|---|---|
|
|
80
|
+
| P0-SEC-016 | Ollama `/api/chat`·`/api/generate`는 `stream` 생략 시 기본 streaming이라 streaming 차단 우회 가능 | Resolved | protocol adapter에 `streamingDefault` 도입, `stream: false` 명시 없으면 streaming으로 간주해 기본 501 fail-closed |
|
|
81
|
+
| P1-SEC-017 | token reveal/purge가 audit 미기록 | Resolved | local TokenVault에 auditSink 주입, `reveal_allowed/denied/failed`, `purge`, `purge_expired` decision audit (plaintext 비포함) |
|
|
82
|
+
| P1-SEC-018 | privacy profile이 사용자 명시 정책을 조용히 약화 가능 | Resolved | `applyPrivacyProfile`이 ACTION_STRENGTH 비교로 강화만 허용 |
|
|
83
|
+
| P1-SEC-019 | decrypt가 envelope `kid` 무시, `init --force` 시 기존 키 파기로 vault/암호문 영구 손실 | Resolved | kid 기반 키 선택, `--force`는 기존 키를 `retired`로 보존하는 rotation으로 변경 |
|
|
84
|
+
| P1-SEC-020 | policy bundle 서명이 AES 암호화 키를 HMAC 키로 재사용 (key separation 위반) | Resolved | `haechi:policy-bundle:signing:v1` domain-separated 파생 서명 키 적용 |
|
|
85
|
+
| P1-SEC-021 | `retentionDays`가 reveal만 차단하고 만료 데이터 미삭제 | Resolved | vault mutation 시 만료 토큰 자동 prune, `purgeExpired()` 및 `haechi token-purge --expired` 추가 |
|
|
86
|
+
| P1-SEC-022 | upstream fetch 타임아웃 부재로 연결 고갈 가능 | Resolved | `limits.upstreamTimeoutMs`(기본 120000) + `504 haechi_upstream_timeout` |
|
|
87
|
+
| P1-SEC-023 | JSON number(카드번호)와 object key 내 PII/secret 미탐지 전달 | Resolved | number leaf와 object key를 detection/transform 대상에 포함 (key는 enforce 시 rename) |
|
|
88
|
+
| P1-OPS-007 | stale lock file 잔존 시 audit/vault 기록 영구 실패 | Resolved | 30초 초과 stale lock 자동 탈취 후 재획득 |
|
|
89
|
+
| P1-OPS-008 | audit append가 매 기록마다 전체 파일 재읽기 (O(n²)) | Resolved | 파일 tail-chunk 읽기로 O(1) append |
|
|
90
|
+
| P2-SEC-024 | unknown `target.type`이 openai-compatible로 silent fallback | Resolved | 알 수 없는 type은 config 검증 단계에서 fail-closed |
|
|
91
|
+
| P2-SEC-025 | 짧은 값 mask 시 대부분 노출 (5자 중 4자) | Resolved | 8자 이하 전체 마스킹 |
|
|
92
|
+
| P2-SEC-026 | assignment-secret redaction이 key 이름까지 제거 | Resolved | lookbehind 패턴으로 secret 값만 치환 |
|
|
93
|
+
| P2-SEC-027 | MCP notification에 JSON-RPC 스펙 위반 error 응답, batch 비명시 처리 | Resolved | notification은 drop, batch는 명시적 fail-closed 거부 |
|
|
94
|
+
| P2-SEC-028 | proxy 내부 오류 메시지가 클라이언트에 노출 | Resolved | 예기치 못한 오류는 일반화된 메시지 반환, 상세는 stderr |
|
|
95
|
+
| P2-DOC-005 | dry-run + responseProtection off 기본값에서 "보호 중" 오인 가능 | Resolved | proxy 기동/`protect` 출력에 비집행 경고 명시 |
|
|
96
|
+
|
|
97
|
+
base64/인코딩 값 디코딩 검사, query string 검사, audit tail truncation 탐지는 명시적 제외로 threat model에 문서화했다 (0.4+ backlog).
|
|
98
|
+
|
|
99
|
+
## 6. P2 제품/문서 리스크 상태
|
|
100
|
+
|
|
101
|
+
| ID | 기존 리스크 | 상태 | 해소 증거 |
|
|
102
|
+
|---|---|---|---|
|
|
103
|
+
| P2-DOC-001 | threat model 별도 문서 부족 | Resolved | `docs/current/threat-model.md` |
|
|
104
|
+
| P2-DOC-002 | shared responsibility 부족 | Resolved | `docs/current/shared-responsibility.md` |
|
|
105
|
+
| P2-DOC-003 | region/privacy profile 미구현 | Resolved for baseline | `haechi/privacy-profiles`, `privacy.profile` runtime 적용 |
|
|
106
|
+
| P2-DOC-004 | API stability 정책 없음 | Resolved | `docs/current/api-stability.md` |
|
|
107
|
+
|
|
108
|
+
## 7. npm developer preview 배포 전 체크리스트
|
|
109
|
+
|
|
110
|
+
현재 외부 npm 게이트 확인 결과:
|
|
111
|
+
|
|
112
|
+
- `npm whoami`: `raeseoklee`
|
|
113
|
+
- `npm view haechi version`: `E404 Not Found`
|
|
114
|
+
|
|
115
|
+
`haechi` 이름은 비어 있어 보이나, package ownership은 인증된 계정에서 최초 publish가 성공해야 확정된다. `release:preflight:npm`은 인증 확인 후 `haechi@<현재 버전>`의 중복 publish를 차단하고, 첫 publish 전 package E404는 통과 조건으로 처리한다.
|
|
116
|
+
|
|
117
|
+
1. `npm run release:preflight`
|
|
118
|
+
2. `npm run sbom`
|
|
119
|
+
3. `npm run bench:payload`
|
|
120
|
+
4. `npm run release:preflight:npm`
|
|
121
|
+
5. GitHub release 생성
|
|
122
|
+
6. GitHub Actions `Publish npm Developer Preview` 성공
|
|
123
|
+
7. `npm view haechi version`으로 실제 배포 버전 확인
|
|
124
|
+
|
|
125
|
+
## 8. 남은 non-blocking backlog
|
|
126
|
+
|
|
127
|
+
| 버전 | 목표 | 남은 범위 |
|
|
128
|
+
|---|---|---|
|
|
129
|
+
| 0.4.0 | token round-trip and adoption | 요청 스코프 response detokenization, deterministic tokenization(파생 키), `haechi mcp-wrap`(양방향 stdio), `haechi audit-verify`/`haechi status`, injection detection type(기본 allow), PII-safe `identity` 필드 및 `authProvider` 계약 예약. `docs/current/release-0.4-implementation-scope.md` 참조 |
|
|
130
|
+
| 0.5.0 | streaming hardening | SSE/NDJSON stream inspection, stream sequence AAD, replay cache, stronger remote deployment guide |
|
|
131
|
+
| 0.6.0 | auth and 운영 통제 | built-in bearer auth, client별 policy scope, model allowlist/rate budget, Vault/AWS KMS reference adapter, external append-only audit sink, signed release artifacts, npm org(`@haechi/*`) 확보 |
|
|
132
|
+
| 0.7.0 | observability | npm workspaces 전환, `@haechi/dashboard` read-only audit viewer (hash chain 무결성 표시, 요약/검색/타임라인) |
|
|
133
|
+
| 1.0.0 | stable API contract | migration policy, long-term audit schema, plugin sandbox/runtime conformance 및 allowlist/manifest 통과 외부 auth/classifier package 동적 로딩 |
|
|
134
|
+
|
|
135
|
+
동적 npm package 로딩은 1.0 plugin sandbox 이전까지 금지한다. 0.4~0.7의 외부 provider는 `createRuntime(config, providers)` 프로그래매틱 주입만 지원한다.
|
|
136
|
+
|
|
137
|
+
## 9. 현재 허용 가능한 사용 범위
|
|
138
|
+
|
|
139
|
+
현재 0.3.2는 다음 범위에서 사용한다.
|
|
140
|
+
|
|
141
|
+
- 로컬 개발 환경
|
|
142
|
+
- 샘플 payload 검증
|
|
143
|
+
- OpenAI-compatible/vLLM/Ollama/llama.cpp proxy PoC
|
|
144
|
+
- 정책/필터/감사 pipeline 검토
|
|
145
|
+
- GitHub 코드 리뷰와 보안 설계 논의
|
|
146
|
+
- npm developer preview
|
|
147
|
+
|
|
148
|
+
현재 0.3.2는 다음 용도로 사용하지 않는다.
|
|
149
|
+
|
|
150
|
+
- production LLM gateway
|
|
151
|
+
- 인터넷에 직접 노출되는 proxy
|
|
152
|
+
- 실제 고객/환자/결제/인증정보 처리
|
|
153
|
+
- compliance evidence 또는 법적 준수 증명
|
|
154
|
+
- npm stable package
|