security: add release trust authority bootstrap

This commit is contained in:
2026-09-27 11:10:21 +08:00
parent 440099e069
commit c600023c83
5 changed files with 2597 additions and 1 deletions
@@ -6,7 +6,7 @@
本工具只处理 RC-06 的一个精确发布批次:60 个合同资产、14 个 Prompt 模块和 31 项处置结论。唯一人工审核人为陈钰麒(总经理)。离线根密钥和 apply 服务密钥由系统按用途隔离管理,它们不是人工审核人。
当前没有生成真实审核私钥、正式签名、候选 tag、发布收据或生产授权。内部试点、UAT、生产及公众开放继续 `NO_GO`。一次 RC-06 签名不等于资产已经发布,也不等于授权公众生产切流。
陈钰麒已在受控本机完成审核密钥初始化;该事实只表示审核私钥已加密保存并完成公钥注册准备。RC-06/recovery/apply 技术密钥、源码 pin、正式签名、候选 tag、发布收据和生产授权仍未形成。内部试点、UAT、生产及公众开放继续 `NO_GO`。一次 RC-06 签名不等于资产已经发布,也不等于授权公众生产切流。
## 2. 审核人只需要执行的两个入口
@@ -54,6 +54,30 @@
- 后续通过业务 API 应用 74 项内容,并由服务密钥签署 74 项机器结果和在线 hash;
- 继续验证 1 个起草+8 个审查运行时 Prompt 快照以及 RC-06 UAT。
系统侧使用 `yuqei-infra/scripts/Launch-ReleaseAuthority.ps1` 调用
`rc06-release-trust-bootstrap.py`。该入口与审核人入口分离,默认非交互:
- `initialize` 一次性生成互不相同的 RC-06 approval root、recovery root 和
apply-service 三把 Ed25519 技术密钥;私钥只以 Windows CurrentUser DPAPI
密文保存在源码树外,并继承仅当前账户与 SYSTEM 可访问的 DACL;
- `build-recovery-keyrings` 使用 recovery root 分别签发 first-release 与
rollback 两种 schema/key-id 的 keyring;两者可共享 recovery root,但不能
混用 schema、root key id 或签名 payload;
- `pin-source` 默认只预览,显式 `--apply` 才会以严格匹配和事务回退方式固定
三类公钥 SHA、两个 recovery keyring payload SHA 和精确 epoch;不写入私钥;
- `sign-rc06-keyring` 只在冻结 manifest 形成后签发绑定精确 manifest 原始 SHA
的候选专属 keyring;
- `sign-apply-payloads` 只签署已经包含 74 项在线 hash、且可由正式 RC-06
verifier 完整验证的 canonical apply payload;所有 receipt 先在内存生成并
逐项自验,再作为禁止覆盖的完整 bundle 原子写出,不调用业务 API;
- `provision-apply-private-key` 在安全 secret-store 交付适配器完成前保持
fail-closed,不会导出明文或 DPAPI 私钥。
DPAPI 与 DACL 不能抵御已经控制当前 Windows 账户的进程。正式初始化仍只能在
发布负责人确认的干净受控主机上执行;临时 UAT 主机、源码仓库、聊天、邮件、
共享盘和构建 artifact 均不得成为技术私钥的保存位置。当前新增工具代码本身不
表示真实技术密钥、pin、keyring、apply receipt 或发布授权已经形成。
## 4. 不得执行的操作
- 不得手工编辑 manifest、request、keyring、approval、SHA 或签名 JSON;
@@ -0,0 +1,102 @@
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, Position = 0)]
[ValidateSet(
"runtime-check",
"initialize",
"status",
"build-recovery-keyrings",
"pin-source",
"sign-rc06-keyring",
"sign-apply-payloads",
"provision-apply-private-key"
)]
[string]$Command,
[Parameter(ValueFromRemainingArguments = $true)]
[string[]]$CommandArguments
)
$ErrorActionPreference = "Stop"
$env:PSModulePath = @(
(Join-Path $env:SystemRoot "System32\WindowsPowerShell\v1.0\Modules")
(Join-Path $env:ProgramFiles "WindowsPowerShell\Modules")
) -join ";"
function Get-TrustedPythonCandidates {
$candidatePaths = [System.Collections.Generic.List[string]]::new()
foreach ($pattern in @(
(Join-Path $env:LOCALAPPDATA "Python\pythoncore-*\python.exe")
(Join-Path $env:LOCALAPPDATA "Programs\Python\Python*\python.exe")
(Join-Path $env:ProgramFiles "Python*\python.exe")
)) {
Get-ChildItem -Path $pattern -File -ErrorAction SilentlyContinue |
ForEach-Object { $candidatePaths.Add($_.FullName) }
}
foreach ($registryRoot in @(
"Registry::HKEY_CURRENT_USER\Software\Python\PythonCore"
"Registry::HKEY_LOCAL_MACHINE\Software\Python\PythonCore"
)) {
Get-ChildItem -LiteralPath $registryRoot -ErrorAction SilentlyContinue |
ForEach-Object {
$properties = Get-ItemProperty -LiteralPath (Join-Path $_.PSPath "InstallPath") -ErrorAction SilentlyContinue
if ($properties.ExecutablePath) {
$candidatePaths.Add([string]$properties.ExecutablePath)
} elseif ($properties.'(default)') {
$candidatePaths.Add((Join-Path ([string]$properties.'(default)') "python.exe"))
}
}
}
$trusted = foreach ($candidatePath in $candidatePaths | Sort-Object -Unique) {
if (-not (Test-Path -LiteralPath $candidatePath -PathType Leaf)) { continue }
$item = Get-Item -LiteralPath $candidatePath -Force
if (($item.Attributes -band [System.IO.FileAttributes]::ReparsePoint) -ne 0) { continue }
if ($item.FullName -like "*\Microsoft\WindowsApps\*") { continue }
$version = [version]::new(
[Math]::Max(0, $item.VersionInfo.FileMajorPart),
[Math]::Max(0, $item.VersionInfo.FileMinorPart),
[Math]::Max(0, $item.VersionInfo.FileBuildPart),
[Math]::Max(0, $item.VersionInfo.FilePrivatePart)
)
if ($version -lt [version]"3.11") { continue }
$signature = Get-AuthenticodeSignature -LiteralPath $item.FullName
if (
$signature.Status -ne [System.Management.Automation.SignatureStatus]::Valid -or
$null -eq $signature.SignerCertificate -or
$signature.SignerCertificate.Subject -notlike "*CN=Python Software Foundation*"
) { continue }
[pscustomobject]@{ Path = $item.FullName; Version = $version }
}
return $trusted | Sort-Object Version -Descending
}
try {
$authorityScript = Join-Path $PSScriptRoot "rc06-release-trust-bootstrap.py"
if (-not (Test-Path -LiteralPath $authorityScript -PathType Leaf)) {
throw "The release authority program is missing"
}
Remove-Item Env:PYTHONPATH -ErrorAction SilentlyContinue
Remove-Item Env:PYTHONHOME -ErrorAction SilentlyContinue
Remove-Item Env:PYTHONSTARTUP -ErrorAction SilentlyContinue
Remove-Item Env:PYTHONUSERBASE -ErrorAction SilentlyContinue
$runtime = $null
$ErrorActionPreference = "Continue"
foreach ($candidate in @(Get-TrustedPythonCandidates)) {
$preflightOutput = @(& $candidate.Path -I -S -B $authorityScript runtime-check 2>&1)
if ($LASTEXITCODE -eq 0) {
$runtime = $candidate
break
}
}
$ErrorActionPreference = "Stop"
if ($null -eq $runtime) {
throw "No trusted offline Python runtime has DPAPI and the required cryptography dependency"
}
& $runtime.Path -I -S -B $authorityScript $Command @CommandArguments
exit $LASTEXITCODE
} catch {
Write-Host ("Authority startup failed: " + $_.Exception.Message) -ForegroundColor Red
Write-Host "No authority key, source pin, keyring, signature, or private-key export was created."
exit 2
}
@@ -134,6 +134,7 @@ GOLDEN_INVENTORY_PATH = (
FROZEN_IMPLEMENTATION_PATHS = (
"yuqei-infra/scripts/build-rc06-publication-batch.py",
"yuqei-infra/scripts/rc06-single-reviewer-signing.py",
"yuqei-infra/scripts/rc06-release-trust-bootstrap.py",
"yuqei-contract-platform/services/contract-api/src/yuqei_contract_api/contract_templates.py",
"yuqei-contract-platform/services/contract-api/src/yuqei_contract_api/contract_scene_assets.py",
"yuqei-contract-platform/services/contract-api/src/yuqei_contract_api/template_inputs.py",
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,713 @@
from __future__ import annotations
import base64
import importlib.util
import json
import os
import re
import sys
from datetime import UTC, datetime, timedelta
from pathlib import Path
import pytest
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
REPO_ROOT = Path(__file__).resolve().parents[2]
SCRIPT = REPO_ROOT / "yuqei-infra" / "scripts" / "rc06-release-trust-bootstrap.py"
EXISTING_BATCH_TEST = REPO_ROOT / "yuqei-infra" / "tests" / "test_rc06_publication_batch.py"
AUTHORITY_LAUNCHER = REPO_ROOT / "yuqei-infra" / "scripts" / "Launch-ReleaseAuthority.ps1"
def _load_script():
spec = importlib.util.spec_from_file_location("rc06_release_trust_bootstrap", SCRIPT)
assert spec is not None and spec.loader is not None
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module
spec.loader.exec_module(module)
return module
authority = _load_script()
def _load_existing_batch_test_module():
spec = importlib.util.spec_from_file_location(
"rc06_publication_batch_fixture_helpers",
EXISTING_BATCH_TEST,
)
assert spec is not None and spec.loader is not None
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module
spec.loader.exec_module(module)
return module
def _protect(raw: bytes, role: str) -> bytes:
return b"fixture-protected\0" + role.encode("ascii") + b"\0" + raw[::-1]
def _unprotect(raw: bytes, role: str) -> bytes:
prefix = b"fixture-protected\0" + role.encode("ascii") + b"\0"
if not raw.startswith(prefix):
raise ValueError("wrong fixture protection domain")
return raw[len(prefix) :][::-1]
def _reviewer_registration(path: Path, *, private_key: Ed25519PrivateKey | None = None) -> dict:
private_key = private_key or Ed25519PrivateKey.generate()
public_key = private_key.public_key()
public_raw = public_key.public_bytes(
serialization.Encoding.Raw,
serialization.PublicFormat.Raw,
)
public_pem = public_key.public_bytes(
serialization.Encoding.PEM,
serialization.PublicFormat.SubjectPublicKeyInfo,
)
fingerprint = authority.batch._sha256_bytes(public_raw)
registration = {
"schema_version": authority.REVIEWER_REGISTRATION_SCHEMA,
"key_id": f"chen-yuqi-rc06-{fingerprint[:16]}",
"algorithm": "Ed25519",
"reviewer": dict(authority.batch.SOLE_RELEASE_REVIEWER),
"created_at": "2026-09-27T00:00:00Z",
"public_key_pem": public_pem.decode("ascii"),
"public_key_raw_sha256": fingerprint,
"public_key_pem_sha256": authority.batch._sha256_bytes(public_pem),
}
path.write_bytes(authority._canonical(registration))
return registration
def _initialize(tmp_path: Path):
state = tmp_path / "authority-state"
result = authority.initialize_authority(
state,
protect=_protect,
unprotect=_unprotect,
created_at=datetime(2026, 9, 27, 1, 0, tzinfo=UTC),
)
return state, result, authority.load_authority(state, unprotect=_unprotect)
def _copy_pin_sources(tmp_path: Path) -> Path:
repo = tmp_path / "candidate"
paths = (
"yuqei-infra/scripts/build-rc06-publication-batch.py",
"yuqei-infra/deploy/plan-first-release-snapshot-restore.py",
"yuqei-infra/deploy/plan-rollback-rehearsal.py",
)
for relative in paths:
source = REPO_ROOT / relative
target = repo / relative
target.parent.mkdir(parents=True, exist_ok=True)
target.write_bytes(source.read_bytes())
return repo
def _formal_apply_materials(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> dict:
state, _result, keys = _initialize(tmp_path)
reviewer_private = Ed25519PrivateKey.generate()
reviewer_file = tmp_path / "reviewer-registration.json"
registration = _reviewer_registration(reviewer_file, private_key=reviewer_private)
helpers = _load_existing_batch_test_module()
inventory = helpers.batch.load_runtime_inventory(REPO_ROOT)
manifest = helpers._manifest(inventory, resolved=True)
manifest_raw = authority._canonical(manifest)
manifest_file = tmp_path / "rc06-publication-manifest.json"
manifest_file.write_bytes(manifest_raw)
manifest_sha = authority.batch._sha256_bytes(manifest_raw)
monkeypatch.setattr(
authority.batch,
"TRUSTED_APPROVAL_ROOT_PUBLIC_KEY_SHA256",
keys[authority.ROLE_RC06_ROOT].public_sha256,
)
monkeypatch.setattr(
authority.batch,
"TRUSTED_APPLY_SERVICE_PUBLIC_KEY_SHA256",
keys[authority.ROLE_APPLY_SERVICE].public_sha256,
)
monkeypatch.setattr(authority.batch, "FROZEN_APPROVAL_KEYRING_EPOCH", 1)
keyring_result = authority.build_rc06_candidate_keyring(
state,
reviewer_file,
manifest_file,
manifest_sha,
unprotect=_unprotect,
now=datetime(2026, 9, 27, 3, 0, tzinfo=UTC),
)
keyring_directory = Path(keyring_result["directory"])
keyring_file = keyring_directory / "rc06-approval-keyring.json"
keyring_raw = keyring_file.read_bytes()
keyring = json.loads(keyring_raw)
approved_at = datetime(2026, 9, 27, 3, 10, tzinfo=UTC)
expires_at = datetime(2026, 9, 27, 5, 0, tzinfo=UTC)
approval_payload = authority.batch.build_approval_payload(
manifest,
manifest_raw_sha256=manifest_sha,
key_id=registration["key_id"],
approval_keyring_epoch=1,
approval_keyring_payload_sha256=keyring["keyring_payload_sha256"],
approved_at=approved_at,
expires_at=expires_at,
)
approval_signature = reviewer_private.sign(
authority.batch.APPROVAL_SIGNATURE_DOMAIN + authority._canonical(approval_payload)
)
approval = {
"schema_version": authority.batch.APPROVAL_SCHEMA_VERSION,
"approval_id": (
"rc06-batch-approval-"
+ authority.batch._sha256_bytes(
authority._canonical(approval_payload) + approval_signature
)[:24]
),
"payload": approval_payload,
"signature": base64.b64encode(approval_signature).decode("ascii"),
}
approval_file = tmp_path / "rc06-batch-approval.json"
approval_raw = authority._canonical(approval)
approval_file.write_bytes(approval_raw)
item_results = [
{
"kind": "asset",
"item_id": item["template_id"],
"expected_content_sha256": item["content_sha256"],
"online_content_sha256": item["content_sha256"],
"status": "applied_and_verified",
}
for item in manifest["asset_batch"]["items"]
] + [
{
"kind": "prompt_module",
"item_id": item["key"],
"expected_content_sha256": item["content_sha256"],
"online_content_sha256": item["content_sha256"],
"status": "applied_and_verified",
}
for item in manifest["prompt_module_batch"]["items"]
]
item_results.sort(key=lambda item: (item["kind"], item["item_id"]))
apply_payload = {
"schema_version": authority.batch.APPLY_PAYLOAD_SCHEMA_VERSION,
"batch_manifest_payload_sha256": manifest["manifest_payload_sha256"],
"approval_receipt_sha256": authority.batch._sha256_bytes(approval_raw),
"environment_id": "isolated-uat-fixture",
"applied_at": "2026-09-27T04:00:00Z",
"generated_by": {"type": "system", "component": "rc06-publication-service"},
"item_results": item_results,
"write_count": 74,
"status": "applied_and_verified",
}
payloads_file = tmp_path / "apply-payloads.json"
payloads_raw = authority._canonical(apply_payload)
payloads_file.write_bytes(payloads_raw)
return {
"state": state,
"keys": keys,
"reviewer_private": reviewer_private,
"registration": registration,
"manifest": manifest,
"manifest_file": manifest_file,
"manifest_sha": manifest_sha,
"keyring": keyring,
"keyring_file": keyring_file,
"keyring_sha": authority.batch._sha256_bytes(keyring_raw),
"root_file": keyring_directory / "rc06-approval-root-public-key.raw",
"approval": approval,
"approval_file": approval_file,
"approval_sha": authority.batch._sha256_bytes(approval_raw),
"apply_payload": apply_payload,
"payloads_file": payloads_file,
"payloads_sha": authority.batch._sha256_bytes(payloads_raw),
}
def test_authority_initialization_creates_three_distinct_protected_keys_and_is_idempotent(
tmp_path: Path,
) -> None:
state, result, keys = _initialize(tmp_path)
assert result["status"] == "initialized_not_pinned_not_signed"
assert result["private_key_export_supported"] is False
assert set(keys) == set(authority.AUTHORITY_ROLES)
assert len({item.public_raw for item in keys.values()}) == 3
key_dir = state / authority.KEYS_DIRECTORY_NAME
assert set(child.name for child in key_dir.iterdir()) == (
authority._expected_authority_names() | {authority.signer.BUNDLE_COMPLETE_FILENAME}
)
for role, item in keys.items():
protected_raw = (key_dir / authority._private_filename(role)).read_bytes()
private_der = authority._private_der(item.private_key)
assert private_der not in protected_raw
assert b"BEGIN PRIVATE KEY" not in protected_raw
envelope = json.loads(protected_raw)
assert envelope["protection"] == authority.PROTECTION_NAME
assert base64.b64decode(envelope["ciphertext_base64"], validate=True) != private_der
repeated = authority.initialize_authority(
state,
protect=lambda _raw, _role: pytest.fail("idempotent initialization generated a new key"),
unprotect=_unprotect,
)
assert repeated["status"] == "already_initialized_and_verified"
assert repeated["roles"] == result["roles"]
def test_authority_rejects_partial_or_tampered_bundle(tmp_path: Path) -> None:
state, _result, _keys = _initialize(tmp_path)
key_dir = state / authority.KEYS_DIRECTORY_NAME
(key_dir / authority._public_filename(authority.ROLE_APPLY_SERVICE)).unlink()
with pytest.raises(authority.AuthorityError, match="incomplete"):
authority.initialize_authority(state, protect=_protect, unprotect=_unprotect)
def test_recovery_keyrings_share_only_the_recovery_root_and_verify_both_schemas(
tmp_path: Path,
) -> None:
state, _result, keys = _initialize(tmp_path)
reviewer_file = tmp_path / "reviewer-registration.json"
reviewer = _reviewer_registration(reviewer_file)
now = datetime(2026, 9, 27, 2, 0, tzinfo=UTC)
result = authority.build_recovery_keyrings(
state,
reviewer_file,
epoch=1,
unprotect=_unprotect,
now=now,
validity=timedelta(days=30),
)
assert result["status"] == "recovery_keyrings_created_not_pinned"
assert result["recovery_root_public_key_sha256"] == keys[
authority.ROLE_RECOVERY_ROOT
].public_sha256
assert result["first_release_keyring_payload_sha256"] != result[
"rollback_keyring_payload_sha256"
]
bundle = Path(result["directory"])
first_release = json.loads((bundle / "first-release-recovery-keyring.json").read_bytes())
rollback = json.loads((bundle / "rollback-rehearsal-keyring.json").read_bytes())
assert first_release["root_key_id"] == authority.FIRST_RELEASE_ROOT_KEY_ID
assert rollback["root_key_id"] == authority.ROLLBACK_ROOT_KEY_ID
assert "algorithm" not in first_release["keys"][0]
assert rollback["keys"][0]["algorithm"] == "ed25519"
assert first_release["keys"][0]["public_key_base64"] == rollback["keys"][0][
"public_key_base64"
]
assert reviewer["public_key_raw_sha256"] not in {
item.public_sha256 for item in keys.values()
}
repeated = authority.build_recovery_keyrings(
state,
reviewer_file,
epoch=1,
unprotect=_unprotect,
now=now + timedelta(hours=1),
)
assert repeated["status"] == "recovery_keyrings_already_created_and_verified_not_pinned"
assert repeated["first_release_keyring_payload_sha256"] == result[
"first_release_keyring_payload_sha256"
]
def test_recovery_keyrings_reject_reviewer_reuse_of_any_technical_key(tmp_path: Path) -> None:
state, _result, keys = _initialize(tmp_path)
technical_private = keys[authority.ROLE_APPLY_SERVICE].private_key
reviewer_file = tmp_path / "reviewer-registration.json"
_reviewer_registration(reviewer_file, private_key=technical_private)
with pytest.raises(authority.AuthorityError, match="must differ"):
authority.build_recovery_keyrings(
state,
reviewer_file,
epoch=1,
unprotect=_unprotect,
now=datetime(2026, 9, 27, 2, 0, tzinfo=UTC),
)
def test_pin_preview_and_apply_update_only_public_hashes_and_epoch_in_temp_sources(
tmp_path: Path,
) -> None:
state, _result, keys = _initialize(tmp_path)
reviewer_file = tmp_path / "reviewer-registration.json"
_reviewer_registration(reviewer_file)
recovery = authority.build_recovery_keyrings(
state,
reviewer_file,
epoch=1,
unprotect=_unprotect,
now=datetime(2026, 9, 27, 2, 0, tzinfo=UTC),
)
repo = _copy_pin_sources(tmp_path)
before = {
path.relative_to(repo): path.read_bytes()
for path in repo.rglob("*.py")
}
plan = authority.plan_pin_updates(
repo,
state,
Path(recovery["directory"]),
epoch=1,
unprotect=_unprotect,
)
preview = authority.pin_plan_summary(plan)
assert preview["status"] == "preview_only_not_applied"
assert all(path.read_bytes() == before[path.relative_to(repo)] for path in repo.rglob("*.py"))
assert all(len(str(value)) in {1, 64} for value in preview["values"].values())
applied = authority.apply_pin_plan(plan)
assert applied["status"] == "pins_applied_not_frozen_not_signed"
assert applied["changed_file_count"] == 3
rc06 = (repo / "yuqei-infra/scripts/build-rc06-publication-batch.py").read_text(
encoding="utf-8"
)
first = (repo / "yuqei-infra/deploy/plan-first-release-snapshot-restore.py").read_text(
encoding="utf-8"
)
rollback = (repo / "yuqei-infra/deploy/plan-rollback-rehearsal.py").read_text(
encoding="utf-8"
)
assert f'TRUSTED_APPROVAL_ROOT_PUBLIC_KEY_SHA256 = "{keys[authority.ROLE_RC06_ROOT].public_sha256}"' in rc06
assert f'TRUSTED_APPLY_SERVICE_PUBLIC_KEY_SHA256 = "{keys[authority.ROLE_APPLY_SERVICE].public_sha256}"' in rc06
assert "FROZEN_APPROVAL_KEYRING_EPOCH = 1" in rc06
for text in (first, rollback):
assert f'TRUSTED_ROOT_PUBLIC_KEY_SHA256 = "{keys[authority.ROLE_RECOVERY_ROOT].public_sha256}"' in text
assert re.search(r"(?m)^MIN_KEYRING_EPOCH: int \| None = 1$", text)
assert "PRIVATE KEY" not in text
repeated = authority.plan_pin_updates(
repo,
state,
Path(recovery["directory"]),
epoch=1,
unprotect=_unprotect,
)
assert all(change.original == change.proposed for change in repeated.changes)
assert authority.apply_pin_plan(repeated)["changed_file_count"] == 0
def test_pin_planner_refuses_unknown_existing_pin_without_overwriting(tmp_path: Path) -> None:
state, _result, _keys = _initialize(tmp_path)
reviewer_file = tmp_path / "reviewer-registration.json"
_reviewer_registration(reviewer_file)
recovery = authority.build_recovery_keyrings(
state,
reviewer_file,
epoch=1,
unprotect=_unprotect,
now=datetime(2026, 9, 27, 2, 0, tzinfo=UTC),
)
repo = _copy_pin_sources(tmp_path)
rc06 = repo / "yuqei-infra/scripts/build-rc06-publication-batch.py"
original = rc06.read_text(encoding="utf-8")
rc06.write_text(
original.replace(
'TRUSTED_APPROVAL_ROOT_PUBLIC_KEY_SHA256 = ""',
'TRUSTED_APPROVAL_ROOT_PUBLIC_KEY_SHA256 = "' + "f" * 64 + '"',
),
encoding="utf-8",
)
# A different already-provisioned pin cannot be replaced by a first-time
# provisioning run.
with pytest.raises(authority.AuthorityError, match="different epoch|unexpected existing value"):
authority.plan_pin_updates(
repo,
state,
Path(recovery["directory"]),
epoch=1,
unprotect=_unprotect,
)
def test_pin_apply_rolls_back_completed_files_when_later_replace_fails(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
state, _result, _keys = _initialize(tmp_path)
reviewer_file = tmp_path / "reviewer-registration.json"
_reviewer_registration(reviewer_file)
recovery = authority.build_recovery_keyrings(
state,
reviewer_file,
epoch=1,
unprotect=_unprotect,
now=datetime(2026, 9, 27, 2, 0, tzinfo=UTC),
)
repo = _copy_pin_sources(tmp_path)
plan = authority.plan_pin_updates(
repo,
state,
Path(recovery["directory"]),
epoch=1,
unprotect=_unprotect,
)
real_replace = authority._write_atomic_replacement
calls = 0
def fail_second(path: Path, raw: bytes) -> None:
nonlocal calls
calls += 1
if calls == 2:
raise OSError("fixture replacement failure")
real_replace(path, raw)
monkeypatch.setattr(authority, "_write_atomic_replacement", fail_second)
with pytest.raises(authority.AuthorityError, match="transaction failed"):
authority.apply_pin_plan(plan)
assert all(change.path.read_bytes() == change.original for change in plan.changes)
def test_rc06_candidate_keyring_requires_frozen_pin_and_binds_exact_manifest(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
state, _result, keys = _initialize(tmp_path)
reviewer_file = tmp_path / "reviewer-registration.json"
registration = _reviewer_registration(reviewer_file)
manifest_file = tmp_path / "manifest.json"
manifest_raw = authority._canonical({"fixture": "validated elsewhere in this unit test"})
manifest_file.write_bytes(manifest_raw)
manifest_sha = authority.batch._sha256_bytes(manifest_raw)
monkeypatch.setattr(authority.batch, "validate_manifest", lambda value: value)
with pytest.raises(authority.AuthorityError, match="frozen RC-06 root pin"):
authority.build_rc06_candidate_keyring(
state,
reviewer_file,
manifest_file,
manifest_sha,
unprotect=_unprotect,
now=datetime(2026, 9, 27, 3, 0, tzinfo=UTC),
)
monkeypatch.setattr(
authority.batch,
"TRUSTED_APPROVAL_ROOT_PUBLIC_KEY_SHA256",
keys[authority.ROLE_RC06_ROOT].public_sha256,
)
monkeypatch.setattr(authority.batch, "FROZEN_APPROVAL_KEYRING_EPOCH", 1)
result = authority.build_rc06_candidate_keyring(
state,
reviewer_file,
manifest_file,
manifest_sha,
unprotect=_unprotect,
now=datetime(2026, 9, 27, 3, 0, tzinfo=UTC),
)
assert result["status"] == "rc06_candidate_keyring_created_not_approved"
bundle = Path(result["directory"])
keyring = json.loads((bundle / "rc06-approval-keyring.json").read_bytes())
assert keyring["authorized_batch_manifest_raw_sha256"] == manifest_sha
assert keyring["epoch"] == 1
assert keyring["keys"][0]["key_id"] == registration["key_id"]
assert keyring["root_key_id"] == authority.batch.TRUSTED_APPROVAL_ROOT_KEY_ID
repeated = authority.build_rc06_candidate_keyring(
state,
reviewer_file,
manifest_file,
manifest_sha,
unprotect=_unprotect,
now=datetime(2026, 9, 27, 4, 0, tzinfo=UTC),
)
assert repeated["status"] == "rc06_candidate_keyring_already_created_and_verified_not_approved"
with pytest.raises(authority.AuthorityError, match="SHA-256 mismatch"):
authority.build_rc06_candidate_keyring(
state,
reviewer_file,
manifest_file,
"f" * 64,
unprotect=_unprotect,
now=datetime(2026, 9, 27, 4, 0, tzinfo=UTC),
)
def test_apply_private_key_provision_command_fails_closed_without_export(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
capsys: pytest.CaptureFixture[str],
) -> None:
monkeypatch.setattr(authority, "_assert_runtime", lambda: None)
result = authority.main(
[
"provision-apply-private-key",
"--state-directory",
os.fspath(tmp_path / "authority-state"),
]
)
captured = capsys.readouterr()
assert result == 2
assert "not implemented" in captured.err
assert '"private_material_exported":false' in captured.err
assert list(tmp_path.iterdir()) == []
def test_apply_payload_signing_is_bound_verified_atomic_and_idempotent(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
materials = _formal_apply_materials(tmp_path, monkeypatch)
output = tmp_path / "signed-apply-receipts"
result = authority.sign_apply_payloads(
materials["state"],
manifest_file=materials["manifest_file"],
manifest_sha256=materials["manifest_sha"],
approval_file=materials["approval_file"],
approval_sha256=materials["approval_sha"],
approval_keyring_file=materials["keyring_file"],
approval_keyring_sha256=materials["keyring_sha"],
approval_root_public_key_file=materials["root_file"],
payloads_file=materials["payloads_file"],
payloads_sha256=materials["payloads_sha"],
output_directory=output,
unprotect=_unprotect,
)
assert result["status"] == "apply_receipts_signed_and_verified_not_published"
assert result["receipt_count"] == 1
assert result["business_api_calls"] == 0
assert result["private_keys_in_bundle"] is False
receipt = json.loads((output / "apply-receipt-001.json").read_bytes())
assert authority.batch.validate_apply_receipt(
materials["manifest"],
materials["manifest_sha"],
materials["approval"],
materials["keyring"],
materials["keys"][authority.ROLE_RC06_ROOT].public_key,
materials["keys"][authority.ROLE_APPLY_SERVICE].public_key,
materials["approval_sha"],
receipt,
) == receipt
repeated = authority.sign_apply_payloads(
materials["state"],
manifest_file=materials["manifest_file"],
manifest_sha256=materials["manifest_sha"],
approval_file=materials["approval_file"],
approval_sha256=materials["approval_sha"],
approval_keyring_file=materials["keyring_file"],
approval_keyring_sha256=materials["keyring_sha"],
approval_root_public_key_file=materials["root_file"],
payloads_file=materials["payloads_file"],
payloads_sha256=materials["payloads_sha"],
output_directory=output,
unprotect=_unprotect,
)
assert repeated["status"] == "apply_receipts_already_signed_and_verified_not_published"
assert repeated["receipts"] == result["receipts"]
def test_apply_payload_signing_rejects_tamper_cross_approval_and_partial_bundle(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
materials = _formal_apply_materials(tmp_path, monkeypatch)
tampered = dict(materials["apply_payload"])
tampered["batch_manifest_payload_sha256"] = "f" * 64
tampered_file = tmp_path / "tampered-payload.json"
tampered_raw = authority._canonical(tampered)
tampered_file.write_bytes(tampered_raw)
tampered_output = tmp_path / "tampered-output"
with pytest.raises(authority.AuthorityError, match="not bound to this batch"):
authority.sign_apply_payloads(
materials["state"],
manifest_file=materials["manifest_file"],
manifest_sha256=materials["manifest_sha"],
approval_file=materials["approval_file"],
approval_sha256=materials["approval_sha"],
approval_keyring_file=materials["keyring_file"],
approval_keyring_sha256=materials["keyring_sha"],
approval_root_public_key_file=materials["root_file"],
payloads_file=tampered_file,
payloads_sha256=authority.batch._sha256_bytes(tampered_raw),
output_directory=tampered_output,
unprotect=_unprotect,
)
assert not tampered_output.exists()
second_payload = dict(materials["approval"]["payload"])
second_payload["approved_at"] = "2026-09-27T03:15:00Z"
second_signature = materials["reviewer_private"].sign(
authority.batch.APPROVAL_SIGNATURE_DOMAIN + authority._canonical(second_payload)
)
second_approval = {
"schema_version": authority.batch.APPROVAL_SCHEMA_VERSION,
"approval_id": (
"rc06-batch-approval-"
+ authority.batch._sha256_bytes(
authority._canonical(second_payload) + second_signature
)[:24]
),
"payload": second_payload,
"signature": base64.b64encode(second_signature).decode("ascii"),
}
second_approval_file = tmp_path / "second-approval.json"
second_approval_raw = authority._canonical(second_approval)
second_approval_file.write_bytes(second_approval_raw)
with pytest.raises(authority.AuthorityError, match="not bound to the approval receipt"):
authority.sign_apply_payloads(
materials["state"],
manifest_file=materials["manifest_file"],
manifest_sha256=materials["manifest_sha"],
approval_file=second_approval_file,
approval_sha256=authority.batch._sha256_bytes(second_approval_raw),
approval_keyring_file=materials["keyring_file"],
approval_keyring_sha256=materials["keyring_sha"],
approval_root_public_key_file=materials["root_file"],
payloads_file=materials["payloads_file"],
payloads_sha256=materials["payloads_sha"],
output_directory=tmp_path / "cross-approval-output",
unprotect=_unprotect,
)
partial = dict(materials["apply_payload"])
partial["item_results"] = partial["item_results"][:-1]
payload_list = [materials["apply_payload"], partial]
payload_list_file = tmp_path / "payload-list.json"
payload_list_raw = authority._canonical(payload_list)
payload_list_file.write_bytes(payload_list_raw)
partial_output = tmp_path / "partial-output"
with pytest.raises(authority.AuthorityError, match="74-item online evidence drift"):
authority.sign_apply_payloads(
materials["state"],
manifest_file=materials["manifest_file"],
manifest_sha256=materials["manifest_sha"],
approval_file=materials["approval_file"],
approval_sha256=materials["approval_sha"],
approval_keyring_file=materials["keyring_file"],
approval_keyring_sha256=materials["keyring_sha"],
approval_root_public_key_file=materials["root_file"],
payloads_file=payload_list_file,
payloads_sha256=authority.batch._sha256_bytes(payload_list_raw),
output_directory=partial_output,
unprotect=_unprotect,
)
assert not partial_output.exists()
def test_authority_launcher_uses_authority_script_and_forwards_non_secret_arguments() -> None:
text = AUTHORITY_LAUNCHER.read_text(encoding="utf-8-sig")
assert '"rc06-release-trust-bootstrap.py"' in text
assert "ValueFromRemainingArguments = $true" in text
assert "$authorityScript $Command @CommandArguments" in text
assert "rc06-single-reviewer-signing.py" not in text
assert "password" not in text.casefold()
assert "passphrase" not in text.casefold()
@pytest.mark.skipif(os.name != "nt", reason="Windows CurrentUser DPAPI is platform-specific")
def test_windows_current_user_dpapi_round_trip_has_role_entropy() -> None:
raw = b"not-a-real-private-key-fixture"
protected = authority._protect_current_user(raw, authority.ROLE_RC06_ROOT)
assert protected != raw
assert authority._unprotect_current_user(protected, authority.ROLE_RC06_ROOT) == raw
with pytest.raises(authority.AuthorityError):
authority._unprotect_current_user(protected, authority.ROLE_APPLY_SERVICE)