feat(github): authorize controlled backup execution

This commit is contained in:
Your Name
2026-06-28 01:37:02 +08:00
parent d4fcce4170
commit 4de66bde2e
7 changed files with 809 additions and 92 deletions

View File

@@ -19,10 +19,11 @@ def test_delivery_closure_workbench_endpoint_returns_product_summary():
assert data["summary"]["source_count"] == 5
assert data["summary"]["loaded_source_count"] == 5
assert data["summary"]["runtime_execution_authorized"] is False
assert data["summary"]["remote_write_authorized"] is False
assert data["summary"]["repo_creation_authorized"] is False
assert data["summary"]["refs_sync_authorized"] is False
assert data["summary"]["workflow_trigger_authorized"] is False
assert data["summary"]["remote_write_authorized"] is True
assert data["summary"]["repo_creation_authorized"] is True
assert data["summary"]["visibility_change_authorized"] is True
assert data["summary"]["refs_sync_authorized"] is True
assert data["summary"]["workflow_trigger_authorized"] is True
assert data["summary"]["secret_values_collected"] is False
assert data["summary"]["average_completion_percent"] >= 0
assert data["summary"]["high_risk_blocker_count"] > 0
@@ -36,10 +37,16 @@ def test_delivery_closure_workbench_endpoint_returns_product_summary():
assert lanes["runtime"]["metric"]["kind"] == "surface_count"
assert lanes["backup"]["metric"]["kind"] == "readiness_row_count"
assert sources["github_private_backup"]["loaded"] is True
assert sources["github_private_backup"]["schema_version"] == "github_target_private_backup_evidence_gate_v1"
assert (
sources["github_private_backup"]["schema_version"]
== "github_target_private_backup_evidence_gate_v1"
)
assert sources["github_private_backup"]["missing_reason"] == ""
assert lanes["github"]["blocker_count"] == 9
assert lanes["github"]["status"] == "blocked_private_visibility_and_safe_credential_evidence_required"
assert lanes["github"]["blocker_count"] == 0
assert (
lanes["github"]["status"]
== "owner_authorized_controlled_execution_preflight_ready"
)
assert lanes["github"]["metric"]["verified"] == 4
assert lanes["github"]["metric"]["total"] == 9
assert all(0 <= lane["completion_percent"] <= 100 for lane in lanes.values())
@@ -48,11 +55,11 @@ def test_delivery_closure_workbench_endpoint_returns_product_summary():
boundaries = data["operation_boundaries"]
assert boundaries["read_only_api_allowed"] is True
assert boundaries["runtime_write_allowed"] is False
assert boundaries["remote_write_allowed"] is False
assert boundaries["repo_creation_allowed"] is False
assert boundaries["visibility_change_allowed"] is False
assert boundaries["refs_sync_allowed"] is False
assert boundaries["workflow_trigger_allowed"] is False
assert boundaries["remote_write_allowed"] is True
assert boundaries["repo_creation_allowed"] is True
assert boundaries["visibility_change_allowed"] is True
assert boundaries["refs_sync_allowed"] is True
assert boundaries["workflow_trigger_allowed"] is True
assert boundaries["secret_value_collection_allowed"] is False
assert boundaries["backup_restore_execution_allowed"] is False
assert boundaries["active_scan_allowed"] is False

View File

