Files
qinglong/docs/operations/ql3-local-security-audit.md
T

5.3 KiB
Raw Blame History

ql3-audit 本机安全审计查询与诊断压缩

ql3-audit 是一次命令、一次进程的实例 Owner 运维入口。它提供有界查询和显式的 诊断审计压缩,不启动管理 daemon,不开放网络端口,也不返回 durable audit 中的 authenticationId

前置条件

  • 已完成 Fresh Setup 或采用流程;
  • 当前 credential 属于实例 authority Project 的 active User Owner
  • deployment root 和子目录由当前 UID 所有,目录为 0700、文件为 0600
  • SQLite、credential 和 Owner pepper keyring 已通过 readiness。

执行形式:

ql3-audit run --command-file /srv/qinglong3/commands/audit-list.json

command file 必须是 deployment root 内的规范、非 symlink、当前 UID 0600 文件。

查询第一页

{
  "schemaVersion": 1,
  "operation": "security.audit.list",
  "options": {
    "deploymentRoot": "/srv/qinglong3",
    "databasePath": "/srv/qinglong3/qinglong3.sqlite",
    "profile": "edge",
    "ownerPepperKeyringDirectory": "/srv/qinglong3/owner-keys",
    "credentialFilePath": "/srv/qinglong3/owner-credential.json"
  },
  "request": {
    "authorityProjectId": "default",
    "query": {
      "limit": 32,
      "filter": {
        "projectId": "automation",
        "outcome": "denied"
      }
    },
    "requestId": "audit-denied-automation-page-1",
    "auditEventId": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaa1"
  }
}

limit 必须为 164。filter 只能包含以下可选精确条件:

  • projectId
  • subject,形如 {"type":"user","id":"owner-user"}
  • outcome

空过滤器必须写成 "filter": {}。不支持 offset、模糊查询、任意排序或调用方 SQL。

翻页

若响应的 nextCursor 非 null,下一条 command 使用新的 request/audit ID,并把 cursor 原样放入 query.before

{
  "query": {
    "limit": 32,
    "before": {
      "occurredAtMs": 1785300000000,
      "eventId": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb"
    },
    "filter": {
      "projectId": "automation",
      "outcome": "denied"
    }
  }
}

排序固定为 occurredAtMs DESC,eventId DESC。每页是独立授权和独立 SQLite snapshot; 如果翻页期间有新事件,而你要求严格同一时点清单,应从第一页重新查询。

不要复用上一页的 auditEventId。查询自己的 allowed audit 在读取 snapshot 后才于同一 事务写入,因此当前响应不会包含本次查询事件。

输出与安全边界

成功记录只包含 event/request/operation、nullable Project/subject、outcome、reasons、 nullable fence 和 timestamp。输出中不存在 authenticationId、credential、pepper、 Secret、路径或 command 内容。

只有实例 authority Project 的当前强认证 User Owner 可以使用此入口。secondary Project Owner 即使能管理自己的 RoleBinding,也不能枚举实例审计。不要通过直接 SQL 绕过该边界。

显式压缩过期诊断事件

先保留部署所需的审计期限,再计算一个不晚于“当前受信时间减 retention”的固定 eligibleBeforeMs。例如 Edge 每次最多处理 64 条:

{
  "schemaVersion": 1,
  "operation": "security.audit.compact",
  "options": {
    "deploymentRoot": "/srv/qinglong3",
    "databasePath": "/srv/qinglong3/qinglong3.sqlite",
    "profile": "edge",
    "ownerPepperKeyringDirectory": "/srv/qinglong3/owner-keys",
    "credentialFilePath": "/srv/qinglong3/owner-credential.json"
  },
  "request": {
    "authorityProjectId": "default",
    "retentionMs": 2592000000,
    "eligibleBeforeMs": 1782710400000,
    "limit": 64,
    "mutationId": "cccccccc-cccc-4ccc-8ccc-ccccccccccc1",
    "requestId": "audit-compact-2026-06-batch-1",
    "failureAuditEventId": "cccccccc-cccc-4ccc-8ccc-ccccccccccc2"
  }
}

约束:

  • retention 必须为 30 天至 10 年;
  • eligibleBeforeMs + retentionMs 不得晚于执行时的受信时钟;
  • Edge limit 为 164Standalone 为 1512
  • mutationIdfailureAuditEventId 必须不同;
  • exact replay 必须复用完全相同的 command 语义;
  • 处理下一批时必须生成新的 mutation/request/failure identity。

响应只返回 batch receipt 的低敏投影,包括删除数量、payload bytes、首尾 cursor、 records digest 和创建时间。重复运行新的 batch,直到 deletedCount 为 0。

压缩的安全边界

v1 只删除超过期限、没有已知引用的诊断事件:

  • 所有非 allowed outcome
  • 精确只读 operation identity.inspectcredential.inspectpolicy.project.inspectpolicy.project.listpolicy.role_binding.inspectpolicy.role_binding.listsecurity.audit.list

允许的 mutation、dispatch、execution、package 和 compaction evidence 不会被该命令 删除。不要把它描述为通用 retention、合规销毁或完整日志轮转。

删除、allowed audit 和不可变 compaction receipt 在同一个 BEGIN IMMEDIATE 中提交。 命令不执行 VACUUM;删除页可供 SQLite 后续复用,但数据库文件大小可能不会立即 下降。物理缩容需要独立的离线备份/恢复维护流程。

查询是有界交互能力,压缩是保守的诊断回收能力;二者都不是合规 export。签名导出、 远端归档、完整领域 retention、销毁证明、聚合和告警仍是后续独立能力。