Skip to content

Commit 1bd236e

Browse files
committed
feat: drain soonest-expiring key first; harden admin auth and keys
- drain_first selects the credential with the least remaining time instead of the first in the list; unknown-expiry keys trail known ones - admin writes and restart require BRIDGE_API_KEY; keyless runtime bootstraps only over a loopback peer and loopback Host - drop retired 1.3.1 model IDs from catalog and config filtering - generate 24-byte bridge keys in installer and dashboard - docs: refresh routing, deployment, and security notes
1 parent 0adedcf commit 1bd236e

21 files changed

Lines changed: 700 additions & 487 deletions

README.ko.md

Lines changed: 72 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<p align="center">
2-
<img src="docs/assets/banner.svg" alt="CommandCode Bridge — 신뢰 환경용 OpenAI-compatible CommandCode 게이트웨이" width="880">
2+
<img src="docs/assets/banner.svg" alt="CommandCode Bridge — 신뢰 환경용 OpenAI-compatible CommandCode 게이트웨이" width="880">
3+
34
</p>
45

56
<p align="center">
@@ -106,148 +107,89 @@ curl -sS http://127.0.0.1:9992/v1/chat/completions \
106107

107108
### API 표면
108109

109-
| Method | Path | Behavior |
110-
111-
| --- | --- | --- |
112-
113-
| `GET` | `/health` | Public secret-free health/runtime summary. |
114-
115-
| `GET` | `/dashboard` | 신뢰 network용 public read-only shell. |
116-
117-
| `GET` | `/v1/models` | `BRIDGE_API_KEY` 설정 시 인증; available model 목록. |
118-
119-
| `GET` | `/v1/models/:model` | 설정 시 인증; 단일 available model 조회. |
120-
121-
| `POST` | `/v1/chat/completions` | 설정 시 인증; streaming/non-streaming chat. |
122-
123-
| `GET` | `/admin/config` | 신뢰 network의 public redacted dashboard state. |
124-
125-
| `GET` | `/admin/commandcode/credentials` | Public redacted diagnostics; `?refresh=true`는 billing refresh. |
126-
127-
| `PUT` | `/admin/config` | Same-host/loopback dashboard write; credentials file 필요. |
128-
129-
| `POST` | `/admin/restart` | Same-host/loopback restart 요청. |
110+
| Method | Path | Behavior |
111+
| ------ | -------------------------------- | ------------------------------------------------------------------------------------------------- |
112+
| `GET` | `/health` | Public secret-free health/runtime summary. |
113+
| `GET` | `/dashboard` | 신뢰 network용 public read-only shell. |
114+
| `GET` | `/v1/models` | `BRIDGE_API_KEY` 설정 시 인증; available model 목록. |
115+
| `GET` | `/v1/models/:model` | 설정 시 인증; 단일 available model 조회. |
116+
| `POST` | `/v1/chat/completions` | 설정 시 인증; streaming/non-streaming chat. |
117+
| `GET` | `/admin/config` | 신뢰 network의 public redacted dashboard state. |
118+
| `GET` | `/admin/commandcode/credentials` | Public redacted diagnostics; `?refresh=true`는 billing refresh. |
119+
| `PUT` | `/admin/config` | 현재 `BRIDGE_API_KEY` 인증 필요. key 없는 runtime은 peer와 Host가 모두 loopback일 때만 bootstrap. |
120+
| `POST` | `/admin/restart` | 동일한 인증 규칙 적용. restart가 끝날 때까지 기존 key가 current key. |
130121

131122
### Model metadata와 정확한 catalog
132123

133124
각 model object는 `id`, `object`, `created`, provider 기반 `owned_by`를 포함합니다. 알려진 context는 `context_window`, `context_length`, `max_context_length`에 동일하게 나옵니다. 정확히 5개 model은 공개 context가 없어 세 capacity field를 모두 생략합니다. 아래는 정확한 1.14.0 canonical catalog이며 “기본 활성화”는 built-in enabled state입니다.
134125

