资讯动态

security-audit-skill:基于CLI+JSON的可编程安全审计实战体系

发布时间:2026/10/18 21:44:17 来源:尧图企业网站定制
1. 这不是“安全审计”培训课而是一套能立刻上手的实战技能体系你打开终端输入一条命令37秒后屏幕上滚动出214行结构化数据——不是杂乱日志而是带 severity 标签、file:line 定位、rule_id 关联、remediation 建议的 JSON 数组你拖拽一个配置文件进 Web UI系统自动比对 CIS Benchmark v2.0.0 的 89 项检查项实时生成 coverage-ledger.json精确到每个 control 的执行状态、跳过原因、证据路径你把 findings.json 丢进团队协作平台开发同事点击某条 high 级别漏洞直接跳转到 Git 提交 diff 页面看到那行被误删的 input validation 逻辑……这不是未来场景这是今天一个熟练掌握 security-audit-skill 的工程师日常工作的最小闭环。security-audit-skill 不是抽象概念它是一组可拆解、可测量、可嵌入工作流的硬技能组合命令行驱动能力、策略即代码Policy-as-Code理解力、审计结果结构化表达力、跨角色协同翻译力。它不依赖特定商业产品不绑定某家云厂商核心载体就是 CLI 工具链 JSON Schema 开源规则集。热搜词里的 security-audit-skill 指向的正是这种“去中心化、可验证、可复现”的审计能力范式——它让安全不再只是安全部门的季度报告而是每个开发者提交 PR 时自动触发的 gate是运维部署前必过的 checklist是 SRE 团队追踪 MTTR 的原始数据源。如果你正在写 CI/CD Pipeline、维护 Kubernetes 集群、或负责开源项目合规交付这套技能不是加分项而是你技术栈里缺失的关键拼图。它解决的不是“要不要做安全审计”而是“如何让每一次审计都产生可追溯、可联动、可沉淀的实际价值”。2. 技能体系设计逻辑从“人工翻文档”到“机器可读流水线”2.1 为什么放弃传统审计工具链三个现实痛点倒逼重构我最早接触安全审计是在一家金融级 SaaS 公司做基础设施加固当时用的是某商业平台UI 美观报告 PDF 做得像咨询公司出品但每次审计要提前两周预约扫描窗口结果出来后还得手动导出 Excel再逐条匹配 Jira issue最后发现 63% 的 high 级别问题其实在半年前的另一份报告里就存在——只是没人建立关联。后来我们试过开源工具比如 Lynis它输出的文本报告很详细但想把“SSH PermitRootLogin 设置为 no”这条发现自动同步到 Ansible playbook 的变量文件里得写正则解析还要处理不同 Linux 发行版的路径差异。更麻烦的是当 DevOps 同事想基于审计结果做自动化修复时他们面对的是一堆 human-readable 的字符串而不是 machine-readable 的结构化数据。这直接催生了 security-audit-skill 的底层设计哲学审计过程必须可编程审计结果必须可消费。具体拆解为三个刚性约束输入可版本化所有审计目标配置文件、代码片段、容器镜像、K8s manifest必须能纳入 Git 仓库审计命令应支持 --config-dir ./infra/terraform/ 这类参数而非依赖 GUI 导入。过程可复现同一份 input在不同时间、不同机器上运行只要工具版本一致输出的 findings.json 的 SHA256 必须完全相同。这意味着不能依赖本地环境变量、临时文件或随机种子。输出可下游集成findings.json 不是终点而是起点。它必须严格遵循预定义的 JSON Schema如 OpenSSF Scorecard 的 schema字段名统一如 severity 必须是 critical/high/medium/low/info位置信息必须包含 file、line、column 三级定位 remediation 字段必须提供可执行的 CLI 命令或代码片段。提示很多团队卡在第三点。他们用工具生成了 JSON但字段命名五花八门——有的叫 risk_level有的叫 severity_score有的甚至用数字 1-5 表示严重等级。这导致后续写脚本聚合数据时光是字段映射就要花两天。security-audit-skill 的第一条铁律就是先定 Schema再选工具。我们团队内部强制使用 https://github.com/ossf/scorecard/blob/main/checks/checks.go 中定义的 CheckResult 结构体作为事实标准所有自研工具输出都必须兼容。2.2 技能树的三层架构CLI 是入口JSON 是血液Coverage Ledger 是大脑security-audit-skill 不是单点技能而是一个立体能力模型分三层递进第一层CLI 驱动层Skills-CLI这是技能的物理入口。不是指会敲ls或grep而是掌握一套“审计专用 CLI 范式”--format json是默认输出格式--output findings.json是标准写法--policy参数指向策略文件如 Rego 规则、YAML 检查清单而非内置硬编码逻辑--baseline支持加载历史 findings.json 作为基线只输出新增问题diff 模式--scope可精确限定审计范围如--scope k8s:deployment,service或--scope terraform:aws_s3_bucket。我们实测过一个熟练者能在 3 分钟内用tfsec --format json --output tf-findings.json --policy ./policies/cis-aws.tfplan完成 Terraform 代码审计并把结果喂给下一个环节。第二层JSON 结构化层Findings.json这是技能的价值载体。一份合格的 findings.json 必须包含四个核心对象{ metadata: { tool: tfsec, version: 1.28.0, timestamp: 2024-06-15T08:22:11Z }, results: [ { rule_id: AWS001, title: S3 bucket should not have public read access, severity: high, file: main.tf, line: 42, column: 5, remediation: Add acl \private\ to the aws_s3_bucket resource block } ], summary: { total: 1, critical: 0, high: 1, medium: 0, low: 0 }, coverage: { files_scanned: 3, lines_analyzed: 1247, rules_applied: 47 } }关键在于remediation字段——它必须是可执行的。我们拒绝任何“建议联系管理员”这类模糊描述。实操中我们要求所有自研规则的 remediation 字段都通过eval $(cat remediation.sh)测试确保粘贴到终端就能跑通。第三层Coverage Ledger 层Coverage-ledger.json这是技能的决策中枢。它不记录问题而是记录“我们承诺审计什么以及实际审计了什么”。一个典型的 coverage-ledger.json 长这样{ audit_scope: kubernetes-cluster-v1.25, controls: [ { id: CIS-1.2.1, name: Ensure that the API server pod specification file permissions are set to 644 or more restrictive, status: passed, evidence: /etc/kubernetes/manifests/kube-apiserver.yaml: permissions644, last_checked: 2024-06-15T08:20:00Z }, { id: CIS-1.2.2, name: Ensure that the API server pod specification file ownership is set to root:root, status: skipped, reason: Host OS is CoreOS, file owned by core:core per distro spec, last_checked: 2024-06-15T08:20:00Z } ] }它的价值在于当审计报告显示“0 critical issues”你可以立刻打开 coverage-ledger.json确认是否真的覆盖了所有关键 control还是因为某些项被跳过导致“假阴性”。我们团队每月用这个文件生成《审计覆盖度报告》直接发给 CTO里面明确列出“CIS-4.2.3etcd encryption未覆盖因当前 etcd 版本 3.5.0需升级后重审”。2.3 为什么选择 JSON 而非 XML/YAML/数据库一次生产事故教会我们的事去年我们曾尝试用 PostgreSQL 存储审计结果理由很充分支持复杂查询、有事务保证、能建索引。上线两周后一个深夜告警CI Pipeline 卡在“生成审计报告”步骤耗时从平均 12 秒飙升到 3 分钟。排查发现PostgreSQL 的 INSERT 操作在高并发下锁表而我们的 Pipeline 是并行触发 12 个微服务的审计任务每个任务都试图写入同一张 findings 表。更糟的是当某个服务审计失败时事务回滚导致其他成功结果也被丢弃——我们失去了“部分成功”的能力。这次事故让我们彻底回归 JSON 文件方案原因很朴素原子性保障echo $json findings.json是原子操作不会出现“写一半失败”的中间态无依赖部署CI Runner 不需要预装数据库客户端也不用管理连接池版本友好Git 天然支持 JSON 文件的 diff你能清晰看到两次审计间新增了哪条 high 级别问题工具链解耦前端用 D3.js 渲染可视化后端用 Python Flask 提供 API分析用 jq 命令行过滤它们都只认 JSON不关心存储介质。现在我们所有审计结果都以findings-${SERVICE}-${TIMESTAMP}.json命名存入 S3同时保留最近 30 天的版本。当需要追溯某个问题时直接aws s3 cp s3://audit-bucket/findings-api-gateway-20240610.json .下载用jq .results[] | select(.severityhigh)提取整个过程 5 秒完成。JSON 不是妥协而是经过血泪教训验证的最优解。3. 核心技能实操从零搭建可落地的审计流水线3.1 环境准备与工具链选型为什么只推荐这 4 个 CLI 工具搭建 security-audit-skill 的第一步不是写规则而是选对 CLI 工具。我们团队过去三年测试过 17 款开源审计工具最终只保留以下 4 个它们共同特点是原生支持 JSON 输出、策略可插拔、社区活跃、二进制体积小20MB。工具名适用场景JSON Schema 兼容性实测启动速度冷态关键优势tfsecTerraform 代码审计完全兼容 OSS-F Scorecard Schema0.8s内置 CIS AWS/Azure/GCP 规则支持自定义 Rego 策略trivy容器镜像 代码库漏洞扫描扩展自 SPDX 2.2需适配层1.2s扫描速度最快支持离线模式CVE 数据库更新最及时kube-benchKubernetes CIS 基准审计原生输出 JSON字段名与 coverage-ledger 兼容3.5s唯一能直接生成 coverage-ledger.json 的工具checkov多云 IaCTerraform/CloudFormation/K8s需加--framework cli参数启用 JSON2.1s规则数量最多2000支持 GitHub Actions 原生集成注意不要被“功能多”迷惑。我们曾试用过一款号称支持 12 种语言的代码审计工具但它输出的 JSON 里severity字段是SEV_HIGH而标准是high光是写字段转换脚本就花了半天。选型原则很简单跑--help看到--format json选项再跑--format json --output test.json看输出是否符合你的 Schema两步验证不超 2 分钟。安装方式统一用官方二进制包非 pip/npm避免依赖冲突# tfsec curl -sfL https://raw.githubusercontent.com/aquasecurity/tfsec/main/scripts/install.sh | sh -s -- -b /usr/local/bin # trivy curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin # kube-bench wget https://github.com/aquasecurity/kube-bench/releases/download/v0.6.12/kube-bench_0.6.12_linux_amd64.tar.gz tar zxvf kube-bench_0.6.12_linux_amd64.tar.gz sudo mv kube-bench /usr/local/bin/ # checkov curl -sfL https://raw.githubusercontent.com/bridgecrewio/checkov/main/scripts/install.sh | sh -s -- -b /usr/local/bin3.2 构建第一个可执行的审计命令以 Kubernetes 集群为例假设你刚接手一个运行在 AWS EKS 上的 Kubernetes 集群老板说“下周要过等保三级先做个基线检查。” 别急着打开浏览器搜 CIS 文档按以下三步走第一步获取集群上下文并验证权限# 确保 kubectl config 指向目标集群 kubectl config current-context # 应输出类似 arn:aws:eks:us-west-2:123456789012:cluster/my-prod-cluster # 验证是否有足够权限kube-bench 需要 list nodes/pods kubectl auth can-i list nodes kubectl auth can-i list pods # 如果返回 false联系集群管理员授予 system:node-reader ClusterRoleBinding第二步运行 kube-bench 并生成 coverage-ledger.json# 创建输出目录 mkdir -p audit-results/k8s-cis-20240615 # 执行审计指定 CIS v1.6.0 for Kubernetes 1.25 kube-bench --benchmark cis-1.6 --version 1.25 \ --output-format json \ --output-path audit-results/k8s-cis-20240615/coverage-ledger.json \ --targets master,node # 此命令会生成两个文件 # - coverage-ledger.json包含所有 controls 的 statuspassed/failed/skipped # - findings.json仅包含 failed 和 warn 状态的问题详情第三步解析结果并生成可操作报告# 提取所有 failed controls 的 ID 和描述 jq -r .controls[] | select(.statusfail) | \(.id) \(.description) \ audit-results/k8s-cis-20240615/coverage-ledger.json # 统计各严重等级问题数注意kube-bench 自身不标 severity需映射 jq [.controls[] | select(.statusfail)] | length audit-results/k8s-cis-20240615/coverage-ledger.json # 生成 remediation 命令示例修复 etcd 加密 echo kubectl edit cm -n kube-system cluster-config | tee audit-results/k8s-cis-20240615/remediation.sh这个流程的核心价值在于你得到的不是一份 PDF 报告而是一个可立即执行的 remediation.sh 脚本和一个能被 Git 追踪的 coverage-ledger.json。下次审计时只需对比新旧两个 coverage-ledger.json就能精准定位“哪些 control 从 failed 变成了 passed”。3.3 将 findings.json 深度融入开发工作流PR 门禁实战安全审计最大的价值不是发现问题而是在问题发生前拦截。我们把 findings.json 作为 GitHub PR 的准入条件具体实现如下Step 1编写 CI 脚本.github/workflows/security-audit.ymlname: Security Audit on PR on: pull_request: branches: [main] paths: - **.tf - **.yaml - **.yml jobs: tfsec-audit: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Install tfsec run: curl -sfL https://raw.githubusercontent.com/aquasecurity/tfsec/main/scripts/install.sh | sh -s -- -b /usr/local/bin - name: Run tfsec id: tfsec run: | tfsec --format json --output tf-findings.json . echo findings_count$(jq .summary.total tf-findings.json) $GITHUB_OUTPUT - name: Fail if high/critical issues found if: ${{ fromJSON(steps.tfsec.outputs.findings_count) 0 }} run: | # 提取 high/critical 问题 jq -r .results[] | select(.severityhigh or .severitycritical) | \(.rule_id) \(.title) at \(.file):\(.line) tf-findings.json exit 1 - name: Upload findings.json as artifact uses: actions/upload-artifactv3 with: name: tf-findings path: tf-findings.jsonStep 2定制化问题展示提升开发者体验单纯exit 1会让开发者困惑。我们在脚本末尾加了一段人性化提示# 在 fail 步骤中追加 echo ::error::Security audit failed. Found $(jq .summary.high .summary.critical tf-findings.json) high/critical issues: jq -r .results[] | select(.severityhigh or .severitycritical) | • \(.rule_id): \(.title) (\(.file):\(.line))\n Fix: \(.remediation) tf-findings.json效果是PR 检查失败时GitHub 评论区直接显示• AWS001: S3 bucket should not have public read access (main.tf:42) Fix: Add acl private to the aws_s3_bucket resource block • GCP002: Compute instance should not have default service account with full access (gcp.tf:87) Fix: Set service_account.0.scopes to [https://www.googleapis.com/auth/cloud-platform] instead of [https://www.googleapis.com/auth/cloud-platform]Step 3建立问题闭环机制我们要求每个 PR 必须关联一个 Jira ticketticket 描述里必须包含findings.json的下载链接。SRE 团队每天晨会看jq .results[] | select(.severitycritical)的输出优先处理 critical 问题。三个月下来critical 问题平均修复时间从 7.2 天降到 1.3 天——因为问题在代码提交那一刻就被捕获而不是等到月度渗透测试才发现。3.4 coverage-ledger.json 的进阶用法构建动态合规仪表盘coverage-ledger.json 的真正威力在于它能把“合规”从静态文档变成动态指标。我们用它构建了一个实时仪表盘核心逻辑如下数据采集层每小时 cron job#!/bin/bash # audit-collector.sh for cluster in prod-staging prod-canary; do export KUBECONFIG/etc/kubeconfig/$cluster kube-bench --benchmark cis-1.6 --version 1.25 \ --output-format json \ --output-path /var/audit/$cluster/$(date %Y%m%d_%H%M%S)_coverage-ledger.json \ --targets master,node done数据聚合层Python 脚本import json, glob, os from datetime import datetime def aggregate_coverage(): all_ledgers glob.glob(/var/audit/*/*_coverage-ledger.json) result {timestamp: datetime.now().isoformat(), clusters: {}} for ledger_path in all_ledgers: cluster_name ledger_path.split(/)[3] with open(ledger_path) as f: ledger json.load(f) # 计算通过率 total len(ledger[controls]) passed len([c for c in ledger[controls] if c[status] passed]) result[clusters][cluster_name] { pass_rate: round(passed/total*100, 1), last_audit: ledger[controls][0][last_checked], critical_controls: len([c for c in ledger[controls] if critical in c.get(name, )]) } with open(/var/www/html/coverage.json, w) as f: json.dump(result, f, indent2) aggregate_coverage()前端展示层纯 HTML Chart.js!-- dashboard.html -- div idchart-container canvas idcoverageChart/canvas /div script fetch(/coverage.json) .then(r r.json()) .then(data { const ctx document.getElementById(coverageChart).getContext(2d); new Chart(ctx, { type: bar, data: { labels: Object.keys(data.clusters), datasets: [{ label: Compliance Pass Rate (%), data: Object.values(data.clusters).map(c c.pass_rate), backgroundColor: rgba(54, 162, 235, 0.6) }] } }); }); /script这个仪表盘每天自动刷新CTO 打开链接就能看到prod-staging92.3%prod-canary98.1%。更重要的是当某个集群 pass_rate 下跌超过 5%脚本自动发 Slack 告警“⚠️ prod-staging 合规率下降至 87.2%2 小时前为 92.3%请检查最近部署的 manifests”。coverage-ledger.json 让合规从“事后证明”变成了“事前预警”。4. 常见问题与避坑指南那些没人告诉你的实战细节4.1 “为什么我的 findings.json 里没有 line/column 信息”——文件解析模式的隐性陷阱这是新手最常遇到的问题。你运行trivy fs --format json --output findings.json .打开 JSON 却发现所有file字段都是Dockerfile但line和column字段为空。原因在于trivy 的 filesystem 模式fs只做内容指纹匹配不进行语法解析而 config 模式config才支持行号定位。正确做法是# 错误用 fs 模式扫描配置文件 trivy fs --format json --output findings.json . # 正确用 config 模式明确指定配置类型 trivy config --format json --output findings.json --config-type dockerfile . trivy config --format json --output findings.json --config-type kubernetes .同理tfsec默认扫描.tf文件但如果你的 Terraform 代码分散在多个子模块且主main.tf里用module network引用tfsec默认不会递归进入 module 目录。解决方案是# 添加 --no-module-download 参数并显式指定所有模块路径 tfsec --format json --output tf-findings.json \ --no-module-download \ --module ./modules/network \ --module ./modules/compute \ .实操心得永远先用--dry-run参数测试。比如tfsec --dry-run --no-module-download .会列出它实际扫描的文件路径确认无误后再去掉--dry-run执行真实审计。我们团队规定所有新加入 Pipeline 的审计命令必须先通过--dry-run验证扫描范围否则禁止上线。4.2 “coverage-ledger.json 显示 skipped但我觉得应该检查”——跳过逻辑的透明化管理kube-bench经常报告skipped比如{ id: CIS-1.1.20, name: Ensure that the etcd data directory permissions are set to 700 or more restrictive, status: skipped, reason: etcd data directory not found }表面看是环境问题但深层原因是kube-bench 的 skip 逻辑是硬编码在 Go 代码里的你无法通过配置修改。这导致两个风险一是误判实际该检查却被跳过二是不可审计不知道谁决定跳过。我们的解决方案是用 wrapper script 替代直接调用 kube-bench。创建safe-kube-bench.sh#!/bin/bash # safe-kube-bench.sh set -e # 记录跳过原因到独立文件 SKIP_LOG/tmp/kube-bench-skips-$(date %s).log # 捕获 kube-bench 的 stderr跳过信息在此 kube-bench --benchmark cis-1.6 --version 1.25 $ 2 $SKIP_LOG # 检查跳过日志对关键 control 强制报错 if grep -q CIS-1.1.20 $SKIP_LOG; then echo CRITICAL: CIS-1.1.20 skipped but etcd data dir must be checked 2 echo Please verify etcd data directory exists and is readable 2 exit 1 fi # 正常输出 cat $SKIP_LOG 2 # 仍输出到 stderr保持原有行为然后在 CI 中调用./safe-kube-bench.sh而非kube-bench。这样所有跳过行为都被日志记录关键 control 的跳过会触发构建失败迫使团队主动解决环境问题而不是掩盖风险。4.3 “findings.json 太大jq 解析超时怎么办”——大文件处理的三个技巧当审计大型 Terraform 项目1000 个资源时tfsec生成的 findings.json 可能达 15MBjq .results[]会卡住。我们用以下方法应对技巧一流式解析streaming# 不加载整个 JSON 到内存逐行处理 cat findings.json | jq -c select(.results) | .results[] | while read finding; do severity$(echo $finding | jq -r .severity) if [[ $severity critical ]]; then echo $finding | jq -r .rule_id, .title, .file, .line fi done技巧二预过滤pre-filtering# 先用 awk 提取含 critical 的行再用 jq 解析 awk /severity:critical/ {print; getline; print; getline; print; getline; print} findings.json | \ jq -s reduce .[] as $item ({}; . $item)技巧三分块处理chunking# 将大 JSON 拆分为 100 条/块的小文件 jq -c .results[] findings.json | split -l 100 - findings_chunk_ for chunk in findings_chunk_*; do jq select(.severityhigh) $chunk high-findings.json done注意事项永远不要用cat findings.json | jq .results[0]这种写法——它会把整个文件读入内存。jq的-ccompact参数和流式管道是处理大文件的生命线。我们线上环境强制要求所有审计脚本添加超时保护timeout 30s jq -c .results[] findings.json避免单个命令拖垮整个 Pipeline。4.4 “不同工具输出的 severity 不一致怎么统一”——建立内部 severity 映射表trivy用CRITICAL/HIGH/MEDIUM/LOWtfsec用critical/high/medium/lowcheckov用HIGH/MEDIUM/LOW无 CRITICAL。如果直接聚合jq select(.severitycritical)会漏掉 trivy 的 CRITICAL 问题。我们的解决方案是在 CI Pipeline 的最后一步用 Python 脚本统一映射# normalize-severity.py import sys, json SEVERITY_MAP { CRITICAL: critical, critical: critical, HIGH: high, high: high, MEDIUM: medium, medium: medium, LOW: low, low: low, INFO: info, info: info } with open(sys.argv[1]) as f: data json.load(f) for result in data.get(results, []): if severity in result: result[severity] SEVERITY_MAP.get(result[severity], unknown) with open(sys.argv[1], w) as f: json.dump(data, f, indent2)在 Pipeline 中调用python normalize-severity.py tf-findings.json python normalize-severity.py trivy-findings.json这样所有工具输出的 findings.json 都遵循同一套 severity 命名后续的jq select(.severitycritical)就能跨工具工作。我们把这个脚本放在团队共享的audit-utils仓库里所有新成员入职第一周就要学会用它。5. 技能进阶从执行者到规则制定者的跨越5.1 编写第一条自定义规则以“禁止硬编码 AWS Access Key”为例掌握工具使用只是起点真正的 skill 体现在能根据业务需求定制规则。我们以一个高频风险为例开发者在 Terraform 代码里硬编码access_key AKIA...。tfsec内置规则AWS017只检查aws_access_key资源但实际中密钥常出现在aws_s3_bucket的lifecycle_rule或aws_lambda_function的environment里。编写自定义 Rego 规则policies/no-hardcoded-keys.regopackage tfsec import data.terraform # 匹配所有包含 access_key 或 secret_key 的属性 violation[{msg: msg, resource: resource}] { resource : terraform.resources[_] attr : resource.attributes[_] attr.name access_key | attr.name secret_key attr.value msg : sprintf(Hardcoded %s detected in %s, [attr.name, resource.type]) } # 扩展检查 environment 变量中的密钥 violation[{msg: msg, resource: resource}] { resource : terraform.resources[_] resource.type aws_lambda_function env : resource.attributes[environment] env ! null value : env.value[variables] value ! null key : value[_] re_match(AKIA[0-9A-Z]{16}, key) msg : sprintf(AWS access key found in Lambda environment variables: %s, key) }然后在tfsec中启用tfsec --format json --output findings.json \ --policy ./policies/no-hardcoded-keys.rego \ --policy ./policies/cis-aws.rego \ .实操心得写 Rego 规则时先用terraform show -json查看资源的 JSON 结构再用opa eval --data policies/no-hardcoded-keys.rego --input terraform-json-output.json测试规则逻辑。我们团队有个不成文规定每条自定义规则必须附带一个test.tf示例文件证明它能准确捕获问题且不误报。5.2 构建组织级 coverage-ledger从单集群到多云全景视图当团队管理 12 个 Kubernetes 集群、8 个 Terraform 环境、5 个容器 Registry 时单个 coverage-ledger.json 失去意义。我们构建了组织级org-coverage-ledger.json结构如下{ org_id: acme-corp, timestamp: 2024-06-15T08:20:00Z, environments: [ { name: prod-us-east-1, type: kubernetes, coverage_ledger: s3://audit-bucket/prod-us-east-1/coverage-ledger.json, last_updated: 2024-06-15T08:20:00Z }, { name: staging-eu-west-1, type: terraform, coverage_ledger: s3://audit-bucket/staging-eu-west-1/tf-coverage.json, last_updated: 2024-06-15T08:15:00Z } ], summary: { total_environments: 25, compliant: 22, non_compliant: 3, compliance_rate: 88.0 } }生成脚本build-org-ledger.py会从 S3 列出所有coverage-ledger*.json文件下载每个文件提取controls[].status统计检查文件时效性超过 24 小

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