fix(security): harden image context and runtime receipts

This commit is contained in:
ogt
2026-07-10 19:13:22 +08:00
parent d6aeb76c4b
commit 2bbb1e8e8b
12 changed files with 246 additions and 16 deletions

View File

@@ -20,6 +20,7 @@ POLICY = "global_product_governance_v2_security_review_v1"
ROOT = Path(__file__).resolve().parents[1]
ASSET_INVENTORY_PATH = Path("governance/ewoooc_asset_inventory.json")
QUALITY_BASELINE_PATH = Path("governance/security_governance_review_baseline.json")
SOURCE_RECEIPT_PATH = Path("governance/security_governance_source_receipt.json")
MUTATING_METHODS = {"POST", "PUT", "PATCH", "DELETE"}
AUTH_DECORATOR_MARKERS = (
@@ -58,6 +59,19 @@ ASSET_REQUIRED_FIELDS = {
"backup_restore",
"learning_targets",
}
DOCKERIGNORE_REQUIRED_PATTERNS = {
".git",
".gitea",
".env",
".env.*",
"data",
"logs",
"backups",
"config/google_credentials.json",
"config/google_token.json",
"config/google_token.pickle",
"config/*.json",
}
def _read(path: Path) -> str:
@@ -250,6 +264,53 @@ def _quality_baseline(root: Path) -> dict[str, Any]:
}
def _source_receipt(root: Path) -> dict[str, Any]:
path = root / SOURCE_RECEIPT_PATH
try:
payload = json.loads(_read(path))
except (TypeError, json.JSONDecodeError):
payload = {}
checks = payload.get("checks") if isinstance(payload, dict) else []
checks_by_id = {
item.get("id"): item
for item in checks
if isinstance(item, dict) and item.get("id")
} if isinstance(checks, list) else {}
source_commit = str(payload.get("source_commit") or "") if isinstance(payload, dict) else ""
commit_shape_valid = len(source_commit) == 40 and all(
char in "0123456789abcdefABCDEF" for char in source_commit
)
return {
"path": SOURCE_RECEIPT_PATH.as_posix(),
"available": bool(payload) and payload.get("receipt_kind") == "security_governance_source_receipt",
"source_commit": source_commit,
"source_commit_shape_valid": commit_shape_valid,
"generated_at": payload.get("generated_at") if isinstance(payload, dict) else None,
"release_gate_status": (
(payload.get("release_gate") or {}).get("status")
if isinstance(payload, dict) else None
),
"_checks": checks_by_id,
}
def _docker_build_context_posture(root: Path) -> dict[str, Any]:
path = root / ".dockerignore"
patterns = {
line.strip().rstrip("/")
for line in _read(path).splitlines()
if line.strip() and not line.lstrip().startswith("#")
}
missing = sorted(DOCKERIGNORE_REQUIRED_PATTERNS - patterns)
return {
"path": ".dockerignore",
"exists": path.is_file(),
"required_pattern_count": len(DOCKERIGNORE_REQUIRED_PATTERNS),
"missing_patterns": missing,
"safe": path.is_file() and not missing,
}
def _workflow_supply_chain(root: Path) -> dict[str, Any]:
files = sorted((root / ".gitea" / "workflows").glob("*.y*ml"))
forbidden: list[dict[str, Any]] = []
@@ -395,7 +456,25 @@ def build_security_governance_review(
route_posture["unclassified_unguarded"] = route_posture["unclassified_unguarded"][:detail_limit]
route_posture["mutating_unguarded"] = route_posture["mutating_unguarded"][:detail_limit]
assets = _asset_inventory(scan_root)
source_receipt = _source_receipt(scan_root)
supply_chain = _workflow_supply_chain(scan_root)
docker_context = _docker_build_context_posture(scan_root)
supply_chain["docker_build_context"] = docker_context
supply_chain["source_chain_ready"] = bool(
supply_chain["gitea_only"] and docker_context["safe"]
)
receipt_supply = source_receipt["_checks"].get("GV.SC-gitea-only-supply-chain", {})
if (
supply_chain["workflow_count"] == 0
and source_receipt["available"]
and source_receipt["source_commit_shape_valid"]
and receipt_supply.get("status") == "pass"
):
receipt_evidence = receipt_supply.get("evidence") or {}
supply_chain = dict(receipt_evidence) if isinstance(receipt_evidence, dict) else {}
supply_chain["evidence_source"] = "cd_source_receipt"
supply_chain["source_commit"] = source_receipt["source_commit"]
supply_chain["source_chain_ready"] = True
dependencies = _dependency_posture(scan_root)
quality = _quality_baseline(scan_root)
large_files = _large_python_files(scan_root)
@@ -447,6 +526,24 @@ def build_security_governance_review(
)
if marker in constitution
]
policy_alignment_ready = bool(constitution) and not policy_drift_markers
policy_evidence = {
"legacy_markers": policy_drift_markers,
"evidence_source": "source_file" if constitution else "missing",
}
receipt_policy = source_receipt["_checks"].get("GV.PO-policy-alignment", {})
if (
not constitution
and source_receipt["available"]
and source_receipt["source_commit_shape_valid"]
and receipt_policy.get("status") == "pass"
):
policy_alignment_ready = True
policy_evidence = {
"legacy_markers": [],
"evidence_source": "cd_source_receipt",
"source_commit": source_receipt["source_commit"],
}
access_contract_ready = bool(
central_policy_registered
@@ -498,12 +595,12 @@ def build_security_governance_review(
_check(
"GV.SC-gitea-only-supply-chain",
"GOVERN/PROTECT",
"pass" if supply_chain["gitea_only"] else "fail",
"pass" if supply_chain["source_chain_ready"] else "fail",
"critical",
"Gitea workflows have no external action or forbidden GitHub source reference." if supply_chain["gitea_only"] else "Workflow still depends on an external action/source.",
"Gitea workflow and Docker build context exclude external actions, forbidden sources, secrets and runtime data." if supply_chain["source_chain_ready"] else "Source workflow or Docker build context boundary is incomplete.",
supply_chain,
"replace_external_action_resolution_with_gitea_job_token_checkout",
release_blocking=not supply_chain["gitea_only"],
"keep_gitea_checkout_and_generate_commit_bound_source_receipt",
release_blocking=not supply_chain["source_chain_ready"],
),
_check(
"ID.RA-dependency-vulnerability-management",
@@ -544,12 +641,12 @@ def build_security_governance_review(
_check(
"GV.PO-policy-alignment",
"GOVERN",
"pass" if not policy_drift_markers else "fail",
"pass" if policy_alignment_ready else "fail",
"high",
"Constitution is aligned to current production/governance doctrine." if not policy_drift_markers else "Legacy security/deployment doctrine still conflicts with production truth.",
{"legacy_markers": policy_drift_markers},
"Constitution is aligned to current production/governance doctrine." if policy_alignment_ready else "Policy source is missing or legacy doctrine still conflicts with production truth.",
policy_evidence,
"sunset_legacy_rules_with_owner_expiry_replacement_and_verifier",
release_blocking=bool(policy_drift_markers),
release_blocking=not policy_alignment_ready,
),
_check(
"GV.OV-modularization",
@@ -645,6 +742,9 @@ def build_security_governance_review(
},
"checks": checks,
"quality_baseline": quality,
"source_receipt": {
key: value for key, value in source_receipt.items() if key != "_checks"
},
"release_gate": {
"status": "pass" if not blocking else "fail",
"blocking_failure_count": len(blocking),