135-
| Provider | Canonical model ID | Context | 기본 활성화 |
136-
137-
| --- | --- | ---: | :---: |
138-
139-
| DeepSeek | `deepseek/deepseek-v4-pro` | 1,000,000 ||
140-
141-
| DeepSeek | `deepseek/deepseek-v4-flash` | 1,000,000 ||
142-
143-
| Moonshot | `moonshotai/Kimi-K3` | 1,000,000 | 아니요 |
144-
145-
| Moonshot | `moonshotai/Kimi-K2.7-Code` | 256,000 | 아니요 |
146-
147-
| Moonshot | `moonshotai/Kimi-K2.7-Code-Highspeed` | 262,000 | 아니요 |
148-
149-
| Moonshot | `moonshotai/Kimi-K2.6` | 256,000 ||
150-
151-
| Moonshot | `moonshotai/Kimi-K2.5` | 256,000 | 아니요 |
152-
153-
| Z.ai | `zai-org/GLM-5.2` | 1,000,000 | 아니요 |
154-
155-
| Z.ai | `zai-org/GLM-5.2-Fast` | 1,000,000 | 아니요 |
156-
157-
| Z.ai | `zai-org/GLM-5.1` | 공개되지 않음 ||
158-
159-
| Z.ai | `zai-org/GLM-5` | 200,000 | 아니요 |
160-
161-
| MiniMax | `MiniMaxAI/MiniMax-M3` | 1,000,000 | 아니요 |
162-
163-
| MiniMax | `MiniMaxAI/MiniMax-M2.7` | 공개되지 않음 ||
164-
165-
| MiniMax | `MiniMaxAI/MiniMax-M2.5` | 200,000 | 아니요 |
166-
167-
| Xiaomi | `xiaomi/mimo-v2.5-pro` | 1,000,000 | 아니요 |
168-
169-
| Xiaomi | `xiaomi/mimo-v2.5` | 1,000,000 | 아니요 |
170-
171-
| Qwen | `Qwen/Qwen3.8-Max` | 1,000,000 | 아니요 |
172-
173-
| Qwen | `Qwen/Qwen3.7-Max` | 1,000,000 | 아니요 |
174-
175-
| Qwen | `Qwen/Qwen3.7-Plus` | 1,000,000 | 아니요 |
176-
177-
| Qwen | `Qwen/Qwen3.7-Flash` | 1,000,000 | 아니요 |
178-
179-
| Qwen | `Qwen/Qwen3.6-Max-Preview` | 공개되지 않음 | 아니요 |
180-
181-
| Qwen | `Qwen/Qwen3.6-Plus` | 공개되지 않음 ||
182-
183-
| StepFun | `stepfun/Step-3.7-Flash` | 256,000 | 아니요 |
184-
185-
| StepFun | `stepfun/Step-3.5-Flash` | 1,000,000 | 아니요 |
186-
187-
| Tencent | `tencent/hy3-paid` | 262,000 | 아니요 |
188-
189-
| NVIDIA | `nvidia/nemotron-3-ultra-550b-a55b` | 1,000,000 | 아니요 |
190-
191-
| Thinking Machines | `thinkingmachines/inkling` | 256,000 | 아니요 |
192-
193-
| Thinking Machines | `thinkingmachines/inkling-small` | 1,000,000 | 아니요 |
194-
195-
| Poolside | `poolside/laguna-s-2.1-free` | 256,000 | 아니요 |
196-
197-
| Anthropic | `claude-sonnet-5` | 1,000,000 | 아니요 |
198-
199-
| Anthropic | `claude-sonnet-4-6` | 1,000,000 | 아니요 |
200-
201-
| Anthropic | `claude-fable-5` | 1,000,000 | 아니요 |
202-
203-
| Anthropic | `claude-opus-5` | 1,000,000 | 아니요 |
204-
205-
| Anthropic | `claude-opus-4-8` | 1,000,000 | 아니요 |
206-
207-
| Anthropic | `claude-opus-4-7` | 1,000,000 | 아니요 |
208-
209-
| Anthropic | `claude-haiku-4-5-20251001` | 200,000 | 아니요 |
210-
211-
| OpenAI | `gpt-5.6-sol` | 1,050,000 | 아니요 |
212-
213-
| OpenAI | `gpt-5.6-terra` | 1,050,000 | 아니요 |
214-
215-
| OpenAI | `gpt-5.6-luna` | 1,050,000 | 아니요 |
216-
217-
| OpenAI | `gpt-5.5` | 공개되지 않음 | 아니요 |
218-
219-
| OpenAI | `gpt-5.4` | 400,000 | 아니요 |
220-
221-
| OpenAI | `gpt-5.3-codex` | 400,000 | 아니요 |
222-
223-
| OpenAI | `gpt-5.4-mini` | 400,000 | 아니요 |
224-
225-
| Google | `google/gemini-3.6-flash` | 1,000,000 | 아니요 |
226-
227-
| Google | `google/gemini-3.5-flash` | 1,000,000 | 아니요 |
228-
229-
| Google | `google/gemini-3.5-flash-lite` | 1,000,000 | 아니요 |
230-
231-
| Google | `google/gemini-3.1-flash-lite` | 1,000,000 | 아니요 |
232-
233-
| Sakana | `sakana/fugu-ultra` | 1,000,000 | 아니요 |
234-
235-
| Meta | `meta/muse-spark-1.1` | 1,050,000 | 아니요 |
236-
237-
| Meta | `meta/muse-spark-1.2` | 1,050,000 | 아니요 |
238-
239-
| Meta | `meta/muse-spark-1.2-contributor` | 1,050,000 | 아니요 |
240-
241-
| xAI | `xai/grok-4.5` | 500,000 | 아니요 |
126+
| Provider | Canonical model ID | Context | 기본 활성화 |
127+
| ----------------- | ------------------------------------- | ------------: | :---------: |
128+
| DeepSeek | `deepseek/deepseek-v4-pro` | 1,000,000 ||
129+
| DeepSeek | `deepseek/deepseek-v4-flash` | 1,000,000 ||
130+
| Moonshot | `moonshotai/Kimi-K3` | 1,000,000 | 아니요 |
131+
| Moonshot | `moonshotai/Kimi-K2.7-Code` | 256,000 | 아니요 |
132+
| Moonshot | `moonshotai/Kimi-K2.7-Code-Highspeed` | 262,000 | 아니요 |
133+
| Moonshot | `moonshotai/Kimi-K2.6` | 256,000 ||
134+
| Moonshot | `moonshotai/Kimi-K2.5` | 256,000 | 아니요 |
135+
| Z.ai | `zai-org/GLM-5.2` | 1,000,000 | 아니요 |
136+
| Z.ai | `zai-org/GLM-5.2-Fast` | 1,000,000 | 아니요 |
137+
| Z.ai | `zai-org/GLM-5.1` | 공개되지 않음 ||
138+
| Z.ai | `zai-org/GLM-5` | 200,000 | 아니요 |
139+
| MiniMax | `MiniMaxAI/MiniMax-M3` | 1,000,000 | 아니요 |
140+
| MiniMax | `MiniMaxAI/MiniMax-M2.7` | 공개되지 않음 ||
141+
| MiniMax | `MiniMaxAI/MiniMax-M2.5` | 200,000 | 아니요 |
142+
| Xiaomi | `xiaomi/mimo-v2.5-pro` | 1,000,000 | 아니요 |
143+
| Xiaomi | `xiaomi/mimo-v2.5` | 1,000,000 | 아니요 |
144+
| Qwen | `Qwen/Qwen3.8-Max` | 1,000,000 | 아니요 |
145+
| Qwen | `Qwen/Qwen3.7-Max` | 1,000,000 | 아니요 |
146+
| Qwen | `Qwen/Qwen3.7-Plus` | 1,000,000 | 아니요 |
147+
| Qwen | `Qwen/Qwen3.7-Flash` | 1,000,000 | 아니요 |
148+
| Qwen | `Qwen/Qwen3.6-Max-Preview` | 공개되지 않음 | 아니요 |
149+
| Qwen | `Qwen/Qwen3.6-Plus` | 공개되지 않음 ||
150+
| StepFun | `stepfun/Step-3.7-Flash` | 256,000 | 아니요 |
151+
| StepFun | `stepfun/Step-3.5-Flash` | 1,000,000 | 아니요 |
152+
| Tencent | `tencent/hy3-paid` | 262,000 | 아니요 |
153+
| NVIDIA | `nvidia/nemotron-3-ultra-550b-a55b` | 1,000,000 | 아니요 |
154+
| Thinking Machines | `thinkingmachines/inkling` | 256,000 | 아니요 |
155+
| Thinking Machines | `thinkingmachines/inkling-small` | 1,000,000 | 아니요 |
156+
| Poolside | `poolside/laguna-s-2.1-free` | 256,000 | 아니요 |
157+
| Anthropic | `claude-sonnet-5` | 1,000,000 | 아니요 |
158+
| Anthropic | `claude-sonnet-4-6` | 1,000,000 | 아니요 |
159+
| Anthropic | `claude-fable-5` | 1,000,000 | 아니요 |
160+
| Anthropic | `claude-opus-5` | 1,000,000 | 아니요 |
161+
| Anthropic | `claude-opus-4-8` | 1,000,000 | 아니요 |
162+
| Anthropic | `claude-opus-4-7` | 1,000,000 | 아니요 |
163+
| Anthropic | `claude-haiku-4-5-20251001` | 200,000 | 아니요 |
164+
| OpenAI | `gpt-5.6-sol` | 1,050,000 | 아니요 |
165+
| OpenAI | `gpt-5.6-terra` | 1,050,000 | 아니요 |
166+
| OpenAI | `gpt-5.6-luna` | 1,050,000 | 아니요 |
167+
| OpenAI | `gpt-5.5` | 공개되지 않음 | 아니요 |
168+
| OpenAI | `gpt-5.4` | 400,000 | 아니요 |
169+
| OpenAI | `gpt-5.3-codex` | 400,000 | 아니요 |
170+
| OpenAI | `gpt-5.4-mini` | 400,000 | 아니요 |
171+
| Google | `google/gemini-3.6-flash` | 1,000,000 | 아니요 |
172+
| Google | `google/gemini-3.5-flash` | 1,000,000 | 아니요 |
173+
| Google | `google/gemini-3.5-flash-lite` | 1,000,000 | 아니요 |
174+
| Google | `google/gemini-3.1-flash-lite` | 1,000,000 | 아니요 |
175+
| Sakana | `sakana/fugu-ultra` | 1,000,000 | 아니요 |
176+
| Meta | `meta/muse-spark-1.1` | 1,050,000 | 아니요 |
177+
| Meta | `meta/muse-spark-1.2` | 1,050,000 | 아니요 |
178+
| Meta | `meta/muse-spark-1.2-contributor` | 1,050,000 | 아니요 |
179+
| xAI | `xai/grok-4.5` | 500,000 | 아니요 |
242180

