把签名凭据卫生收进 check:production-ops 门禁
Project CI / AI game creator shell Rust crates (push) Successful in 1m31s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m58s
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / Backend tests (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled

- 两个 AGC 打包管线必须用 withCredentials 把 AgcUpdaterSigningKey / ...Password 绑到 TAURI_SIGNING_PRIVATE_KEY / ..._PASSWORD
- 禁止 echo $TAURI_SIGNING_PRIVATE_KEY、Write-Host $env:...、%VAR%、set -x 之类会把绑定凭据打进日志的写法;归档 glob 不得出现 *.pem|*.key|*.pfx|*.p12
- 变异验证:往 mac 管线插一行 echo $TAURI_SIGNING_PRIVATE_KEY 后门禁立刻以「不得把签名凭据打印到构建日志」失败退出;还原后 check:production-ops OK
- 渠道化里程碑第 5 条补记该静态门禁与剩余边界(真实 Jenkins 运行日志仍需 CI 取证)
This commit is contained in:
kdletters
2026-09-29 00:05:54 +08:00
parent f6ccabf425
commit d39931a01a
2 changed files with 51 additions and 1 deletions
@@ -7794,6 +7794,56 @@ for (const [file, content] of [
}
}
}
// 更新签名私钥只允许经 Jenkins 凭据绑定注入构建进程:既不得把凭据本身写进 Jenkinsfile,
// 也不得回显到日志或进归档(对应「AGC 更新发布管线渠道化」第 5 条的可静态复核部分)。
for (const [file, content] of [
['jenkins/Jenkinsfile.ai-game-creator-shell-build', agcPipelineContent],
[
'jenkins/Jenkinsfile.ai-game-creator-shell-macos-build',
agcMacosPipelineContent,
],
]) {
for (const [snippet, reason] of [
[
"string(credentialsId: 'AgcUpdaterSigningKey', variable: 'TAURI_SIGNING_PRIVATE_KEY')",
'签名私钥必须经 `AgcUpdaterSigningKey` 凭据绑定注入 `TAURI_SIGNING_PRIVATE_KEY`。',
],
[
"string(credentialsId: 'AgcUpdaterSigningKeyPassword', variable: 'TAURI_SIGNING_PRIVATE_KEY_PASSWORD')",
'私钥口令必须经 `AgcUpdaterSigningKeyPassword` 凭据绑定注入。',
],
]) {
if (!content.includes(snippet)) {
failed = true;
console.error(`[check:production-ops] ${file} ${reason}`);
}
}
for (const leak of [
'echo $TAURI_SIGNING_PRIVATE_KEY',
'echo "$TAURI_SIGNING_PRIVATE_KEY"',
'echo ${TAURI_SIGNING_PRIVATE_KEY}',
'echo "$env:TAURI_SIGNING_PRIVATE_KEY"',
'Write-Host $env:TAURI_SIGNING_PRIVATE_KEY',
'Write-Output $env:TAURI_SIGNING_PRIVATE_KEY',
'%TAURI_SIGNING_PRIVATE_KEY%',
'set -x',
]) {
if (content.includes(leak)) {
failed = true;
console.error(
`[check:production-ops] ${file} 不得把签名凭据打印到构建日志(命中 \`${leak}\`,xtrace 会把绑定的凭据一起打出来)。`,
);
}
}
const archiveBlock = content.split('archiveArtifacts')[1] ?? '';
if (/(\.pem|\.key|\.pfx|\.p12)\b/u.test(archiveBlock.slice(0, 600))) {
failed = true;
console.error(
`[check:production-ops] ${file} 归档 glob 不得包含签名私钥类文件(*.pem / *.key / *.pfx / *.p12)。`,
);
}
}
for (const [snippet, reason] of [
[
"string(name: 'OSS_DOWNLOAD_URL'",