meta-reviewing-infra-reviewing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Infrastructure Code Review Patterns

基础设施代码审查模式

Quick Guide: When a diff touches operational code, grep it for secrets first - hardcoded credentials are always blocking. Verify third-party actions are pinned to SHAs and base images to digests or versions, containers run as non-root, workflow permissions are least-privilege, and secrets never pass through build args, logs, or artifacts. Judge deployment ceremony against what the diff actually deploys.

<critical_requirements>
快速指南: 当差异内容涉及运维代码时,首先搜索是否存在密钥——硬编码凭据属于必须阻断的问题。验证第三方操作是否固定到SHA值,基础镜像是否固定到摘要或版本,容器是否以非root用户运行,工作流权限是否遵循最小权限原则,且密钥绝不会通过构建参数、日志或工件传递。根据差异实际部署的内容来判断部署流程的严谨程度。

<critical_requirements>

CRITICAL: Before Reviewing Infrastructure Code

关键要求:审查基础设施代码前需确认

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type
, named constants)
(You MUST verify no secrets are hardcoded - scan the diff for tokens, API keys, passwords, and connection strings)
(You MUST verify third-party CI actions are pinned to full SHA hashes, not mutable tags like
@v4
or
@main
)
(You MUST verify secrets never pass through build args, echo/log lines, or uploaded artifacts)
(You MUST verify production Dockerfiles the diff adds or changes set a non-root USER and pin their base image)
(You MUST verify workflow permissions are declared least-privilege, not inherited write-all)
</critical_requirements>

Auto-detection: review workflow, CI PR review, Dockerfile review, pipeline review, deployment config review, GitHub Actions review, IaC review, terraform review
When to use:
  • Reviewing diffs that touch CI/CD workflows (GitHub Actions, GitLab CI)
  • Reviewing Dockerfiles, .dockerignore, or compose files
  • Reviewing deployment configs (Kubernetes, Helm, platform configs)
  • Reviewing IaC (Terraform, Pulumi) or release/build scripts
  • Reviewing package-manager and lockfile changes with supply-chain impact
When NOT to use:
  • When implementing infrastructure (use the relevant infra implementation skill)
  • For application code in the same diff (use the web/api reviewing skills)
  • For incident response or live operations questions
Key patterns covered:
  • Supply-chain pinning: actions, base images, lockfiles
  • Secret exposure across build args, logs, artifacts, and ignore files
  • Dockerfile hygiene: non-root, multi-stage, layer order
  • CI/CD least-privilege permissions and pipeline correctness
  • Deployment safety scoped to what the diff deploys
Detailed Resources:
  • examples/core.md - Good/bad infrastructure patterns to look for during review

<philosophy>
所有代码必须遵循CLAUDE.md中的项目约定(短横线命名、命名导出、导入顺序、
import type
、命名常量)
(必须确认没有硬编码的密钥——扫描差异内容,检查是否存在令牌、API密钥、密码和连接字符串)
(必须确认第三方CI操作固定到完整的SHA哈希值,而非
@v4
@main
这类可变标签)
(必须确认密钥绝不会通过构建参数、echo/日志行或上传的工件传递)
(必须确认差异中新增或修改的生产环境Dockerfile设置了非root USER,且固定了基础镜像)
(必须确认工作流权限声明为最小权限,而非继承全写入权限)
</critical_requirements>

自动检测场景: 工作流审查、CI PR审查、Dockerfile审查、流水线审查、部署配置审查、GitHub Actions审查、IaC审查、Terraform审查
适用场景:
  • 审查涉及CI/CD工作流(GitHub Actions、GitLab CI)的差异内容
  • 审查Dockerfile、.dockerignore或compose文件
  • 审查部署配置(Kubernetes、Helm、平台配置)
  • 审查IaC(Terraform、Pulumi)或发布/构建脚本
  • 审查对供应链有影响的包管理器和锁文件变更
不适用场景:
  • 实现基础设施时(使用相关的基础设施实现技能)
  • 同一差异中的应用代码(使用Web/API审查技能)
  • 事件响应或实时运维问题