243181
### Dashboard와 credential routing
244182

245183
`http://127.0.0.1:9992/dashboard`를 여십시오. 모바일 우선 UI는 한국어 fallback과 한국어/영어/중국어 locale을 `localStorage`에 저장합니다. online/version 상태를 보여주고 bind, client key, routing, key별 concurrency를 수정하며 redacted credential을 관리·refresh합니다. Model catalog는 provider별 fold와 enabled/total count로 표시됩니다. 빈 secret field는 기존 key를 보존합니다. Save는 JSON을 쓰고 restart가 적용합니다. Raw upstream key는 반환하지 않습니다.
246184

247-
`daily_burn_priority`는 required daily burn을 가중하는 기본값이며 `depletion_aware`는 legacy alias입니다. `balance_priority`는 usable balance, `round_robin`은 smooth weight rotation, `drain_first`eligible key를 우선합니다. 모든 policy는 먼저 1일 안에 만료되는 eligible credential로 범위를 좁힙니다. Manual disable, `allowedModels`, in-flight cap, exhausted/expired balance, auth failure, 429/5xx/timeout cooldown은 key를 제외할 수 있습니다. 요청 하나는 key 하나에 고정되고 visible output 전까지만 failover합니다.
185+
`daily_burn_priority`는 required daily burn을 가중하는 기본값이며 `depletion_aware`는 legacy alias입니다. `balance_priority`는 usable balance, `round_robin`은 smooth weight rotation, `drain_first`남은 기한이 가장 적은 eligible key를 먼저 소진합니다. 모든 policy는 먼저 1일 안에 만료되는 eligible credential로 범위를 좁힙니다. Manual disable, `allowedModels`, in-flight cap, exhausted/expired balance, auth failure, 429/5xx/timeout cooldown은 key를 제외할 수 있습니다. 요청 하나는 key 하나에 고정되고 visible output 전까지만 failover합니다.
248186

