freshcrate
Home > Infrastructure > gproxy

gproxy

gproxy is a Rust-based multi-channel LLM proxy that exposes OpenAI / Claude / Gemini-style APIs through a unified gateway, with a built-in admin console, user/key management, and request/usage auditin

Description

gproxy is a Rust-based multi-channel LLM proxy that exposes OpenAI / Claude / Gemini-style APIs through a unified gateway, with a built-in admin console, user/key management, and request/usage auditing.

README

Deployment Guide

Build

Single-instance release build:

cargo build -p gproxy --release

If you changed the embedded console frontend, build it before packaging or running the binary:

cd frontend/console
pnpm install
pnpm build

The output binary is located at target/release/gproxy.

Embedded Console

The current binary includes an embedded browser console mounted at /console.

  • Console URL: http://127.0.0.1:8787/console
  • Browser login: POST /login
  • Browser auth header: Authorization: Bearer <session_token>

Typical local workflow:

cd frontend/console
pnpm install
pnpm build

cargo run -p gproxy

Then open /console in a browser and log in with a current v1 username and password.

Environment Variables

The full set of startup parameters and their corresponding environment variables are defined in apps/gproxy/src/main.rs:

Environment Variable Default Required Description
GPROXY_HOST 127.0.0.1 No Listen address.
GPROXY_PORT 8787 No Listen port.
GPROXY_ADMIN_USER admin No Bootstrap admin username used when creating or reconciling the admin account.
GPROXY_ADMIN_PASSWORD None No Bootstrap admin password. On first startup, if an admin account must be created and no password is provided, one is generated and logged once.
GPROXY_ADMIN_API_KEY None No Bootstrap admin API key. On first startup, if an admin account must be created and no API key is provided, one is generated and logged once.
GPROXY_DSN If unset, sqlite://<data_dir>/gproxy.db?mode=rwc is generated automatically. No Database DSN.
GPROXY_PROXY None No Upstream HTTP proxy.
GPROXY_SPOOF chrome_136 No TLS fingerprint emulation name.
DATABASE_SECRET_KEY None No Database-at-rest encryption key; when set, credentials, passwords, and API keys are encrypted at rest with XChaCha20Poly1305.
GPROXY_REDIS_URL None No Redis DSN; the Redis backend is enabled only when the binary is built with the redis feature.
GPROXY_CONFIG gproxy.toml No TOML config path used as the seed file during first-time initialization.
GPROXY_DATA_DIR ./data No Data directory; the default SQLite file and runtime data are based on this directory.

Additional Notes:

  • CLI arguments and environment variables are both parsed by clap; explicit CLI values take priority over defaults.
  • If the database already contains global_settings and GPROXY_DSN / GPROXY_DATA_DIR were not passed explicitly at startup, the process will reconnect to the database using the persisted configuration.

TOML Config Format

The TOML file pointed to by GPROXY_CONFIG is only used during initialization when the database does not already contain data. The corresponding structure is defined in crates/gproxy-api/src/admin/config_toml.rs.

[global]
host = "0.0.0.0"
port = 8787
proxy = "http://127.0.0.1:7890"
spoof_emulation = "chrome_136"
update_source = "github"
enable_usage = true
enable_upstream_log = false
enable_upstream_log_body = false
enable_downstream_log = false
enable_downstream_log_body = false
dsn = "sqlite://./data/gproxy.db?mode=rwc"
data_dir = "./data"

[[providers]]
name = "openai-main"
channel = "openai"
settings = { base_url = "https://api.openai.com/v1" }
credentials = [
  { api_key = "sk-provider-1" }
]

[[models]]
provider_name = "openai-main"
model_id = "gpt-4.1-mini"
display_name = "GPT-4.1 mini"
enabled = true
price_each_call = 0.0

[[model_aliases]]
alias = "chat-default"
provider_name = "openai-main"
model_id = "gpt-4.1-mini"
enabled = true