涵盖的核心模式:
  • 供应链固定:操作、基础镜像、锁文件
  • 密钥泄露:涉及构建参数、日志、工件和忽略文件的场景
  • Dockerfile规范:非root用户、多阶段构建、分层顺序
  • CI/CD最小权限配置和流水线正确性
  • 与差异部署内容匹配的部署安全性
详细资源:
  • examples/core.md - 审查过程中需要关注的基础设施模式示例(正确/错误做法)

<philosophy>

Philosophy

理念

Operational code fails in production only. No unit test catches an unpinned action's supply-chain compromise or a leaked deploy key; the review is frequently the only gate this code passes through. Security findings here are cheap to fix pre-merge and brutally expensive after.
When reviewing infrastructure code:
  • Scan for secrets before reading for style - the highest-severity class takes seconds to check
  • Treat every third-party reference (action, image, module) as an attack surface: is it pinned to something immutable?
  • Cross-reference the diff's blast radius: a new env var must exist everywhere the app runs; a renamed job must update everything that
    needs
    it
  • Ask what happens when this pipeline runs on a fork PR, on a re-run, and on two branches at once
When NOT to flag:
  • Don't demand k8s-grade ceremony (probes, resource limits, rollback strategy) for a docs site or an internal workflow that deploys nothing
  • Don't demand multi-stage builds for a CI-only image where size is irrelevant
  • Don't flag missing caching in a job that runs in seconds
  • Don't require a vault migration in a diff that just consumes an existing secret the established way
Core principles:
  • Secrets and supply chain are non-negotiable: always blocking, in any diff, at any scale
  • Pin everything external: mutable references delegate your security to strangers
  • Least privilege by default: a workflow gets the permissions it needs, not the ones it inherits
  • Ceremony proportional to blast radius: production deployment paths earn strictness; a lint workflow does not
</philosophy>
<patterns>
运维代码只会在生产环境中失效。 单元测试无法检测到未固定的操作所导致的供应链漏洞,或泄露的部署密钥;审查通常是这类代码通过的唯一关卡。在此处发现的安全问题在合并前修复成本很低,而在合并后修复则代价极高。
审查基础设施代码时:
  • 在检查风格之前先扫描密钥——最高严重性的问题只需几秒钟就能确认
  • 将每个第三方引用(操作、镜像、模块)视为攻击面:是否固定到不可变的对象?
  • 交叉参考差异的影响范围:新增的环境变量必须在应用运行的所有环境中存在;重命名的任务必须更新所有依赖它的内容
  • 思考当该流水线在分支PR、重新运行以及两个分支同时运行时会发生什么
无需标记的场景:
  • 无需为文档站点或不部署任何内容的内部工作流要求K8s级别的流程(探针、资源限制、回滚策略)
  • 无需为仅用于CI的镜像要求多阶段构建(镜像大小无关紧要)
  • 无需标记运行仅需几秒的任务中缺失缓存的问题
  • 无需要求在仅以既定方式使用现有密钥的差异中进行密钥库迁移
核心原则:
  • 密钥和供应链问题不可协商:任何差异、任何规模下都必须阻断
  • 固定所有外部引用:可变引用会将你的安全控制权交给他人
  • 默认最小权限:工作流仅获取所需权限,而非继承的所有权限
  • 流程严谨程度与影响范围匹配:生产部署路径需要严格规范;代码检查工作流则无需
</philosophy>
<patterns>

Core Patterns

核心模式

Pattern 1: Supply-Chain Pinning

模式1:供应链固定

Every external reference resolves to something immutable.
markdown
undefined
每个外部引用都解析为不可变的对象。
markdown
undefined

Pinning Review

固定性审查