249187
### 설정과 운영
250188

189+
저장된 1.3.1 dashboard catalog에서 업그레이드하면 현재 model의 enabled state와 모든 custom model은 보존하고, built-in metadata는 1.14.0 canonical 정의로 갱신합니다. 제거된 1.3.1 ID 6개는 unknown upstream model로 전달하지 않으며, 제거된 default가 설정돼 있으면 `deepseek/deepseek-v4-pro`로 안전하게 fallback합니다.
190+
191+
브라우저에 key가 저장된 기존 사용자는 그대로 동작합니다. 새 브라우저에서는 저장·재시작 전에 **현재 Admin API Key**에 기존 key를 한 번 입력합니다. key 없는 runtime은 실제 loopback 연결이며 Host도 loopback인 경우에만 bootstrap할 수 있습니다.
192+
251193
Credential 우선순위는 `COMMANDCODE_CREDENTIALS_FILE`, `COMMANDCODE_CREDENTIALS`/`COMMANDCODE_API_KEYS`, `COMMANDCODE_API_KEY`, CLI auth file 순입니다. 핵심 기본값은 `HOST=127.0.0.1`, `PORT=9992`, `COMMANDCODE_ROUTING_POLICY=daily_burn_priority`, `COMMANDCODE_MAX_IN_FLIGHT_PER_CREDENTIAL=4`, `COMMANDCODE_CLI_VERSION=1.14.0`, `COMMANDCODE_TIMEOUT_MS=300000`, `COMMANDCODE_EMPTY_VISIBLE_RESPONSE_POLICY=error_on_length`입니다. `BRIDGE_API_KEY`는 설정 시 `/v1/*`를 보호하며 client는 Bearer 또는 `x-api-key`를 쓸 수 있습니다. Credential JSON은 `chmod 600`으로 보호하십시오. Balance alert는 기본 off입니다. 선택적 `commandcode-router`는 여러 bridge host의 least-in-flight routing용입니다.
252194

253195
## 동작 방식

0 commit comments

Comments
 (0)