[[users]]
name = "alice"
password = "plain-text-or-argon2-phc"
enabled = true

[[users.keys]]
api_key = "sk-user-1"
label = "default"
enabled = true

[[permissions]]
user_name = "alice"
provider_name = "openai-main"
model_pattern = "gpt-*"

[[file_permissions]]
user_name = "alice"
provider_name = "openai-main"

[[rate_limits]]
user_name = "alice"
model_pattern = "gpt-*"
rpm = 60
rpd = 10000
total_tokens = 200000

[[quotas]]
user_name = "alice"
quota = 100.0
cost_used = 0.0

Field Descriptions:

  • [global] covers global listen address, logging, update source, DSN, and data directory configuration.
  • [[providers]] defines a provider; settings and credentials are both JSON values read via serde_json::Value.
  • [[models]] / [[model_aliases]] define forwardable models and their aliases.
  • Admin access is represented by [[users]] entries with is_admin = true and at least one enabled [[users.keys]] entry. If the seed config does not define such an admin, startup can bootstrap one from GPROXY_ADMIN_USER, GPROXY_ADMIN_PASSWORD, and GPROXY_ADMIN_API_KEY.
  • The password field under [[users]] can be either plaintext or a direct Argon2 PHC hash.
  • [[users.keys]] is a nested array table representing the user's API key list.
  • [[permissions]], [[file_permissions]], [[rate_limits]], and [[quotas]] correspond to model permissions, file permissions, rate limiting, and cost quotas respectively.

Database Support

gproxy-storage compiles in three database backends via SeaORM / SQLx:

Database DSN Prefix Description
SQLite sqlite: Default mode; if GPROXY_DSN is not set explicitly, startup generates a SQLite file DSN automatically.
PostgreSQL postgres: Provided by sqlx-postgres and the SeaORM Postgres feature.
MySQL mysql: Provided by sqlx-mysql and the SeaORM MySQL feature.

Common DSN examples:

sqlite://./data/gproxy.db?mode=rwc
postgres://gproxy:secret@127.0.0.1:5432/gproxy
mysql://gproxy:secret@127.0.0.1:3306/gproxy

After establishing the connection, SeaOrmStorage::connect() will:

  1. Optionally load the database encryptor corresponding to DATABASE_SECRET_KEY.
  2. Apply per-database connection tuning parameters.
  3. Connect to the database and run sync() to synchronize the schema.

Graceful Shutdown

Graceful shutdown behavior is jointly implemented by apps/gproxy/src/main.rs and apps/gproxy/src/workers/mod.rs:

  1. The process listens for Ctrl+C; on Unix it also listens for SIGTERM.
  2. Once shutdown is triggered, the Axum server enters the with_graceful_shutdown flow and stops accepting new requests.
  3. The main thread then calls worker_set.shutdown(), broadcasting the shutdown signal to all workers.
  4. WorkerSet waits up to 5 seconds for workers to drain.
  5. UsageSink closes its receiver, drains remaining usage messages, and performs a final batch write.
  6. HealthBroadcaster flushes any health states still in its debounce window to the database.
  7. QuotaReconciler and RateLimitGC exit their next loop iteration upon receiving the signal.
  8. If any workers have not finished within 5 seconds, the process logs a warning but does not block indefinitely.

Release History