@@ -18,11 +18,10 @@ def test_load_github_target_private_backup_evidence_gate_from_committed_snapshot
snapshot = load_latest_github_target_private_backup_evidence_gate()
assert snapshot["schema_version"] == "github_target_private_backup_evidence_gate_v1"
assert snapshot["mode"] == "read_only_private_backup_evidence_gate"
assert (
snapshot["status"]
== "blocked_private_visibility_and_safe_credential_evidence_required"
snapshot["mode"] == "owner_authorized_controlled_execution_no_secret_plaintext"
)
assert snapshot["status"] == "owner_authorized_controlled_execution_preflight_ready"
assert snapshot["summary"]["target_decision_count"] == 10
assert snapshot["summary"]["approval_required_target_count"] == 9
assert snapshot["summary"]["github_connector_owner_visible_repository_count"] == 4
@@ -55,6 +54,13 @@ def test_load_github_target_private_backup_evidence_gate_from_committed_snapshot
== 0
)
assert snapshot["summary"]["github_missing_target_refs_sync_ready_count"] == 0
assert (
snapshot["summary"][
"github_missing_target_create_private_repo_authorized_count"
]
== 5
)
assert snapshot["summary"]["github_missing_target_refs_sync_authorized_count"] == 5
assert snapshot["summary"]["private_backup_verified_count"] == 4
assert snapshot["summary"]["private_visibility_verified_count"] == 4
assert snapshot["summary"]["safe_credential_required_count"] == 9
@@ -90,17 +96,48 @@ def test_load_github_target_private_backup_evidence_gate_from_committed_snapshot
assert (
snapshot["summary"]["github_target_owner_response_handoff_not_approval"] is True
)
assert snapshot["summary"]["blocked_target_count"] == 9
assert snapshot["summary"]["owner_execution_authorization_received_count"] == 1
assert snapshot["summary"]["owner_execution_authorized_target_count"] == 9
assert (
snapshot["summary"]["owner_execution_authorization_status"]
== "owner_authorized_controlled_execution"
)
assert (
snapshot["summary"]["owner_execution_authorization_source"]
== "chat_authorization_2026-06-28_full_hard_gate_open"
)
assert (
snapshot["summary"]["owner_execution_controlled_preflight_required_count"] == 9
)
assert snapshot["summary"]["post_execution_readback_required_count"] == 9
assert snapshot["summary"]["execution_ready_count"] == 9
assert snapshot["summary"]["blocked_target_count"] == 0
assert snapshot["summary"]["public_repo_allowed"] is False
assert snapshot["summary"]["repo_creation_authorized"] is False
assert snapshot["summary"]["visibility_change_authorized"] is False
assert snapshot["summary"]["refs_sync_authorized"] is False
assert snapshot["summary"]["repo_creation_authorized"] is True
assert snapshot["summary"]["visibility_change_authorized"] is True
assert snapshot["summary"]["refs_sync_authorized"] is True
assert snapshot["summary"]["workflow_trigger_authorized"] is True
assert snapshot["summary"]["github_primary_switch_authorized"] is False
assert snapshot["summary"]["secret_value_collection_allowed"] is False
assert snapshot["operation_boundaries"]["read_only_api_allowed"] is True
assert snapshot["operation_boundaries"]["repo_creation_allowed"] is False
assert snapshot["operation_boundaries"]["visibility_change_allowed"] is False
assert snapshot["operation_boundaries"]["refs_sync_allowed"] is False
assert snapshot["operation_boundaries"]["github_api_write_allowed"] is True
assert snapshot["operation_boundaries"]["repo_creation_allowed"] is True
assert snapshot["operation_boundaries"]["visibility_change_allowed"] is True
assert snapshot["operation_boundaries"]["refs_sync_allowed"] is True
assert snapshot["operation_boundaries"]["workflow_trigger_allowed"] is True
assert snapshot["operation_boundaries"]["secret_value_collection_allowed"] is False
assert (
snapshot["operation_boundaries"]["private_clone_url_collection_allowed"]
is False
)
assert snapshot["authorization_flags"]["repo_creation_authorized"] is True
assert snapshot["authorization_flags"]["visibility_change_authorized"] is True
assert snapshot["authorization_flags"]["refs_sync_authorized"] is True
assert snapshot["authorization_flags"]["workflow_trigger_authorized"] is True
assert snapshot["authorization_flags"]["github_primary_switch_authorized"] is False
assert (
snapshot["authorization_flags"]["private_clone_url_collection_allowed"] is False
)
intake = snapshot["owner_response_intake_readiness"]
assert (
intake["status"]
@@ -189,7 +226,7 @@ def test_load_github_target_private_backup_evidence_gate_from_committed_snapshot
)
assert (
targets["owenhytsai/awoooi"]["safe_credential_evidence_submission_status"]
== "waiting_redacted_evidence_ref"
== "owner_execution_authorized_post_apply_readback_pending"
)
assert (
"redacted_metadata_pointer"
@@ -210,6 +247,10 @@ def test_load_github_target_private_backup_evidence_gate_from_committed_snapshot
is False
)
assert targets["owenhytsai/awoooi"]["owner_response_execution_authorized"] is False
assert targets["owenhytsai/awoooi"]["owner_execution_authorized"] is True
assert targets["owenhytsai/awoooi"]["controlled_execution_ready"] is True
assert targets["owenhytsai/awoooi"]["refs_sync_ready"] is True
assert targets["owenhytsai/awoooi"]["blockers"] == []
assert (
"canonical_source"
in targets["owenhytsai/awoooi"]["owner_response_required_fields"]
@@ -226,6 +267,9 @@ def test_load_github_target_private_backup_evidence_gate_from_committed_snapshot
is False
)
assert targets["owenhytsai/ewoooc"]["missing_target_refs_sync_ready"] is False
assert targets["owenhytsai/ewoooc"]["repo_creation_authorized"] is True
assert targets["owenhytsai/ewoooc"]["refs_sync_authorized"] is True
assert targets["owenhytsai/ewoooc"]["execution_ready"] is True
assert targets["owenhytsai/ewoooc"]["private_backup_verified"] is False
assert (
targets["owenhytsai/ewoooc"]["owner_response_template_id"]
@@ -352,6 +396,21 @@ def test_github_target_private_backup_gate_rejects_missing_source_write_flags(tm
load_latest_github_target_private_backup_evidence_gate(tmp_path)
def test_github_target_private_backup_gate_rejects_execution_authorization_secrets(
tmp_path,
):
_copy_security_snapshots(tmp_path)
authorization_path = (
tmp_path / "github-target-owner-execution-authorization.snapshot.json"
)
authorization = json.loads(authorization_path.read_text(encoding="utf-8"))
authorization["summary"]["secret_value_collection_allowed"] = True
authorization_path.write_text(json.dumps(authorization), encoding="utf-8")
with pytest.raises(ValueError, match="forbidden authorization flags"):
load_latest_github_target_private_backup_evidence_gate(tmp_path)
def test_github_target_owner_response_preflight_accepts_redacted_evidence_refs():
preflight = preflight_github_target_owner_response_submission(
_valid_owner_response_submission()
@@ -439,8 +498,8 @@ def test_github_target_safe_credential_evidence_review_accepts_redacted_refs():
assert payload["summary"]["safe_credential_evidence_submission_accepted_count"] == 1
assert payload["summary"]["safe_credential_accepted_evidence_count"] == 0
assert payload["summary"]["private_backup_verified_count"] == 4
assert payload["summary"]["execution_ready_count"] == 0
assert payload["summary"]["blocked_target_count"] == 9
assert payload["summary"]["execution_ready_count"] == 9
assert payload["summary"]["blocked_target_count"] == 0
assert payload["boundaries"]["payload_persisted"] is False
assert payload["boundaries"]["safe_credential_accepted_updated"] is False
assert payload["boundaries"]["runtime_execution_authorized"] is False
@@ -510,6 +569,7 @@ def _copy_security_snapshots(tmp_path: Path) -> None:
"github-target-probe.snapshot.json",
"github-target-connector-readback.snapshot.json",
"github-target-missing-source-readiness.snapshot.json",
"github-target-owner-execution-authorization.snapshot.json",
):
shutil.copy(source_dir / filename, tmp_path / filename)

View File

@@ -16,7 +16,8 @@ def test_github_target_private_backup_evidence_gate_endpoint_returns_read_only_g
assert response.status_code == 200
data = response.json()
assert data["schema_version"] == "github_target_private_backup_evidence_gate_v1"
assert data["mode"] == "read_only_private_backup_evidence_gate"
assert data["mode"] == "owner_authorized_controlled_execution_no_secret_plaintext"
assert data["status"] == "owner_authorized_controlled_execution_preflight_ready"
assert data["summary"]["approval_required_target_count"] == 9
assert data["summary"]["github_connector_readback_count"] == 9
assert data["summary"]["github_connector_private_visibility_count"] == 4
@@ -25,6 +26,11 @@ def test_github_target_private_backup_evidence_gate_endpoint_returns_read_only_g
assert data["summary"]["github_missing_target_gitea_source_candidate_count"] == 3
assert data["summary"]["github_missing_target_create_private_repo_ready_count"] == 0
assert data["summary"]["github_missing_target_refs_sync_ready_count"] == 0
assert (
data["summary"]["github_missing_target_create_private_repo_authorized_count"]
== 5
)
assert data["summary"]["github_missing_target_refs_sync_authorized_count"] == 5
assert data["summary"]["private_backup_verified_count"] == 4
assert data["summary"]["private_visibility_verified_count"] == 4
assert data["summary"]["safe_credential_evidence_intake_ready"] is True
@@ -46,18 +52,22 @@ def test_github_target_private_backup_evidence_gate_endpoint_returns_read_only_g
assert data["summary"]["owner_response_collection_check_count"] == 6
assert data["summary"]["owner_response_intake_preflight_check_count"] == 6
assert data["summary"]["owner_response_request_execution_authorized"] is False
assert data["summary"]["blocked_target_count"] == 9
assert data["summary"]["owner_execution_authorization_received_count"] == 1
assert data["summary"]["owner_execution_authorized_target_count"] == 9
assert data["summary"]["execution_ready_count"] == 9
assert data["summary"]["blocked_target_count"] == 0
assert data["summary"]["public_repo_allowed"] is False
assert data["summary"]["repo_creation_authorized"] is False
assert data["summary"]["visibility_change_authorized"] is False
assert data["summary"]["refs_sync_authorized"] is False
assert data["summary"]["repo_creation_authorized"] is True
assert data["summary"]["visibility_change_authorized"] is True
assert data["summary"]["refs_sync_authorized"] is True
assert data["summary"]["workflow_trigger_authorized"] is True
assert data["summary"]["secret_value_collection_allowed"] is False
assert data["operation_boundaries"]["read_only_api_allowed"] is True
assert data["operation_boundaries"]["github_api_write_allowed"] is False
assert data["operation_boundaries"]["repo_creation_allowed"] is False
assert data["operation_boundaries"]["visibility_change_allowed"] is False
assert data["operation_boundaries"]["refs_sync_allowed"] is False
assert data["operation_boundaries"]["workflow_trigger_allowed"] is False
assert data["operation_boundaries"]["github_api_write_allowed"] is True
assert data["operation_boundaries"]["repo_creation_allowed"] is True
assert data["operation_boundaries"]["visibility_change_allowed"] is True
assert data["operation_boundaries"]["refs_sync_allowed"] is True
assert data["operation_boundaries"]["workflow_trigger_allowed"] is True
assert data["operation_boundaries"]["private_clone_url_collection_allowed"] is False
intake = data["owner_response_intake_readiness"]
assert (
@@ -92,9 +102,11 @@ def test_github_target_private_backup_evidence_gate_endpoint_returns_read_only_g
== "/api/v1/agents/github-target-safe-credential-evidence-reviewer-validation/validate-redacted-refs"
)
assert data["targets"][0]["owner_response_execution_authorized"] is False
assert data["targets"][0]["owner_execution_authorized"] is True
assert data["targets"][0]["controlled_execution_ready"] is True
assert (
data["targets"][0]["safe_credential_evidence_submission_status"]
== "waiting_redacted_evidence_ref"
== "owner_execution_authorized_post_apply_readback_pending"
)
assert data["targets"][0]["safe_credential_raw_payload_storage_allowed"] is False
assert (
@@ -211,5 +223,5 @@ def test_github_target_safe_credential_evidence_review_api_does_not_persist():
== 0
)
assert readback["summary"]["github_missing_target_refs_sync_ready_count"] == 0
assert readback["summary"]["execution_ready_count"] == 0
assert readback["summary"]["execution_ready_count"] == 9
assert "192.168.0." not in response.text