haechi 1.1.0 → 1.1.1

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/README.ko.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Haechi
2
2
 
3
+ <p align="center">
4
+ <img src="https://raw.githubusercontent.com/raeseoklee/haechi/main/docs/assets/haechi.jpg" alt="해치 — 게이트를 지키며 디지털 방패로 검문하는 수호 영물" width="820">
5
+ </p>
6
+
3
7
  [![npm](https://img.shields.io/npm/v/haechi)](https://www.npmjs.com/package/haechi)
4
8
  [![CI](https://github.com/raeseoklee/haechi/actions/workflows/ci.yml/badge.svg)](https://github.com/raeseoklee/haechi/actions/workflows/ci.yml)
5
9
  [![license](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
@@ -60,7 +64,7 @@ npm run demo:report
60
64
  node packages/cli/bin/haechi.mjs proxy --config haechi.config.json
61
65
  ```
62
66
 
63
- 기존 HTTP JSON 클라이언트를 `http://localhost:1016`으로 지정하고, `haechi.config.json`에서 `target.upstream`을 설정한다. 다른 로컬 포트를 사용하려면 설정에서 `proxy.port`를 변경하거나 `--port`를 전달한다.
67
+ 기존 HTTP JSON 클라이언트를 `http://localhost:11016`으로 지정하고, `haechi.config.json`에서 `target.upstream`을 설정한다. 다른 로컬 포트를 사용하려면 설정에서 `proxy.port`를 변경하거나 `--port`를 전달한다.
64
68
 
65
69
  proxy는 기본적으로 loopback에 바인드된다. `0.0.0.0`, `::`, 또는 다른 non-loopback 호스트에 바인딩하려면 `--allow-remote-bind`를 명시적으로 제공해야 한다. 이 플래그는 명시적인 네트워크 접근 통제 하에서만 사용한다.
66
70
 
@@ -92,7 +96,7 @@ Haechi는 OpenAI 호환 서버, vLLM, Ollama, llama.cpp를 위한 프로토콜 a
92
96
  }
93
97
  ```
94
98
 
95
- 그런 다음 OpenAI 호환 클라이언트를 `http://127.0.0.1:1016/v1`으로 지정한다. Ollama 네이티브 API의 경우 `target.adapter: "ollama"`를 사용하고 proxy를 통해 `/api/chat` 또는 `/api/generate`를 호출한다.
99
+ 그런 다음 OpenAI 호환 클라이언트를 `http://127.0.0.1:11016/v1`으로 지정한다. Ollama 네이티브 API의 경우 `target.adapter: "ollama"`를 사용하고 proxy를 통해 `/api/chat` 또는 `/api/generate`를 호출한다.
96
100
 
97
101
  ## 토큰 왕복
98
102
 
@@ -187,7 +191,7 @@ JWT/JWKS 인증과 KMS 기반 key custody는 `haechi-*` 위성 패키지로 제
187
191
  | `mode` / `policy.mode` | `dry-run` | `dry-run`과 `report-only`는 탐지 및 audit만 수행하고, `enforce`는 변환/차단을 적용한다. `policy.mode`가 `mode`보다 우선한다 |
188
192
  | `target.type` / `target.adapter` | `llm-http` / `openai-compatible` | upstream 프로토콜: `openai-compatible`, `vllm-openai`, `ollama`, `llama-cpp`. 알 수 없는 type은 fail-closed로 처리된다 |
189
193
  | `target.upstream` | `http://127.0.0.1:9999` | proxy가 요청을 전달하는 유일한 upstream (절대 URL 요청 대상은 거부된다) |
190
- | `proxy.host` / `proxy.port` | `127.0.0.1` / `1016` | proxy 바인드 주소. 아래의 remote 바인딩 참고 |
194
+ | `proxy.host` / `proxy.port` | `127.0.0.1` / `11016` | proxy 바인드 주소. 아래의 remote 바인딩 참고 |
191
195
  | `responseProtection.enabled` | `false` | upstream JSON 응답을 검사한다. `failureMode: fail-closed`는 비JSON/압축/대용량 응답을 거부한다 |
192
196
  | `responseProtection.maxBytes` | `1048576` | 응답 크기의 상한 — `failureMode: allow` 상태에서도 적용된다 |
193
197
  | `streaming.requestMode` | `block` | `block`은 스트리밍을 501 차단; `inspect`는 SSE/NDJSON 응답을 stream-filter; `pass-through`는 검사 없이 전달(audit 기록). Ollama chat/generate는 `stream: false`가 없으면 스트리밍으로 간주된다 |
@@ -228,7 +232,7 @@ haechi proxy --config haechi.config.json --host 0.0.0.0 --allow-remote-bind
228
232
 
229
233
  **proxy는 아직 클라이언트 인증을 제공하지 않는다** (0.6 계획): 포트에 접근할 수 있는 누구든 upstream과 token round-trip 경로를 사용할 수 있다. `--allow-remote-bind`는 명시적인 네트워크 통제 하에서만 사용한다:
230
234
 
231
- - **컨테이너**: 컨테이너 내에서 `0.0.0.0`으로 바인딩하는 것은 일반적인 패턴이다 — 포트 매핑에서 노출을 제한한다(예: `-p 127.0.0.1:1016:1016`)
235
+ - **컨테이너**: 컨테이너 내에서 `0.0.0.0`으로 바인딩하는 것은 일반적인 패턴이다 — 포트 매핑에서 노출을 제한한다(예: `-p 127.0.0.1:11016:11016`)
232
236
  - **LAN/원격**: 방화벽, VPN(예: Tailscale), 또는 인증 reverse proxy를 앞에 둔다
233
237
 
234
238
  ## Privacy Profiles
package/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Haechi
2
2
 
3
+ <p align="center">
4
+ <img src="https://raw.githubusercontent.com/raeseoklee/haechi/main/docs/assets/haechi.jpg" alt="Haechi — a guardian haechi warding a gateway with a digital shield" width="820">
5
+ </p>
6
+
3
7
  [![npm](https://img.shields.io/npm/v/haechi)](https://www.npmjs.com/package/haechi)
4
8
  [![CI](https://github.com/raeseoklee/haechi/actions/workflows/ci.yml/badge.svg)](https://github.com/raeseoklee/haechi/actions/workflows/ci.yml)
5
9
  [![license](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
@@ -60,7 +64,7 @@ The default config runs in `dry-run` mode. It detects sensitive values and write
60
64
  node packages/cli/bin/haechi.mjs proxy --config haechi.config.json
61
65
  ```
62
66
 
63
- Point an existing HTTP JSON client at `http://localhost:1016` and set `target.upstream` in `haechi.config.json`. Change `proxy.port` in the config or pass `--port` to use a different local port.
67
+ Point an existing HTTP JSON client at `http://localhost:11016` and set `target.upstream` in `haechi.config.json`. Change `proxy.port` in the config or pass `--port` to use a different local port.
64
68
 
65
69
  The proxy binds to loopback by default. Binding to `0.0.0.0`, `::`, or another non-loopback host fails unless `--allow-remote-bind` is provided. Use that flag only behind explicit network access controls.
66
70
 
@@ -92,7 +96,7 @@ Haechi includes protocol adapter presets for OpenAI-compatible servers, vLLM, Ol
92
96
  }
93
97
  ```
94
98
 
95
- Then point an OpenAI-compatible client at `http://127.0.0.1:1016/v1`. For Ollama native APIs, use `target.adapter: "ollama"` and call `/api/chat` or `/api/generate` through the proxy.
99
+ Then point an OpenAI-compatible client at `http://127.0.0.1:11016/v1`. For Ollama native APIs, use `target.adapter: "ollama"` and call `/api/chat` or `/api/generate` through the proxy.
96
100
 
97
101
  ## Token Round-Trip
98
102
 
@@ -187,7 +191,7 @@ The satellites are `node:`-only by default (heavy SDKs are optional peers) and k
187
191
  | `mode` / `policy.mode` | `dry-run` | `dry-run` and `report-only` detect + audit only; `enforce` transforms/blocks. `policy.mode` wins over `mode` |
188
192
  | `target.type` / `target.adapter` | `llm-http` / `openai-compatible` | Upstream protocol: `openai-compatible`, `vllm-openai`, `ollama`, `llama-cpp`. Unknown types fail closed |
189
193
  | `target.upstream` | `http://127.0.0.1:9999` | The only upstream the proxy will forward to (absolute-URL request targets are rejected) |
190
- | `proxy.host` / `proxy.port` | `127.0.0.1` / `1016` | Proxy bind address. See remote binding below |
194
+ | `proxy.host` / `proxy.port` | `127.0.0.1` / `11016` | Proxy bind address. See remote binding below |
191
195
  | `responseProtection.enabled` | `false` | Inspect upstream JSON responses. `failureMode: fail-closed` rejects non-JSON/compressed/oversized responses |
192
196
  | `responseProtection.maxBytes` | `1048576` | Hard response size cap — enforced even in `failureMode: allow` |
193
197
  | `streaming.requestMode` | `block` | `block` 501s streaming; `inspect` stream-filters SSE/NDJSON responses; `pass-through` forwards uninspected (audited). Ollama chat/generate count as streaming unless `stream: false` |
@@ -228,7 +232,7 @@ haechi proxy --config haechi.config.json --host 0.0.0.0 --allow-remote-bind
228
232
 
229
233
  **The proxy has no client authentication yet** (planned for 0.6): anyone who can reach the port can use your upstream and the token round-trip path. Use `--allow-remote-bind` only behind explicit network controls:
230
234
 
231
- - **Containers**: binding `0.0.0.0` inside a container is the normal pattern — restrict exposure at the port mapping, e.g. `-p 127.0.0.1:1016:1016`
235
+ - **Containers**: binding `0.0.0.0` inside a container is the normal pattern — restrict exposure at the port mapping, e.g. `-p 127.0.0.1:11016:11016`
232
236
  - **LAN/remote**: put a firewall, VPN (e.g. Tailscale), or an authenticating reverse proxy in front
233
237
 
234
238
  ## Privacy Profiles
@@ -11,7 +11,7 @@
11
11
  {
12
12
  "mode": "dry-run",
13
13
  "target": { "type": "llm-http", "adapter": "openai-compatible", "upstream": "http://127.0.0.1:9999" },
14
- "proxy": { "host": "127.0.0.1", "port": 1016 },
14
+ "proxy": { "host": "127.0.0.1", "port": 11016 },
15
15
  "responseProtection": { "enabled": false, "mode": "enforce", "failureMode": "fail-closed", "allowNonJson": false, "allowCompressed": false, "maxBytes": 1048576 },
16
16
  "streaming": { "requestMode": "block" },
17
17
  "limits": { "maxRequestBytes": 1048576, "upstreamTimeoutMs": 120000 },
@@ -44,7 +44,7 @@
44
44
  | 키 | 타입 / 값 | 기본값 | 설명 |
45
45
  |---|---|---|---|
46
46
  | `proxy.host` | 비어 있지 않은 문자열 | `127.0.0.1` | 바인드 주소. loopback이 아닌 host를 사용하려면 `--allow-remote-bind` CLI 플래그가 필요하다 — 설정 파일만으로는 시작되지 않는다([loopback 밖으로 바인딩](#binding-beyond-loopback) 참고). |
47
- | `proxy.port` | 정수 0–65535 | `1016` | 리슨 포트(`0` = 임시 포트). `--port`로 실행 시마다 덮어쓸 수 있다. |
47
+ | `proxy.port` | 정수 0–65535 | `11016` | 리슨 포트(`0` = 임시 포트). `--port`로 실행 시마다 덮어쓸 수 있다. |
48
48
 
49
49
  ## `responseProtection`
50
50
 
@@ -246,7 +246,7 @@ proxy는 CLI 플래그를 명시적으로 전달하지 않으면 loopback이 아
246
246
  haechi proxy --config haechi.config.json --host 0.0.0.0 --allow-remote-bind
247
247
  ```
248
248
 
249
- **proxy는 아직 클라이언트 인증을 제공하지 않는다**(0.6 계획): 포트에 접근할 수 있는 누구든 upstream과 token round-trip 경로를 사용할 수 있다. `--allow-remote-bind`는 명시적인 네트워크 통제 하에서만 사용해야 한다 — 컨테이너 내에서 `0.0.0.0`으로 바인드하고 host 포트 매핑을 제한하거나(`-p 127.0.0.1:1016:1016`), 방화벽/VPN/인증 reverse proxy 뒤에 두어야 한다.
249
+ **proxy는 아직 클라이언트 인증을 제공하지 않는다**(0.6 계획): 포트에 접근할 수 있는 누구든 upstream과 token round-trip 경로를 사용할 수 있다. `--allow-remote-bind`는 명시적인 네트워크 통제 하에서만 사용해야 한다 — 컨테이너 내에서 `0.0.0.0`으로 바인드하고 host 포트 매핑을 제한하거나(`-p 127.0.0.1:11016:11016`), 방화벽/VPN/인증 reverse proxy 뒤에 두어야 한다.
250
250
 
251
251
  ## 검증 요약
252
252
 
@@ -11,7 +11,7 @@
11
11
  {
12
12
  "mode": "dry-run",
13
13
  "target": { "type": "llm-http", "adapter": "openai-compatible", "upstream": "http://127.0.0.1:9999" },
14
- "proxy": { "host": "127.0.0.1", "port": 1016 },
14
+ "proxy": { "host": "127.0.0.1", "port": 11016 },
15
15
  "responseProtection": { "enabled": false, "mode": "enforce", "failureMode": "fail-closed", "allowNonJson": false, "allowCompressed": false, "maxBytes": 1048576 },
16
16
  "streaming": { "requestMode": "block" },
17
17
  "limits": { "maxRequestBytes": 1048576, "upstreamTimeoutMs": 120000 },
@@ -44,7 +44,7 @@
44
44
  | Key | Type / values | Default | Notes |
45
45
  |---|---|---|---|
46
46
  | `proxy.host` | non-empty string | `127.0.0.1` | Bind address. Non-loopback hosts require the `--allow-remote-bind` CLI flag — config alone will not start (see [Binding beyond loopback](#binding-beyond-loopback)). |
47
- | `proxy.port` | integer 0–65535 | `1016` | Listen port (`0` = ephemeral). Override per-run with `--port`. |
47
+ | `proxy.port` | integer 0–65535 | `11016` | Listen port (`0` = ephemeral). Override per-run with `--port`. |
48
48
 
49
49
  ## `responseProtection`
50
50
 
@@ -246,7 +246,7 @@ The proxy refuses non-loopback hosts unless the CLI flag is passed explicitly
246
246
  haechi proxy --config haechi.config.json --host 0.0.0.0 --allow-remote-bind
247
247
  ```
248
248
 
249
- **The proxy has no client authentication yet** (planned for 0.6): anyone who can reach the port can use your upstream and the token round-trip path. Use `--allow-remote-bind` only behind explicit network controls — bind `0.0.0.0` inside a container and restrict the host port mapping (`-p 127.0.0.1:1016:1016`), or front it with a firewall/VPN/authenticating reverse proxy.
249
+ **The proxy has no client authentication yet** (planned for 0.6): anyone who can reach the port can use your upstream and the token round-trip path. Use `--allow-remote-bind` only behind explicit network controls — bind `0.0.0.0` inside a container and restrict the host port mapping (`-p 127.0.0.1:11016:11016`), or front it with a firewall/VPN/authenticating reverse proxy.
250
250
 
251
251
  ## Validation cheatsheet
252
252
 
@@ -83,7 +83,7 @@ docs/
83
83
 
84
84
  | Mode | 변경 범위 | 적합한 상황 | 예시 |
85
85
  |---|---|---|---|
86
- | Local proxy | 코드 변경 거의 없음 | LLM HTTP, MCP Streamable HTTP를 빠르게 보호 | base URL을 `http://localhost:1016`로 변경 |
86
+ | Local proxy | 코드 변경 거의 없음 | LLM HTTP, MCP Streamable HTTP를 빠르게 보호 | base URL을 `http://localhost:11016`로 변경 |
87
87
  | SDK wrapper | 작은 코드 변경 | 앱 내부 context를 더 정확히 전달 | `haechi.protectMessage(...)` |
88
88
  | Middleware | 웹/API 서버에 삽입 | Express/Fastify/FastAPI 같은 gateway | request/response hook |
89
89
  | Sidecar | self-hosted service 옆 배치 | 컨테이너/서버 운영 환경 | app -> sidecar -> provider |
@@ -83,7 +83,7 @@ For the initial public release, `core`, `crypto`, `policy`, `filter`, `audit`, `
83
83
 
84
84
  | Mode | Scope of change | When to use | Example |
85
85
  |---|---|---|---|
86
- | Local proxy | Almost no code changes | Quickly protect LLM HTTP or MCP Streamable HTTP | Change base URL to `http://localhost:1016` |
86
+ | Local proxy | Almost no code changes | Quickly protect LLM HTTP or MCP Streamable HTTP | Change base URL to `http://localhost:11016` |
87
87
  | SDK wrapper | Small code changes | Pass more precise in-app context | `haechi.protectMessage(...)` |
88
88
  | Middleware | Insert into web/API server | Gateways like Express/Fastify/FastAPI | request/response hook |
89
89
  | Sidecar | Deploy alongside self-hosted service | Container/server runtime environments | app -> sidecar -> provider |
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "proxy": {
9
9
  "host": "127.0.0.1",
10
- "port": 1016
10
+ "port": 11016
11
11
  },
12
12
  "responseProtection": {
13
13
  "enabled": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "haechi",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Self-hosted AI context enforcement across LLM, MCP, vLLM, Ollama, and agent traffic — a stable, zero-dependency security gateway.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -92,7 +92,7 @@ async function initCommand(argv) {
92
92
  mode: result.config.mode,
93
93
  warnings: [
94
94
  "The generated .haechi/dev.keys.json file is for local development only.",
95
- "Haechi 0.3.x does not include a production KMS/HSM/Vault key provider."
95
+ "Core ships no production KMS/HSM/Vault key provider; KMS/Vault-backed custody is available via the haechi-crypto-kms satellite (external cryptoProvider)."
96
96
  ]
97
97
  });
98
98
  }
@@ -306,7 +306,7 @@ export function normalizeConfig(config) {
306
306
  throw new Error("audit.anchor.everyRecords must be a positive integer");
307
307
  }
308
308
  if (merged.tokenVault.provider !== "local") {
309
- throw new Error("0.2 only supports local token vault provider");
309
+ throw new Error("Only the local token vault provider is supported");
310
310
  }
311
311
  if (!["disabled", "local-dev"].includes(merged.tokenVault.revealPolicy)) {
312
312
  throw new Error(`Invalid tokenVault.revealPolicy: ${merged.tokenVault.revealPolicy}`);
@@ -2,7 +2,7 @@ import { createServer } from "node:http";
2
2
  import { createHash, randomUUID } from "node:crypto";
3
3
  import { inspectResponseStream } from "../stream-filter/index.mjs";
4
4
 
5
- export const DEFAULT_PROXY_PORT = 1016;
5
+ export const DEFAULT_PROXY_PORT = 11016;
6
6
 
7
7
  export function createHaechiProxy({ runtime, port = DEFAULT_PROXY_PORT, host = "127.0.0.1", allowRemoteBind = false }) {
8
8
  assertSafeProxyBind({ host, allowRemoteBind });