For EACH external reference the diff adds or changes:
  • Third-party GitHub Actions pinned to a full commit SHA (comment may carry the version)
  • First-party actions (actions/*) at minimum major-version pinned
  • Base images pinned to a digest or a specific version tag - never
    latest
  • Dependency installs in CI use the lockfile (
    npm ci
    ,
    bun install --frozen-lockfile
    ), and the lockfile is committed
  • Terraform/Pulumi providers and modules carry version constraints

```yaml
对于差异中新增或修改的每个外部引用:
  • 第三方GitHub Actions固定到完整的提交SHA(注释可附带版本信息)
  • 第一方操作(actions/*)至少固定到主版本
  • 基础镜像固定到摘要或特定版本标签——绝不能是
    latest
  • CI中的依赖安装使用锁文件(
    npm ci
    bun install --frozen-lockfile
    ),且锁文件已提交
  • Terraform/Pulumi提供者和模块带有版本约束

```yaml

Must Fix: mutable tag - the action's owner (or their attacker) can rewrite v4 tomorrow

必须修复:可变标签——操作的所有者(或攻击者)可随时重写v4版本

  • uses: some-org/deploy-action@v4
  • uses: some-org/deploy-action@v4

Good: immutable SHA, human-readable version alongside

正确做法:不可变SHA,同时附带人类可读的版本

  • uses: some-org/deploy-action@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v4.1.2

**Why this matters:** A mutable tag is remote code execution deferred: whoever controls that ref controls your CI, with your secrets in scope. Tag-rewriting attacks on popular actions are documented, recurring events.

---
  • uses: some-org/deploy-action@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v4.1.2

**重要性:** 可变标签相当于延迟执行的远程代码执行:控制该引用的人可以控制你的CI,且拥有密钥权限。针对热门操作的标签重写攻击已有记录,且时有发生。

---

Pattern 2: Secret Exposure

模式2:密钥泄露

Secrets reach the process that needs them and nothing else.
markdown
undefined
密钥仅到达需要它的流程,不会泄露到其他地方。
markdown
undefined

Secret Review

密钥审查

  • No literal tokens, keys, passwords, or connection strings anywhere in the diff
  • Secrets arrive via the platform's secret store (secrets context, env from vault) - not committed files
  • No secret passes through a Docker build arg (build args persist in image history)
  • No echo/printf/debug line prints a secret; secret-bearing env is not dumped wholesale (
    env | sort
    )
  • Uploaded artifacts and caches cannot contain secret-bearing files (.env, credentials)
  • .gitignore / .dockerignore cover .env files and credential paths the diff introduces

```dockerfile
  • 差异中任何位置都不存在字面量令牌、密钥、密码或连接字符串
  • 密钥通过平台的密钥存储(secrets上下文、来自密钥库的环境变量)传递——而非提交的文件
  • 密钥不会通过Docker构建参数传递(构建参数会保留在镜像历史中)
  • 没有echo/printf/调试行打印密钥;不会批量输出包含密钥的环境变量(如
    env | sort
  • 上传的工件和缓存不能包含带有密钥的文件(.env、凭据)
  • .gitignore / .dockerignore覆盖差异引入的.env文件和凭据路径

```dockerfile

Must Fix: the token is baked into image history - docker history shows it

必须修复:令牌会嵌入到镜像历史中——docker history可查看

ARG NPM_TOKEN RUN echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc && npm ci
ARG NPM_TOKEN RUN echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc && npm ci

Good: secret mount exists only for the one RUN

正确做法:密钥仅在单个RUN步骤中挂载

RUN --mount=type=secret,id=npm_token
NPM_TOKEN=$(cat /run/secrets/npm_token) npm ci

**Why this matters:** A leaked secret is a full compromise of whatever it guards, and build-arg/log leaks are invisible until someone pulls the image or reads the log archive.

---
RUN --mount=type=secret,id=npm_token
NPM_TOKEN=$(cat /run/secrets/npm_token) npm ci

**重要性:** 泄露的密钥会导致其保护的资源完全被攻陷,而构建参数/日志泄露在有人拉取镜像或读取日志存档前是不可见的。

---

Pattern 3: Dockerfile Hygiene

模式3:Dockerfile规范

The image is minimal, cache-friendly, and unprivileged.
markdown
undefined
镜像保持最小化、缓存友好且非特权。
markdown
undefined

Dockerfile Review

Dockerfile审查

When the diff adds or changes a Dockerfile:
  • Production stage sets a non-root USER
  • Multi-stage build separates build tooling from the runtime image (when the image ships to production)
  • Dependency manifests are COPYed and installed BEFORE the source copy (layer caching)
  • .dockerignore exists and excludes node_modules, .git, .env
  • Base image is minimal for the job (slim/alpine/distroless where compatible)

```dockerfile
当差异新增或修改Dockerfile时:
  • 生产阶段设置非root USER
  • 多阶段构建将构建工具与运行时镜像分离(当镜像部署到生产环境时)
  • 先复制依赖清单再安装,之后再复制源代码(分层缓存)
  • .dockerignore已存在,并排除node_modules、.git、.env
  • 基础镜像针对任务保持最小化(兼容时使用slim/alpine/distroless)

```dockerfile

Should Fix: source copy first - every code change busts the dependency cache

建议修复:先复制源代码——每次代码变更都会破坏依赖缓存

COPY . . RUN npm ci && npm run build
COPY . . RUN npm ci && npm run build

Good: manifest layer caches until dependencies actually change

正确做法:清单层会缓存直到依赖实际变更

COPY package.json package-lock.json ./ RUN npm ci COPY . . RUN npm run build

**Why this matters:** Root containers turn any app compromise into a container-escape attempt; bad layer order turns every commit into a full rebuild, which teams then "fix" by caching less safely.

---
COPY package.json package-lock.json ./ RUN npm ci COPY . . RUN npm run build

**重要性:** root容器会将任何应用漏洞转化为容器逃逸尝试;不合理的分层顺序会导致每次提交都需要完全重建,团队随后会通过不安全的缓存方式来“解决”这个问题。

---

Pattern 4: CI/CD Permissions and Pipeline Correctness

模式4:CI/CD权限与流水线正确性

The workflow can do its job and nothing more, and its jobs compose correctly.
markdown
undefined
工作流仅能完成所需任务,且任务组合正确。
markdown
undefined

Workflow Review

工作流审查

  • permissions:
    is declared at workflow or job level - read-all default, write scopes named individually
  • pull_request_target
    (if present) does not check out and execute PR head code with secrets in scope
  • Job
    needs:
    ordering matches real dependencies - deploy waits for test
  • Concurrency groups guard deploy jobs against overlapping runs
  • Cache keys include the lockfile hash - not a static string that never invalidates
  • When the diff renames jobs/outputs, everything that references them is updated in the same diff

```yaml
  • 在工作流或任务级别声明
    permissions:
    ——默认只读,写入权限需单独指定
  • pull_request_target
    (如果存在)不会在拥有密钥权限的情况下检出并执行PR头部代码
  • 任务
    needs:
    顺序与实际依赖匹配——部署需等待测试完成
  • 并发组防止部署任务重叠运行
  • 缓存密钥包含锁文件哈希——而非永不失效的静态字符串
  • 当差异重命名任务/输出时,所有引用它们的内容都在同一差异中更新

```yaml

Must Fix: inherited write-all - a compromised step can push code and rewrite releases

必须修复:继承全写入权限——被攻陷的步骤可推送代码并重写发布内容

on: pull_request
on: pull_request

Good: the job names exactly what it may touch

正确做法:任务明确声明可访问的资源

permissions: contents: read pull-requests: write

**Why this matters:** Default token permissions turn "a test step got compromised" into "the repository got compromised". `pull_request_target` with a head checkout is the classic secrets-exfiltration footgun.

---
permissions: contents: read pull-requests: write

**重要性:** 默认令牌权限会将“测试步骤被攻陷”转化为“仓库被攻陷”。`pull_request_target`结合头部检出是典型的密钥泄露陷阱。

---

Pattern 5: Deployment Safety - Scoped to the Diff

模式5:部署安全性——与差异范围匹配

When the diff touches how production runs, verify it can fail safely.
markdown
undefined
当差异涉及生产环境运行方式时,需验证其可安全失败。
markdown
undefined

Deployment Review (when the diff touches deployment config)

部署审查(当差异涉及部署配置时)

  • Health/readiness checks exist for services behind a load balancer or orchestrator
  • Resource limits accompany new containers on shared clusters
  • The app handles SIGTERM (finish in-flight work, then exit) when the platform does rolling restarts
  • New env vars/secrets the diff introduces exist in EVERY environment the app deploys to
  • IaC state changes (backend, locking) are deliberate;
    terraform plan
    output accompanies risky changes

**Why this matters:** A missing readiness check means the balancer routes traffic to a booting container; a missing env var in one environment is the deploy that fails only in production, at deploy time.

</patterns>

---

<decision_framework>
  • 负载均衡器或编排器后的服务存在健康/就绪检查
  • 共享集群上的新容器附带资源限制
  • 平台执行滚动重启时,应用可处理SIGTERM(完成正在进行的工作后退出)
  • 差异引入的新环境变量/密钥在应用部署的所有环境中都存在
  • IaC状态变更(后端、锁定)是有意为之;风险变更需附带
    terraform plan
    输出

**重要性:** 缺失就绪检查意味着负载均衡器会将流量路由到正在启动的容器;某个环境中缺失环境变量会导致仅在生产部署时失败。

</patterns>

---

<decision_framework>

Decision Framework

决策框架

Severity Classification for Infra Issues

基础设施问题的严重性分类

Is this a security defect the diff introduces?
├─ Hardcoded secret, or secret through build arg/log/artifact → MUST FIX
├─ Third-party action on a mutable tag → MUST FIX
├─ pull_request_target executing PR head code with secrets → MUST FIX
├─ Write-all permissions on a workflow that needs read → MUST FIX
├─ Production container running as root → MUST FIX
└─ NO → Is it an operational-correctness gap?
    ├─ Base image on `latest` / installs ignoring the lockfile → SHOULD FIX
    ├─ Deploy job without concurrency guard → SHOULD FIX
    ├─ New env var missing from one environment → SHOULD FIX
    ├─ Cache-hostile Dockerfile layer order → SHOULD FIX
    ├─ New production service without health checks or limits → SHOULD FIX
    └─ NO → Is it a genuine enhancement?
        ├─ Slimmer base image where size demonstrably matters → NICE TO HAVE
        ├─ Faster caching for an already-fast job → DON'T MENTION
        ├─ K8s-grade ceremony for a workflow that deploys nothing → DON'T MENTION
        └─ Tool preferences (compose vs k8s, npm vs bun) → DON'T MENTION
</decision_framework>

<red_flags>
该差异是否引入安全缺陷?
├─ 硬编码密钥,或通过构建参数/日志/工件泄露密钥 → 必须修复
├─ 第三方操作使用可变标签 → 必须修复
├─ pull_request_target在拥有密钥权限的情况下执行PR头部代码 → 必须修复
├─ 仅需只读权限的工作流使用全写入权限 → 必须修复
├─ 生产容器以root用户运行 → 必须修复
└─ 否 → 是否存在运维正确性缺口?
    ├─ 基础镜像使用`latest` / 安装时忽略锁文件 → 建议修复
    ├─ 部署任务无并发组防护 → 建议修复
    ├─ 新环境变量在某个环境中缺失 → 建议修复
    ├─ Dockerfile分层顺序不利于缓存 → 建议修复
    ├─ 新生产服务无健康检查或资源限制 → 建议修复
    └─ 否 → 是否为真正的增强功能?
        ├─ 在大小确实重要的场景下使用更精简的基础镜像 → 锦上添花
        ├─ 为已快速运行的任务优化缓存 → 无需提及
        ├─ 为不部署任何内容的工作流要求K8s级流程 → 无需提及
        └─ 工具偏好(compose vs k8s, npm vs bun) → 无需提及
</decision_framework>

<red_flags>

RED FLAGS

红色预警

High Priority Issues (Must Fix):
  • Any credential literal in the diff (grep for
    token
    ,
    key
    ,
    password
    ,
    secret
    , connection-string shapes)
  • uses: third-party/action@v3
    /
    @main
    /
    @master
  • ARG
    /
    ENV
    carrying secrets in a Dockerfile
  • Missing
    permissions:
    on workflows that handle untrusted input
  • pull_request_target
    +
    actions/checkout
    of the PR head
  • Production Dockerfile with no
    USER
    directive
Medium Priority Issues (Should Fix):
  • FROM node:latest
    or digest-less base images on deploy paths
  • npm install
    in CI where
    npm ci
    belongs
  • Static cache keys that never invalidate
  • Deploy steps with no concurrency group
  • Missing .dockerignore alongside a new Dockerfile
  • Debug steps that
    env
    -dump or
    set -x
    around secret use
Common Mistakes:
  • Pinning first-party actions to SHA while leaving the third-party one on a tag (backwards priority)
  • Adding a secret to one environment and assuming the others inherit it
  • Copying source before manifests and "fixing" slow builds by skipping the lockfile
  • needs:
    chains that let deploy start when only lint passed
  • Treating
    terraform apply
    in CI as safe because plan passed locally against different state
Gotchas & Edge Cases:
  • Docker build args persist in
    docker history
    even when unset afterwards
  • Rewritten tags pass
    uses:
    resolution - only SHAs are immutable
  • Composite actions inherit and can leak the caller's env
  • GITHUB_TOKEN default permissions differ per org setting - declaring them is the only portable truth
  • Alpine images lack glibc; native modules that built fine on debian-slim fail there at runtime
  • SIGKILL follows SIGTERM after the grace period - cleanup that takes longer than the grace period never finishes
</red_flags>

<critical_reminders>
高优先级问题(必须修复):
  • 差异中存在任何凭据字面量(搜索
    token
    key
    password
    secret
    、连接字符串格式)
  • uses: third-party/action@v3
    /
    @main
    /
    @master
  • Dockerfile中使用
    ARG
    /
    ENV
    传递密钥
  • 处理不受信任输入的工作流缺失
    permissions:
    声明
  • pull_request_target
    +
    actions/checkout
    检出PR头部代码
  • 生产Dockerfile无
    USER
    指令
中优先级问题(建议修复):
  • 部署路径中使用
    FROM node:latest
    或无摘要的基础镜像
  • CI中使用
    npm install
    而非
    npm ci
  • 永不失效的静态缓存密钥
  • 部署步骤无并发组
  • 新增Dockerfile时缺失.dockerignore
  • 在密钥使用前后执行
    env
    输出或
    set -x
    的调试步骤
常见错误:
  • 将第一方操作固定到SHA,却让第三方操作使用标签(优先级颠倒)
  • 在一个环境中添加密钥,假设其他环境会继承
  • 先复制源代码再复制清单,通过跳过锁文件来“修复”缓慢的构建
  • needs:
    链允许部署在仅通过代码检查时就开始
  • 认为CI中的
    terraform apply
    是安全的,因为本地针对不同状态执行了plan
陷阱与边缘情况:
  • Docker构建参数即使后续取消设置,仍会保留在
    docker history
  • 重写的标签可通过
    uses:
    解析——只有SHA是不可变的
  • 复合操作会继承并可能泄露调用者的环境变量
  • GITHUB_TOKEN默认权限因组织设置而异——明确声明是唯一可移植的方式
  • Alpine镜像缺少glibc;在debian-slim上构建正常的原生模块在Alpine中运行时会失败
  • SIGKILL会在宽限期后跟随SIGTERM——耗时超过宽限期的清理操作永远无法完成
</red_flags>

<critical_reminders>

CRITICAL REMINDERS

关键提醒

All code must follow project conventions in CLAUDE.md
(You MUST verify no secrets are hardcoded - scan the diff for tokens, API keys, passwords, and connection strings)
(You MUST verify third-party CI actions are pinned to full SHA hashes, not mutable tags like
@v4
or
@main
)
(You MUST verify secrets never pass through build args, echo/log lines, or uploaded artifacts)
(You MUST verify production Dockerfiles the diff adds or changes set a non-root USER and pin their base image)
(You MUST verify workflow permissions are declared least-privilege, not inherited write-all)
Failure to catch these issues will result in leaked credentials, supply-chain compromise executing in CI with secrets in scope, and deploys that fail only in production.
</critical_reminders>
所有代码必须遵循CLAUDE.md中的项目约定
(必须确认没有硬编码的密钥——扫描差异内容,检查是否存在令牌、API密钥、密码和连接字符串)
(必须确认第三方CI操作固定到完整的SHA哈希值,而非
@v4
@main
这类可变标签)
(必须确认密钥绝不会通过构建参数、echo/日志行或上传的工件传递)
(必须确认差异中新增或修改的生产环境Dockerfile设置了非root USER,且固定了基础镜像)
(必须确认工作流权限声明为最小权限,而非继承全写入权限)
未能发现这些问题将导致凭据泄露、供应链漏洞在拥有密钥权限的CI中执行,以及仅在生产环境中失败的部署。
</critical_reminders>