Skip to content
This page is a translation of the authoritative Chinese source and may lag behind.View the original

Audit and security configuration

This chapter covers the audit records of config changes, and the console's security settings. The audit log has a console page (admin only); a few security capabilities (like manual IP banning) deliberately have no UI — a design trade-off this chapter explains honestly.

Audit logs

Audit logs record config-change operations in the console (create/delete/modify), login/logout, password changes, and other security events, complementing request logs (Logs and body storage, which record every API call).

How to view: after logging in as admin, go to Settings → Audit (admin only). The page supports filtering by actor (substring match), action type, entity type, and time range, browsed in reverse-chronological pagination; click any row to view the change detail (diff and metadata). The corresponding API is GET /console/api/audit-logs (admin only), see the "Audit logs" section of the Console API docs. Reading audit logs itself does not produce an audit record.

Fields of each audit record:

FieldDescription
actorThe initiating subject: console username; secret_key (secret-key bearer direct call); api_key:<mask> (initiated by an access-key holder, e.g. MCP tool call, context refresh)
actionFor config entities, CRUD actions like create / update / delete; also rotate (access-key credential rotation) / batch_update / batch_commit / import (SSO credentials); for security events, login.success / login.failure / logout / change_password / admin_change_password / sessions.revoke_all; for MCP events with a subject, tool.call / acl.violation / mcp.context.refreshed
entity_typeaccess_key / upstream / model / model_pricing / mcp_server / console_user / console_session / load_balancer / lb_static_binding / lb_static_binding_pin / sso_credential / search_provider (search engine) / search_config (search config) / batch; MCP tool calls and ACL violations are mcp, client-initiated MCP session refresh is mcp_context
entity_idThe affected entity's identifier
diffThe change difference (for update / rotate), truncated when too long; credential fields (api_key / api_keys / auth_header) only record masks, never plaintext
ip_addressThe actor's IP
request_idThe z-request-id header (if present)
occurred_atEvent time (UTC)

Audit only records events with an initiating subject. Subject-less system self-driven behavior (MCP server startup registration, session eviction) doesn't enter the audit table — it goes to runtime logs. Audit answers "who did what to which"; system self-description belongs to the operator side.

Writes are "fire-and-forget": an audit-write failure doesn't affect the main operation, only alerts. MCP tool calls and ACL violations are also recorded in the audit log. Audit rows persist in both SQLite and PostgreSQL storage modes (STORAGE_MODE has only these two legal values; there is no configurable memory mode). Note this is orthogonal to the distributed-state backend (the Redis / memory backend determined by whether REDIS_URL is configured, managing sessions, rate limits, broadcast) — whether audit persists depends only on the persistence storage backend, unrelated to Redis.

Note: audit logs are positioned as operational metadata, not equivalent to a full audit system. For stronger guarantees in production-grade compliance auditing, combine with external log collection.

IP banning

Console login brute-force protection is handled automatically by IP banning:

  • Reaching CONSOLE_MAX_FAILURES (default 5) consecutive login failures → auto-temporarily ban that IP for CONSOLE_BAN_DURATION (default 300 seconds).
  • Bans are stored in memory (lost on restart) and in Redis (persistent across instances).

There is no manual ban/unban entry. This is intentional: manual IP management is a WAF (Web Application Firewall) responsibility, not the gateway's. For manual IP control, deploy a WAF or reverse proxy in front of the gateway.

Rate limiting

Three layers of rate limiting:

LayerConfigDefault
Per access keyRATE_LIMIT_RPM / RATE_LIMIT_WINDOW_SECSdisabled; when enabled 120 req/min
Per IPIP_RATE_LIMIT_RPMdisabled
Per upstream / per modelrpm / max_concurrency / tpm / tps_min_interval_ms / wait_timeout_secs (default 10s) / initial_tokens (0–100, default 100) (console database side)configured as needed

Read-only snapshot: GET /console/api/rate-limit-status returns each layer's current token/concurrency occupancy. Per-key rate limiting is configured via environment variables, per-upstream / per-model in the console, with no separate write API.

Callers hitting a limit receive HTTP 429 Too Many Requests. Only per-upstream / per-model rate limiting carries a Retry-After response header (seconds, the wait until next availability); the 429 from per-access-key and per-IP rate limiting carries no such header. The three sources of 429 and how to tell them apart are in Error codes.

Access-key masking

The list shows only the first/last 4 chars of a key (e.g. sk-a***xxxx). The full value is fetched on demand only via "Copy" (GET /access-keys/{name}/api-key); anonymous keys don't support fetching the full value. The upstream's API key is never exposed in the console.

Password policy

  • bcrypt-hashed storage.
  • New/reset/change all require ≥ 8 characters.
  • Disabling a console user → that user's existing sessions are immediately revoked.

Security response headers

Console routes uniformly carry:

HeaderValue
X-Content-Type-Optionsnosniff
X-Frame-OptionsDENY
Referrer-Policy(policy value)
Content-Security-Policy(policy value)

FAQ

Q: I can't find the audit-log page in the console? The Audit page is in Settings → Audit, admin only. If you log in as monitor, the sidebar doesn't show that entry (by design, not a bug).

Q: How do I manually ban a malicious IP? You can't; the gateway provides no manual banning. IP banning is automatic (failure-count triggered). For manual IP control use a WAF/reverse proxy.

Q: I locked myself out of login? Wait for the ban timeout (default 300 seconds) to auto-release. Or have an admin adjust CONSOLE_MAX_FAILURES/CONSOLE_BAN_DURATION (requires a container restart).

Q: Can I turn off the access-key list mask to see full values? No, masking is mandatory. To get the full value use that row's "Copy" button (fetches it once via API).

Next: Configure Header ACL access rules for admission control; Logs and body storage for request logs; Access key and key group fields for key management; Environment variable reference for all environment variables.