审计与安全配置
本章讲配置变更的审计记录,以及控制台的安全设置。审计日志有控制台页面(仅 admin);个别安全能力(如手动 IP 封禁)有意不做界面,属设计取舍,本章如实说明。
审计日志
审计日志记录控制台里的配置变更操作(增/删/改)、登录/登出与密码修改等安全事件,与请求日志(日志与日志体存储,记录每次 API 调用)互补。
查看方式:管理员登录后,进入 Settings → Audit(仅 admin 可见)。页面支持按操作者(子串匹配)、操作类型、实体类型、时间范围过滤,按时间倒序分页浏览;点击任意行可查看变更详情(diff 与元数据)。对应 API 是 GET /console/api/audit-logs(仅 admin),见 Console API 文档的「审计日志」一节。读取审计日志本身不会产生审计记录。
每条审计记录的字段:
| 字段 | 说明 |
|---|---|
| actor | 发起主体:控制台用户名;secret_key(密钥 bearer 直调);api_key:<掩码>(某 access key 持有者发起,如 MCP 工具调用、上下文刷新) |
| action | 配置实体为 create / update / delete 等 CRUD 动作;另有 rotate(access key 凭证轮换)/ batch_update / batch_commit / import(SSO 凭据);安全事件为 login.success / login.failure / logout / change_password / admin_change_password / sessions.revoke_all;有主体的 MCP 事件为 tool.call / acl.violation / mcp.context.refreshed |
| entity_type | access_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_config(搜索配置)/ batch;MCP 工具调用与 ACL 违规为 mcp,客户端发起的 MCP 会话刷新为 mcp_context |
| entity_id | 受影响实体标识 |
| diff | 变更差异(update / rotate 操作),超长截断;凭证字段(api_key / api_keys / auth_header)只记录掩码,不落明文 |
| ip_address | 操作者 IP |
| request_id | z-request-id 头(若有) |
| occurred_at | 事件发生时间(UTC) |
审计只记录有发起主体的事件。无主体的系统自驱行为(MCP 服务器启动注册、会话淘汰)不进审计表,走运行日志——审计回答"谁对什么负责",系统自述归运维侧。
写入是「即发即忘」:审计写入失败不影响主操作,仅告警。MCP 工具调用与 ACL 违规也记录到审计日志。审计行在 SQLite 与 PostgreSQL 两种存储模式下都会持久化(STORAGE_MODE 只有这两个合法值,不存在可配置的 memory 模式)。注意这与分布式状态后端(REDIS_URL 是否配置决定的 Redis / 内存后端,管会话、限流、广播)是两个正交维度——审计持久化与否只取决于持久化存储后端,与 Redis 无关。
说明:审计日志定位为运维元数据,不等同完整审计系统。生产级合规审计如需更强保证,建议配合外部日志采集。
IP 封禁
控制台登录防爆破由 IP 封禁自动处理:
- 连续登录失败达
CONSOLE_MAX_FAILURES(默认 20)→ 自动临时封禁该 IPCONSOLE_BAN_DURATION(默认 300 秒)。 - 封禁存于内存(重启丢失)与 Redis(多实例持久)。
没有手动封禁/解封的入口。这是有意的:手动 IP 管理属于 WAF(Web 应用防火墙)的职责,网关不做。如需手动 IP 控制,在网关前部署 WAF 或反代。
限流
三层限流:
| 层级 | 配置 | 默认 |
|---|---|---|
| 每访问密钥 | 密钥或所属组的 rate_limit(rpm / tpm),另有全局默认(/settings/rate-limit) | 未设(不限) |
| 每 IP | IP_RATE_LIMIT_RPM | 禁用 |
| 每上游/每模型 | rpm / max_concurrency / tpm / tps_min_interval_ms / wait_timeout_secs(默认 10s)/ initial_tokens(0–100,默认 100)(控制台数据库侧) | 按需配 |
只读快照:GET /console/api/rate-limit-status 返回各层当前令牌/并发占用。每密钥限流在控制台配置(三层 RPM/TPM——见 ADR-026),每上游/每模型限流也在控制台配置,无独立写 API。
调用方遇限流时会收到 HTTP 429 Too Many Requests。每访问密钥、每上游/每模型限流会在响应里带 Retry-After 响应头(单位秒,表示距下次可用还需等待的时间);每访问密钥还会带 z-rate-limited: access_key:<rpm|tpm>:<scope> 标签头。每 IP 限流返回的 429 不带此头。429 的来源与区分见 错误码。
访问密钥掩码
列表里密钥只显示前后 4 位(如 sk-a***xxxx)。完整值只在「复制」时按需取出(GET /access-keys/{name}/api-key),匿名密钥不支持取完整值。上游的 API key 在控制台永不暴露。
密码策略
- bcrypt 哈希存储。
- 新建/重置/改密均要求 ≥8 字符。
- 禁用控制台用户 → 该用户现有会话立即吊销。
安全响应头
控制台路由统一带:
| 头 | 值 |
|---|---|
X-Content-Type-Options | nosniff |
X-Frame-Options | DENY |
Referrer-Policy | (策略值) |
Content-Security-Policy | (策略值) |
常见问题
Q:在控制台找不到审计日志页? Audit 页在 Settings → Audit,仅 admin 可见。如果你用 monitor 登录,侧边栏不会显示该入口(设计如此,非 bug)。
Q:怎么手动封禁某个恶意 IP? 做不到,网关不提供手动封禁。IP 封禁是自动的(失败次数触发)。手动 IP 控制用 WAF/反代。
Q:登录被自己锁了怎么办? 等封禁超时(默认 300 秒)自动解。或让管理员调整 CONSOLE_MAX_FAILURES/CONSOLE_BAN_DURATION(需重启容器)。
Q:访问密钥列表的掩码能关掉看完整值吗? 不能,掩码是强制的。要取完整值用该行的「复制」按钮(调接口取一次)。
下一步:配置 Header ACL 访问规则 看准入控制;日志与日志体存储 看请求日志;访问密钥与密钥组字段 看密钥管理;环境变量配置参考 看全部环境变量。