VersionChangesUrgencyDate
v1.0.18## v1.0.18 > Streaming usage 端到端打通(`stream_options.include_usage` 自动注入 + 所有跨协议流式路径都观察上游 usage),mimalloc 接管全局分配器,缓存流水线重排为 magic → rules → flatten 并用 sanitize 统一清理空块/空消息 + 自动把 cache_control 回迁到最近可缓存块,`context-1m-2025-08-07` beta 在 anthropic / claudecode 渠道默认剥离,一次性迁移扫掉指向已废弃 realtime 变体的 routing 规则,控制台新增「恢复默认路由」按钮。 ### English #### Added - **Upstream streaming usage tracking.** The engine now observes and records upstream usage on streaming requests across every cross-protocol path, not just theHigh4/21/2026
v1.0.17## v1.0.17 > The suffix-variant rewrite pipeline is repaired end-to-end: the engine was passing `&[]` as the rewrite rule slice, the handler was letting alias resolution replace the user-sent model name (so `model_pattern` never matched), and `body.model = "provider/variant"` from OpenAI-style clients rode the `provider/` prefix straight into the filter. All three are fixed — a request to `claudecode/claude-opus-4-7-thinking-adaptive-effort-max` now actually reaches Anthropic with `thinking.disHigh4/17/2026
v1.0.11## v1.0.11 > End-to-end upstream latency tracking (TTFB + total) from transport layer to DB to console, a new dashboard module with credential health / KPI / traffic charts, protocol-aware auth for custom channel dispatch routes, and a LogGuard that finally flushes request logs on panic and stream cancel. ### English #### Added - **Upstream latency tracking end-to-end.** The transport layer now captures TTFB (`initial_latency_ms`) and total request duration (`total_latency_ms`) on every upstHigh4/15/2026
v1.0.10## v1.0.10 > Two focused fixes from the v1.0.9 fallout: claudecode OAuth refresh was broken against Anthropic's token endpoint and left credentials permanently dead, and the sanitize middleware was leaking `anthropic-version` through so every upstream request carried a duplicated header. ### English #### Fixed - **claudecode OAuth refresh actually works again.** The v1.0.9 gproxy-channel refactor routed `refresh_credential`'s `refresh_token` path through the generic `oauth2_refresh::refresh_High4/14/2026
v1.0.8## v1.0.8 > **Cross-protocol error bodies finally make it to the client in the > right schema, orphaned `tool_result` messages stop breaking Claude > requests, and streaming upstream logs now store the actual wire > bytes.** The headline fix: when a Claude/Gemini/OpenAI upstream > returns a non-2xx error body, the engine now converts it to the > client's declared error shape (e.g. Claude `{"type":"error",...}` → > OpenAI `{"error":{...}}`) instead of handing the raw JSON to an SDK > that can't High4/14/2026
v1.0.4## v1.0.4 ### English #### Added - **Channel-level rewrite rules** — new `rewrite_rules` field on all 14 channel Settings structs allows per-channel request body rewriting before the request is finalized. Rules support JSON path targeting with glob matching. A dedicated `RewriteRulesEditor` component with full i18n is available in the console. - **Dispatch template presets for custom channel** — the console now offers built-in dispatch template presets when configuring custom channeHigh4/11/2026
v0.3.42## v0.3.42 ### English #### Added - Added CORS handling for provider routes. Provider endpoints now respond to browser preflight requests and include permissive `access-control-allow-origin` headers on proxied responses. - Added the optional ClaudeCode setting `claudecode_flatten_system_text_before_cache_control`, allowing system text blocks to be merged before cache-control processing when needed. #### Changed - ClaudeCode account handling now records and propagates `account_uuid` in more Medium4/1/2026

Dependencies & License Audit

Loading dependencies...

Similar Packages

copilot-api🚀 Access the reverse-engineered GitHub Copilot API through this proxy, enabling streamlined integration for your development needs.main@2026-04-21
prompts.chatf.k.a. Awesome ChatGPT Prompts. Share, discover, and collect prompts from the community. Free and open source — self-host for your organization with complete privacy.main@2026-04-21
ai-guideProvide free, open access to comprehensive AI tools, guides, reviews, and resources to reduce knowledge gaps and empower users.main@2026-04-21
LeanKGLeanKG: Stop Burning Tokens. Start Coding Lean.v0.16.5
new-apiA unified AI model hub for aggregation & distribution. It supports cross-converting various LLMs into OpenAI-compatible, Claude-compatible, or Gemini-compatible formats. A centralized gateway for persv0.12.14