A minimal New-API fork for token usage auditing
This repository is an audit-focused fork of QuantumNous/new-api.
It is not a new gateway implementation and does not change New-API's core business logic. It only adds a small set of audit collection hooks that asynchronously report parsed request metadata and settled token usage to an independent token-audit service.
The goal is to support internal enterprise token auditing:
- Report token usage by user and token within a time range.
- Classify requests such as coding, debugging, architecture, operations, documentation, code review, data analysis, suspected non-work, and other.
- Trace every suspected non-work or uncertain request back to user, token, model, time, token usage, and prompt preview.
- Keep New-API upgrade cost low by leaving classification, reports, review workflow, and WeCom push in the independent audit service.
The custom changes are limited to three files:
| File | Purpose |
|---|---|
audit/sender.go |
Adds audit event sender: environment config, HMAC signing, non-blocking queue, async HTTP reporting |
controller/relay.go |
Sends request events after request parsing, including user, token, model, path, format, prompt hash, prompt preview, and full prompt |
model/log.go |
Sends usage events after consumption logging, including prompt tokens, completion tokens, quota, channel, group, duration, and upstream request id |
New-API reports two event types to the audit service:
POST /internal/new-api/audit/request
POST /internal/new-api/audit/usage
Every request is signed with:
X-Audit-Timestamp
X-Audit-Signature
Signature algorithm:
hex(hmac_sha256(timestamp + "." + raw_body, AUDIT_SECRET))
New-API's existing logs and database are good for usage accounting, but not enough for work-purpose auditing:
- The
logstable records user, token, model, quota, token counts, andrequest_id, but not prompt content. - Parsing Docker logs with regular expressions is fragile across multiple nodes, log rotation, format changes, and streaming requests.
- Writing audit data into New-API business tables increases upgrade risk and couples audit logic to gateway logic.
- Token counts alone cannot prove whether a request was used for work. Prompt evidence, classification results, and manual review are required.
This fork therefore uses a "minimal New-API collection + independent audit processing" approach:
- New-API only reports request and usage events at stable hook points.
request_idlinks prompt data with final usage.- Reporting uses an async non-blocking queue, so audit service failures do not block API requests.
- Full prompts are not written to the New-API main database; they are encrypted and stored by the audit service.
- The audit service uses a local SQLite file database by default in production, with a 30-day retention policy. No extra MySQL service is required.
- Classification, reports, manual review, and push notifications evolve independently in
token-audit.
CPA / Client
|
v
patched New-API
| 1. report request event after parsing
| 2. report usage event after settlement
v
token-audit service
|
| request_id links prompt and token usage
v
independent audit SQLite file database
|
v
classification, reports, review, WeCom push
New-API still handles authentication, routing, forwarding, billing, and normal logging exactly as before. Audit reporting failures are logged but do not affect user requests.
This fork adds the following New-API environment variables:
| Variable | Default | Description |
|---|---|---|
AUDIT_ENABLED |
false |
Enable audit reporting |
AUDIT_ENDPOINT |
empty | Audit service base URL, for example http://token-audit:8000 |
AUDIT_SECRET |
empty | Shared HMAC secret between New-API and audit service |
AUDIT_TIMEOUT_MS |
800 |
Per-event reporting timeout in milliseconds |
AUDIT_QUEUE_SIZE |
1000 |
Async reporting queue size |
AUDIT_MAX_EVENT_BYTES |
1048576 |
Maximum serialized audit event size in bytes; oversized request events omit full prompt text and send only hash/preview/length, while other oversized events are dropped |
AUDIT_EXCLUDED_TOKEN_NAMES |
empty | Comma-separated token names excluded from audit, used for the audit classifier token |
Recommended configuration:
AUDIT_ENABLED=true
AUDIT_ENDPOINT=http://token-audit:8000
AUDIT_SECRET=replace-with-long-random-secret
AUDIT_TIMEOUT_MS=800
AUDIT_QUEUE_SIZE=1000
AUDIT_MAX_EVENT_BYTES=1048576
AUDIT_EXCLUDED_TOKEN_NAMES=audit-classifierRecommended production rollout:
- Deploy the independent
token-auditservice first. The audit database is a local SQLite file, for example/opt/token-audit/data/token_audit.db. - Build and deploy this fork's New-API image with
AUDIT_ENABLED=false. - Confirm CPA, New-API, and upstream model calls still work normally.
- Set
AUDIT_ENABLED=trueand enter shadow reporting mode. - Compare New-API
logswith the audit database by request count, token count, andrequest_idlink rate. - After reconciliation is stable, enable classification jobs, daily/weekly reports, and WeCom push.
Docker Compose example:
services:
new-api:
image: your-registry/new-api-audit:audit-hook
environment:
AUDIT_ENABLED: "true"
AUDIT_ENDPOINT: "http://token-audit:8000"
AUDIT_SECRET: "${AUDIT_SECRET}"
AUDIT_TIMEOUT_MS: "800"
AUDIT_QUEUE_SIZE: "1000"
AUDIT_MAX_EVENT_BYTES: "1048576"
AUDIT_EXCLUDED_TOKEN_NAMES: "audit-classifier"
depends_on:
- token-auditLocal build:
docker build -t new-api-audit:audit-hook .This fork was locally verified with:
gofmt -w audit/sender.go controller/relay.go model/log.go
git diff --check
go test ./audit ./model ./controller -run '^$'Notes:
-run '^$'verifies that affected packages compile without running existing test cases.- A full local
go test ./audit ./model ./controllercurrently hits an existing upstream SQLite initialization failure incontroller; it is not caused by the audit hook. - Run a full CI or image-build verification before production rollout.
Audit data can contain sensitive prompts. Deploy it according to internal compliance requirements:
- Keep
AUDIT_ENDPOINTon Docker/internal networks. Do not expose it publicly. - Use a high-entropy
AUDIT_SECRETand manage it separately from ordinary New-API config. - Do not store full prompts in the New-API main database; let the audit service encrypt them at application level.
- Reports should show prompt previews by default. Full prompt text should only be decryptable for internal admin review.
- If the classifier calls models through New-API, use a dedicated token and include it in
AUDIT_EXCLUDED_TOKEN_NAMES.
The fork keeps the custom change surface small so it can follow upstream New-API:
git remote add upstream https://github.com/QuantumNous/new-api.git
git fetch upstream --tags
git switch -c upgrade/upstream-vX.Y.Z
git merge --no-ff vX.Y.Z
gofmt -w audit/sender.go controller/relay.go model/log.go
go test ./audit ./model ./controller -run '^$'
docker build -t new-api-audit:audit-hook .If a rebase conflict occurs, check:
- The request parsing area in
controller/relay.go, near sensitive-word checks and token estimation. RecordConsumeLoginmodel/log.go.- Whether
common.RequestIdKeyandcommon.UpstreamRequestIdKeystill exist.
- LinuxDO: A high-quality technical community.
This repository keeps New-API's original capabilities and license, and only adds the minimal hooks required for internal auditing.
The current code baseline is upstream v1.0.0-rc.22. New-API may use ClickHouse separately for gateway logs through LOG_SQL_DSN; the standalone token-audit service continues to use its own SQLite audit database, with a different responsibility.
Upstream project references:
Users must still comply with upstream model terms, the original New-API license, and applicable requirements for generative AI services, log retention, privacy, and data security.
