feat(api): expose gitea runner attestation request
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 27s
CD Pipeline / build-and-deploy (push) Has been cancelled
CD Pipeline / post-deploy-checks (push) Has been cancelled
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 27s
CD Pipeline / build-and-deploy (push) Has been cancelled
CD Pipeline / post-deploy-checks (push) Has been cancelled
This commit is contained in:
@@ -307,6 +307,8 @@ jobs:
|
||||
;;
|
||||
apps/api/src/services/gitea_private_inventory_p0_scorecard.py)
|
||||
;;
|
||||
apps/api/src/services/gitea_workflow_runner_owner_attestation_request.py)
|
||||
;;
|
||||
apps/api/src/services/reboot_auto_recovery_slo_scorecard.py)
|
||||
;;
|
||||
apps/api/src/services/reboot_auto_recovery_drill_preflight.py)
|
||||
@@ -405,6 +407,8 @@ jobs:
|
||||
;;
|
||||
apps/api/tests/test_gitea_private_inventory_p0_scorecard_api.py)
|
||||
;;
|
||||
apps/api/tests/test_gitea_workflow_runner_owner_attestation_request_api.py)
|
||||
;;
|
||||
apps/api/tests/test_reboot_auto_recovery_slo_scorecard_api.py)
|
||||
;;
|
||||
apps/api/tests/test_iwooos_security_operating_system.py)
|
||||
@@ -583,6 +587,7 @@ jobs:
|
||||
src/services/gitea_owner_coverage_attestation_validation.py \
|
||||
src/services/gitea_private_inventory_closeout_validation.py \
|
||||
src/services/gitea_private_inventory_p0_scorecard.py \
|
||||
src/services/gitea_workflow_runner_owner_attestation_request.py \
|
||||
src/services/reboot_auto_recovery_slo_scorecard.py \
|
||||
src/services/reboot_auto_recovery_drill_preflight.py \
|
||||
src/services/iwooos_security_operating_system.py \
|
||||
@@ -635,6 +640,7 @@ jobs:
|
||||
tests/test_backup_dr_readiness_matrix_api.py \
|
||||
tests/test_credential_escrow_evidence_intake_readiness_api.py \
|
||||
tests/test_gitea_private_inventory_p0_scorecard_api.py \
|
||||
tests/test_gitea_workflow_runner_owner_attestation_request_api.py \
|
||||
tests/test_reboot_auto_recovery_slo_scorecard_api.py \
|
||||
tests/test_iwooos_security_operating_system.py \
|
||||
tests/e2e_network_test.py::TestHMACVerification::test_valid_hmac_signature \
|
||||
|
||||
@@ -381,6 +381,9 @@ from src.services.gitea_private_inventory_closeout_validation import (
|
||||
from src.services.gitea_private_inventory_p0_scorecard import (
|
||||
load_latest_gitea_private_inventory_p0_scorecard,
|
||||
)
|
||||
from src.services.gitea_workflow_runner_owner_attestation_request import (
|
||||
load_latest_gitea_workflow_runner_owner_attestation_request,
|
||||
)
|
||||
from src.services.gitea_workflow_runner_health import (
|
||||
load_latest_gitea_workflow_runner_health,
|
||||
)
|
||||
@@ -4129,6 +4132,39 @@ async def get_gitea_workflow_runner_health() -> dict[str, Any]:
|
||||
) from exc
|
||||
|
||||
|
||||
@router.get(
|
||||
"/gitea-workflow-runner-owner-attestation-request",
|
||||
response_model=dict[str, Any],
|
||||
summary="取得 Gitea workflow runner owner attestation request",
|
||||
description=(
|
||||
"從 Gitea workflow / runner health contract 產生 runner label owner "
|
||||
"attestation request packet;此端點只回傳脫敏 metadata 欄位、驗收規則與禁止事項。"
|
||||
"它不送出 request、不呼叫 Gitea API、不修改 workflow、不重啟或註冊 runner、"
|
||||
"不改 runner label、不讀 Secret 或 runner token、不觸發 workflow。"
|
||||
),
|
||||
)
|
||||
async def get_gitea_workflow_runner_owner_attestation_request() -> dict[str, Any]:
|
||||
"""Return the read-only Gitea runner owner attestation request packet."""
|
||||
try:
|
||||
return await asyncio.to_thread(
|
||||
load_latest_gitea_workflow_runner_owner_attestation_request
|
||||
)
|
||||
except FileNotFoundError as exc:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=str(exc),
|
||||
) from exc
|
||||
except (json.JSONDecodeError, ValueError) as exc:
|
||||
logger.error(
|
||||
"gitea_workflow_runner_owner_attestation_request_invalid",
|
||||
error=str(exc),
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="Gitea workflow runner owner attestation request 無效",
|
||||
) from exc
|
||||
|
||||
|
||||
@router.get(
|
||||
"/observability-contract-matrix",
|
||||
response_model=dict[str, Any],
|
||||
|
||||
@@ -33,6 +33,9 @@ from src.services.credential_escrow_evidence_intake_readiness import (
|
||||
from src.services.gitea_private_inventory_p0_scorecard import (
|
||||
load_latest_gitea_private_inventory_p0_scorecard,
|
||||
)
|
||||
from src.services.gitea_workflow_runner_owner_attestation_request import (
|
||||
load_latest_gitea_workflow_runner_owner_attestation_request,
|
||||
)
|
||||
from src.services.gitea_workflow_runner_health import (
|
||||
load_latest_gitea_workflow_runner_health,
|
||||
)
|
||||
@@ -65,6 +68,9 @@ def load_delivery_closure_workbench() -> dict[str, Any]:
|
||||
load_latest_awoooi_gitea_onboarding_warning_step_runtime_enablement_gate()
|
||||
)
|
||||
gitea = load_latest_gitea_workflow_runner_health()
|
||||
gitea_runner_attestation_request = (
|
||||
load_latest_gitea_workflow_runner_owner_attestation_request()
|
||||
)
|
||||
runtime = load_latest_runtime_surface_inventory()
|
||||
backup = load_latest_backup_dr_readiness_matrix()
|
||||
credential_escrow_intake = load_latest_credential_escrow_evidence_intake_readiness()
|
||||
@@ -78,6 +84,7 @@ def load_delivery_closure_workbench() -> dict[str, Any]:
|
||||
cicd_template_copy_receipt=cicd_template_copy_receipt,
|
||||
cicd_runtime_enablement_gate=cicd_runtime_enablement_gate,
|
||||
gitea=gitea,
|
||||
gitea_runner_attestation_request=gitea_runner_attestation_request,
|
||||
runtime=runtime,
|
||||
backup=backup,
|
||||
credential_escrow_intake=credential_escrow_intake,
|
||||
@@ -95,6 +102,7 @@ def build_delivery_closure_workbench(
|
||||
cicd_template_copy_receipt: dict[str, Any],
|
||||
cicd_runtime_enablement_gate: dict[str, Any],
|
||||
gitea: dict[str, Any],
|
||||
gitea_runner_attestation_request: dict[str, Any],
|
||||
runtime: dict[str, Any],
|
||||
backup: dict[str, Any],
|
||||
credential_escrow_intake: dict[str, Any],
|
||||
@@ -145,6 +153,18 @@ def build_delivery_closure_workbench(
|
||||
production_deploy_rollups = _dict(production_deploy.get("rollups"))
|
||||
gitea_status = _dict(gitea.get("program_status"))
|
||||
gitea_rollups = _dict(gitea.get("rollups"))
|
||||
gitea_runner_request_readback = _dict(
|
||||
gitea_runner_attestation_request.get("readback")
|
||||
)
|
||||
gitea_runner_request_packet = _dict(
|
||||
gitea_runner_attestation_request.get("request_packet")
|
||||
)
|
||||
gitea_runner_request_rollups = _dict(
|
||||
gitea_runner_attestation_request.get("rollups")
|
||||
)
|
||||
gitea_runner_request_boundaries = _dict(
|
||||
gitea_runner_attestation_request.get("operation_boundaries")
|
||||
)
|
||||
runtime_status = _dict(runtime.get("program_status"))
|
||||
runtime_rollups = _dict(runtime.get("rollups"))
|
||||
backup_status = _dict(backup.get("program_status"))
|
||||
@@ -1007,6 +1027,47 @@ def build_delivery_closure_workbench(
|
||||
"metric": {
|
||||
"kind": "workflow_count",
|
||||
"count": _int(gitea_rollups.get("total_workflows")),
|
||||
"runner_attestation_request_status": str(
|
||||
gitea_runner_attestation_request.get("status") or ""
|
||||
),
|
||||
"runner_attestation_request_ready": (
|
||||
gitea_runner_request_rollups.get("request_template_ready") is True
|
||||
),
|
||||
"runner_attestation_request_active_blocker_count": _int(
|
||||
gitea_runner_request_rollups.get("active_blocker_count")
|
||||
),
|
||||
"runner_attestation_contract_id": str(
|
||||
gitea_runner_request_readback.get("contract_id") or ""
|
||||
),
|
||||
"runner_attestation_workflow_count": _int(
|
||||
gitea_runner_request_rollups.get(
|
||||
"workflow_requiring_attestation_count"
|
||||
)
|
||||
),
|
||||
"runner_attestation_required_owner_field_count": _int(
|
||||
gitea_runner_request_rollups.get("required_owner_field_count")
|
||||
),
|
||||
"runner_attestation_owner_response_received_count": _int(
|
||||
gitea_runner_request_rollups.get("owner_response_received_count")
|
||||
),
|
||||
"runner_attestation_owner_response_accepted_count": _int(
|
||||
gitea_runner_request_rollups.get("owner_response_accepted_count")
|
||||
),
|
||||
"runner_attestation_request_send_performed": (
|
||||
gitea_runner_request_boundaries.get("request_send_performed")
|
||||
is True
|
||||
),
|
||||
"runner_attestation_runner_label_change_allowed": (
|
||||
gitea_runner_request_boundaries.get("runner_label_change_allowed")
|
||||
is True
|
||||
),
|
||||
"runner_attestation_runner_registration_allowed": (
|
||||
gitea_runner_request_boundaries.get("runner_registration_allowed")
|
||||
is True
|
||||
),
|
||||
"runner_attestation_secret_read_allowed": (
|
||||
gitea_runner_request_boundaries.get("secret_read_allowed") is True
|
||||
),
|
||||
},
|
||||
"href": "/deployments",
|
||||
"next_action": _first_contract_action(gitea.get("runner_contracts")),
|
||||
@@ -1363,6 +1424,55 @@ def build_delivery_closure_workbench(
|
||||
)
|
||||
is True
|
||||
),
|
||||
"gitea_runner_attestation_request_status": str(
|
||||
gitea_runner_attestation_request.get("status") or ""
|
||||
),
|
||||
"gitea_runner_attestation_request_ready": (
|
||||
gitea_runner_request_rollups.get("request_template_ready") is True
|
||||
),
|
||||
"gitea_runner_attestation_request_active_blocker_count": _int(
|
||||
gitea_runner_request_rollups.get("active_blocker_count")
|
||||
),
|
||||
"gitea_runner_attestation_contract_id": str(
|
||||
gitea_runner_request_readback.get("contract_id") or ""
|
||||
),
|
||||
"gitea_runner_attestation_runner_label": str(
|
||||
gitea_runner_request_readback.get("runner_label") or ""
|
||||
),
|
||||
"gitea_runner_attestation_workflow_count": _int(
|
||||
gitea_runner_request_rollups.get(
|
||||
"workflow_requiring_attestation_count"
|
||||
)
|
||||
),
|
||||
"gitea_runner_attestation_required_owner_field_count": _int(
|
||||
gitea_runner_request_rollups.get("required_owner_field_count")
|
||||
),
|
||||
"gitea_runner_attestation_forbidden_action_count": _int(
|
||||
gitea_runner_request_rollups.get("forbidden_action_count")
|
||||
),
|
||||
"gitea_runner_attestation_owner_response_received_count": _int(
|
||||
gitea_runner_request_rollups.get("owner_response_received_count")
|
||||
),
|
||||
"gitea_runner_attestation_owner_response_accepted_count": _int(
|
||||
gitea_runner_request_rollups.get("owner_response_accepted_count")
|
||||
),
|
||||
"gitea_runner_attestation_request_sent": (
|
||||
gitea_runner_request_packet.get("request_sent") is True
|
||||
),
|
||||
"gitea_runner_attestation_request_send_performed": (
|
||||
gitea_runner_request_boundaries.get("request_send_performed") is True
|
||||
),
|
||||
"gitea_runner_attestation_runner_label_change_allowed": (
|
||||
gitea_runner_request_boundaries.get("runner_label_change_allowed")
|
||||
is True
|
||||
),
|
||||
"gitea_runner_attestation_runner_registration_allowed": (
|
||||
gitea_runner_request_boundaries.get("runner_registration_allowed")
|
||||
is True
|
||||
),
|
||||
"gitea_runner_attestation_secret_read_allowed": (
|
||||
gitea_runner_request_boundaries.get("secret_read_allowed") is True
|
||||
),
|
||||
"p0_cicd_baseline_status": str(cicd_baseline.get("status") or ""),
|
||||
"p0_cicd_baseline_workplan_id": str(
|
||||
cicd_baseline_readback.get("workplan_id") or ""
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
"""Gitea workflow runner owner attestation request readback.
|
||||
|
||||
Builds a metadata-only request packet from the committed Gitea workflow /
|
||||
runner health contract. This module never sends the request, calls Gitea,
|
||||
changes runner labels, registers runners, triggers workflows, or reads secrets.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from src.services.gitea_workflow_runner_health import (
|
||||
load_latest_gitea_workflow_runner_health,
|
||||
)
|
||||
|
||||
_SCHEMA_VERSION = "gitea_workflow_runner_owner_attestation_request_v1"
|
||||
_CONTRACT_ID = "ubuntu_latest_gitea_runner_label"
|
||||
_REQUIRED_FIELDS = [
|
||||
"runner_label",
|
||||
"actual_runner_mapping_ref",
|
||||
"runner_host_alias",
|
||||
"executor_scope",
|
||||
"capacity_owner",
|
||||
"maintenance_window",
|
||||
"evidence_ref",
|
||||
"no_secret_value_attestation",
|
||||
"no_runner_registration_change_attestation",
|
||||
"rollback_owner",
|
||||
"post_check_owner",
|
||||
]
|
||||
_FORBIDDEN_ACTIONS = [
|
||||
"workflow_modification",
|
||||
"workflow_dispatch",
|
||||
"runner_label_change",
|
||||
"runner_registration",
|
||||
"runner_restart",
|
||||
"runner_container_stop",
|
||||
"secret_or_runner_token_read",
|
||||
"gitea_api_write",
|
||||
"github_api",
|
||||
]
|
||||
|
||||
|
||||
def load_latest_gitea_workflow_runner_owner_attestation_request() -> dict[str, Any]:
|
||||
"""Return the owner attestation request packet for runner label evidence."""
|
||||
|
||||
health = load_latest_gitea_workflow_runner_health()
|
||||
rollups = _dict(health.get("rollups"))
|
||||
action_contracts = [
|
||||
contract
|
||||
for contract in health.get("runner_contracts", [])
|
||||
if isinstance(contract, dict)
|
||||
and contract.get("contract_id")
|
||||
in set(_strings(rollups.get("runner_contracts_requiring_action")))
|
||||
]
|
||||
target_contract = next(
|
||||
(
|
||||
contract
|
||||
for contract in action_contracts
|
||||
if contract.get("contract_id") == _CONTRACT_ID
|
||||
),
|
||||
{},
|
||||
)
|
||||
workflow_ids = _strings(rollups.get("workflow_ids_requiring_runner_attestation"))
|
||||
request_ready = bool(target_contract) and bool(workflow_ids)
|
||||
active_blockers = []
|
||||
if not request_ready:
|
||||
active_blockers.append("runner_attestation_request_source_missing")
|
||||
active_blockers.append("owner_attestation_response_not_received")
|
||||
|
||||
return {
|
||||
"schema_version": _SCHEMA_VERSION,
|
||||
"priority": "P1-002",
|
||||
"scope": "gitea_workflow_runner_owner_attestation_request",
|
||||
"status": (
|
||||
"owner_attestation_request_ready_waiting_response"
|
||||
if request_ready
|
||||
else "blocked_owner_attestation_request_source_missing"
|
||||
),
|
||||
"readback": {
|
||||
"workplan_id": "P1-002-GITEA-RUNNER-OWNER-ATTESTATION",
|
||||
"source_health_schema_version": health.get("schema_version"),
|
||||
"source_health_endpoint": "/api/v1/agents/gitea-workflow-runner-health",
|
||||
"contract_id": _CONTRACT_ID,
|
||||
"runner_label": _first_string(target_contract.get("runner_labels")),
|
||||
"request_packet_id": "gitea_runner_owner_attestation_request::ubuntu_latest",
|
||||
"safe_next_step": (
|
||||
"collect_redacted_owner_attestation_response_then_validate_no_runner_mutation"
|
||||
),
|
||||
},
|
||||
"request_packet": {
|
||||
"request_template_ready": request_ready,
|
||||
"request_sent": False,
|
||||
"owner_response_received": False,
|
||||
"owner_response_accepted": False,
|
||||
"contract_id": _CONTRACT_ID,
|
||||
"display_name": str(target_contract.get("display_name") or ""),
|
||||
"risk_level": str(target_contract.get("risk_level") or "high"),
|
||||
"runner_labels": _strings(target_contract.get("runner_labels")),
|
||||
"workflow_ids_requiring_attestation": workflow_ids,
|
||||
"required_owner_fields": _REQUIRED_FIELDS,
|
||||
"forbidden_actions": _FORBIDDEN_ACTIONS,
|
||||
"allowed_response_shape": {
|
||||
"redacted_metadata_only": True,
|
||||
"evidence_ref_required": True,
|
||||
"secret_value_allowed": False,
|
||||
"runner_token_allowed": False,
|
||||
"authorization_header_allowed": False,
|
||||
"raw_runner_config_allowed": False,
|
||||
},
|
||||
"acceptance_checks": [
|
||||
"runner_label_mapping_ref_present",
|
||||
"runner_host_alias_present",
|
||||
"capacity_owner_present",
|
||||
"maintenance_window_present",
|
||||
"no_secret_value_attested",
|
||||
"no_runner_registration_change_attested",
|
||||
"post_check_owner_present",
|
||||
],
|
||||
"rejection_rules": [
|
||||
"contains_secret_value",
|
||||
"contains_runner_token",
|
||||
"requests_runner_label_change",
|
||||
"requests_runner_registration",
|
||||
"requests_workflow_dispatch",
|
||||
"missing_evidence_ref",
|
||||
],
|
||||
},
|
||||
"rollups": {
|
||||
"request_template_ready": request_ready,
|
||||
"request_packet_count": int(request_ready),
|
||||
"workflow_requiring_attestation_count": len(workflow_ids),
|
||||
"runner_contracts_requiring_action_count": len(action_contracts),
|
||||
"required_owner_field_count": len(_REQUIRED_FIELDS),
|
||||
"forbidden_action_count": len(_FORBIDDEN_ACTIONS),
|
||||
"owner_response_received_count": 0,
|
||||
"owner_response_accepted_count": 0,
|
||||
"active_blocker_count": len(active_blockers),
|
||||
"runtime_gate_opened": False,
|
||||
},
|
||||
"active_blockers": active_blockers,
|
||||
"operation_boundaries": {
|
||||
"read_only_api_allowed": True,
|
||||
"request_send_performed": False,
|
||||
"workflow_modification_allowed": False,
|
||||
"workflow_trigger_allowed": False,
|
||||
"runner_label_change_allowed": False,
|
||||
"runner_registration_allowed": False,
|
||||
"runner_restart_allowed": False,
|
||||
"runner_container_stop_allowed": False,
|
||||
"secret_read_allowed": False,
|
||||
"secret_plaintext_allowed": False,
|
||||
"runner_token_read_allowed": False,
|
||||
"gitea_api_write_allowed": False,
|
||||
"github_api_used": False,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def _dict(value: Any) -> dict[str, Any]:
|
||||
return value if isinstance(value, dict) else {}
|
||||
|
||||
|
||||
def _strings(value: Any) -> list[str]:
|
||||
if not isinstance(value, list):
|
||||
return []
|
||||
return [str(item) for item in value if item is not None]
|
||||
|
||||
|
||||
def _first_string(value: Any) -> str:
|
||||
values = _strings(value)
|
||||
return values[0] if values else ""
|
||||
@@ -276,6 +276,31 @@ def _assert_delivery_workbench_shape(data: dict):
|
||||
assert data["summary"]["github_global_freeze_enabled"] is True
|
||||
assert data["summary"]["github_lane_status"] == "stopped_retired_do_not_use"
|
||||
assert data["summary"]["github_lane_excluded_from_p0_blocker_count"] is True
|
||||
assert data["summary"]["gitea_runner_attestation_request_status"] == (
|
||||
"owner_attestation_request_ready_waiting_response"
|
||||
)
|
||||
assert data["summary"]["gitea_runner_attestation_request_ready"] is True
|
||||
assert data["summary"]["gitea_runner_attestation_request_active_blocker_count"] == 1
|
||||
assert data["summary"]["gitea_runner_attestation_contract_id"] == (
|
||||
"ubuntu_latest_gitea_runner_label"
|
||||
)
|
||||
assert data["summary"]["gitea_runner_attestation_runner_label"] == "ubuntu-latest"
|
||||
assert data["summary"]["gitea_runner_attestation_workflow_count"] == 8
|
||||
assert data["summary"]["gitea_runner_attestation_required_owner_field_count"] >= 10
|
||||
assert data["summary"]["gitea_runner_attestation_forbidden_action_count"] >= 8
|
||||
assert data["summary"]["gitea_runner_attestation_owner_response_received_count"] == 0
|
||||
assert data["summary"]["gitea_runner_attestation_owner_response_accepted_count"] == 0
|
||||
assert data["summary"]["gitea_runner_attestation_request_sent"] is False
|
||||
assert data["summary"]["gitea_runner_attestation_request_send_performed"] is False
|
||||
assert (
|
||||
data["summary"]["gitea_runner_attestation_runner_label_change_allowed"]
|
||||
is False
|
||||
)
|
||||
assert (
|
||||
data["summary"]["gitea_runner_attestation_runner_registration_allowed"]
|
||||
is False
|
||||
)
|
||||
assert data["summary"]["gitea_runner_attestation_secret_read_allowed"] is False
|
||||
assert data["summary"]["github_blocked_preflight_target_count"] == 0
|
||||
assert data["summary"]["github_operator_unblock_required"] is False
|
||||
assert data["summary"]["reboot_auto_recovery_status"] == (
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from src.api.v1.agents import router
|
||||
|
||||
|
||||
def test_gitea_workflow_runner_owner_attestation_request_endpoint():
|
||||
app = FastAPI()
|
||||
app.include_router(router, prefix="/api/v1")
|
||||
client = TestClient(app)
|
||||
|
||||
response = client.get(
|
||||
"/api/v1/agents/gitea-workflow-runner-owner-attestation-request"
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert (
|
||||
data["schema_version"]
|
||||
== "gitea_workflow_runner_owner_attestation_request_v1"
|
||||
)
|
||||
assert data["priority"] == "P1-002"
|
||||
assert data["status"] == "owner_attestation_request_ready_waiting_response"
|
||||
assert data["readback"]["contract_id"] == "ubuntu_latest_gitea_runner_label"
|
||||
assert data["readback"]["runner_label"] == "ubuntu-latest"
|
||||
assert data["request_packet"]["request_template_ready"] is True
|
||||
assert data["request_packet"]["request_sent"] is False
|
||||
assert data["request_packet"]["owner_response_received"] is False
|
||||
assert data["request_packet"]["owner_response_accepted"] is False
|
||||
assert (
|
||||
len(data["request_packet"]["workflow_ids_requiring_attestation"])
|
||||
== data["rollups"]["workflow_requiring_attestation_count"]
|
||||
== 8
|
||||
)
|
||||
assert data["rollups"]["required_owner_field_count"] >= 10
|
||||
assert data["rollups"]["owner_response_received_count"] == 0
|
||||
assert data["rollups"]["owner_response_accepted_count"] == 0
|
||||
assert "owner_attestation_response_not_received" in data["active_blockers"]
|
||||
|
||||
boundaries = data["operation_boundaries"]
|
||||
assert boundaries["read_only_api_allowed"] is True
|
||||
assert boundaries["request_send_performed"] is False
|
||||
assert boundaries["workflow_modification_allowed"] is False
|
||||
assert boundaries["workflow_trigger_allowed"] is False
|
||||
assert boundaries["runner_label_change_allowed"] is False
|
||||
assert boundaries["runner_registration_allowed"] is False
|
||||
assert boundaries["runner_restart_allowed"] is False
|
||||
assert boundaries["secret_read_allowed"] is False
|
||||
assert boundaries["runner_token_read_allowed"] is False
|
||||
assert boundaries["gitea_api_write_allowed"] is False
|
||||
assert boundaries["github_api_used"] is False
|
||||
@@ -51,6 +51,19 @@
|
||||
|
||||
**邊界**:未重啟主機,未 restart service,未 workflow_dispatch,未操作 host / Docker / K8s / DB / firewall,未使用 GitHub / `gh` / GitHub API,未讀 secret / token / raw sessions / SQLite / `.env`。
|
||||
|
||||
## 2026-06-30 — 07:38 P1-002 Gitea runner owner attestation request readback
|
||||
|
||||
**照主線 next_focus 推進的實作**:
|
||||
- P0-006 reboot SLO 仍只剩 `host_boot_observation_older_than_target_window`,未重啟主機;因此依 Delivery Workbench 下一個可執行主線推進 Gitea runner owner attestation request。
|
||||
- 新增 `GET /api/v1/agents/gitea-workflow-runner-owner-attestation-request`,把 `ubuntu_latest_gitea_runner_label`、8 個需 owner attestation 的 workflow、11 個 required owner fields、9 個 forbidden actions 與 response acceptance / rejection rules 轉成機器可讀 request packet。
|
||||
- Delivery Workbench 的 `gitea` lane 與 summary 現在顯示 request ready、workflow count、required field count、response received / accepted count 與 runner mutation/secret/Gitea write 邊界。
|
||||
|
||||
**驗證**:
|
||||
- Focused pytest:Gitea runner attestation request / workflow runner health / Delivery Workbench / CD profile `29 passed`。
|
||||
- `py_compile`、Gitea runner pressure guard、`git diff --check` 通過。
|
||||
|
||||
**邊界**:未送出 request,未呼叫 Gitea API,未修改 workflow,未 workflow_dispatch,未註冊 / 重啟 runner,未改 runner label,未操作 host / Docker / K8s / DB / firewall,未讀 secret / token / raw sessions / SQLite / `.env`,未使用 GitHub / `gh` / GitHub API。
|
||||
|
||||
## 2026-06-30 — 00:41 P0-004 template copy receipt runtime-image readback 修正
|
||||
|
||||
**照優先順序完成的實作**:
|
||||
|
||||
@@ -228,7 +228,9 @@ def test_gitea_private_inventory_scorecard_stays_on_controlled_runtime_profile()
|
||||
"apps/api/src/services/gitea_owner_coverage_attestation_validation.py)",
|
||||
"apps/api/src/services/gitea_private_inventory_closeout_validation.py)",
|
||||
"apps/api/src/services/gitea_private_inventory_p0_scorecard.py)",
|
||||
"apps/api/src/services/gitea_workflow_runner_owner_attestation_request.py)",
|
||||
"apps/api/tests/test_gitea_private_inventory_p0_scorecard_api.py)",
|
||||
"apps/api/tests/test_gitea_workflow_runner_owner_attestation_request_api.py)",
|
||||
"docs/operations/awoooi-gitea-authenticated-inventory-payload-validation.snapshot.json)",
|
||||
"docs/security/GITEA-REPO-INVENTORY-SNAPSHOT.md)",
|
||||
"docs/security/gitea-repo-inventory.snapshot.json)",
|
||||
@@ -240,7 +242,9 @@ def test_gitea_private_inventory_scorecard_stays_on_controlled_runtime_profile()
|
||||
"src/services/gitea_owner_coverage_attestation_validation.py",
|
||||
"src/services/gitea_private_inventory_closeout_validation.py",
|
||||
"src/services/gitea_private_inventory_p0_scorecard.py",
|
||||
"src/services/gitea_workflow_runner_owner_attestation_request.py",
|
||||
"tests/test_gitea_private_inventory_p0_scorecard_api.py",
|
||||
"tests/test_gitea_workflow_runner_owner_attestation_request_api.py",
|
||||
"scripts/security/tests/test_gitea_authenticated_inventory_payload_validator.py)",
|
||||
"../../scripts/security/gitea-private-inventory-p0-scorecard.py",
|
||||
"../../scripts/security/gitea-authenticated-inventory-payload-validator.py",
|
||||
|
||||
Reference in New Issue
Block a user