Merge remote-tracking branch 'gitea/main' into codex/github-safe-credential-intake-20260627

This commit is contained in:
Your Name
2026-06-27 21:49:34 +08:00
15 changed files with 1095 additions and 43 deletions

View File

@@ -8,6 +8,7 @@ import pytest
from src.services.github_target_private_backup_evidence_gate import (
load_latest_github_target_private_backup_evidence_gate,
preflight_github_target_owner_response_submission,
)
from src.services.snapshot_paths import default_security_dir
@@ -321,6 +322,62 @@ 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_owner_response_preflight_accepts_redacted_evidence_refs():
preflight = preflight_github_target_owner_response_submission(
_valid_owner_response_submission()
)
assert (
preflight["schema_version"]
== "github_target_owner_response_intake_preflight_v1"
)
assert preflight["status"] == "ready_for_read_only_owner_response_intake"
assert preflight["mode"] == "validate_owner_response_only_no_persist_no_github_write"
assert preflight["summary"]["candidate_response_item_count"] == 1
assert preflight["summary"]["preflight_passed_response_item_count"] == 1
assert preflight["summary"]["preflight_blocked_response_item_count"] == 0
assert preflight["summary"]["owner_response_received_count"] == 0
assert preflight["summary"]["owner_response_accepted_count"] == 0
assert preflight["summary"]["safe_credential_accepted_evidence_count"] == 0
assert preflight["summary"]["github_api_write_allowed"] is False
assert preflight["summary"]["repo_creation_authorized"] is False
assert preflight["summary"]["refs_sync_authorized"] is False
assert preflight["operation_boundaries"]["persist_submission_allowed"] is False
assert preflight["operation_boundaries"]["github_api_write_allowed"] is False
assert preflight["operation_boundaries"]["private_clone_url_collection_allowed"] is False
assert preflight["authorization_flags"]["owner_response_execution_authorized"] is False
assert preflight["responses"][0]["accepted_for_read_only_intake"] is True
assert preflight["responses"][0]["owner_response_received"] is False
assert preflight["responses"][0]["owner_response_accepted"] is False
def test_github_target_owner_response_preflight_blocks_credentials_and_commands():
submission = _valid_owner_response_submission()
submission["responses"][0]["private_clone_url_credential"] = (
"https://owner:ghp_1234567890abcdefghijklmnopqrstu@github.com/owenhytsai/awoooi.git"
)
submission["responses"][0]["repo_creation_command"] = (
"gh repo create owenhytsai/awoooi --private"
)
preflight = preflight_github_target_owner_response_submission(submission)
assert preflight["status"] == "blocked_owner_response_intake_preflight"
assert preflight["summary"]["candidate_response_item_count"] == 1
assert preflight["summary"]["preflight_passed_response_item_count"] == 0
assert preflight["summary"]["preflight_blocked_response_item_count"] == 1
assert preflight["summary"]["forbidden_payload_hit_count"] >= 3
assert preflight["summary"]["owner_response_received_count"] == 0
assert preflight["summary"]["owner_response_accepted_count"] == 0
assert preflight["summary"]["github_api_write_allowed"] is False
response = preflight["responses"][0]
assert response["accepted_for_read_only_intake"] is False
assert "forbidden_payload_detected" in response["blockers"]
assert "unsupported_response_fields" in response["blockers"]
assert response["execution_authorized"] is False
assert response["repo_creation_authorized"] is False
def _copy_security_snapshots(tmp_path: Path) -> None:
source_dir = default_security_dir(Path(__file__))
for filename in (
@@ -332,3 +389,34 @@ def _copy_security_snapshots(tmp_path: Path) -> None:
"github-target-missing-source-readiness.snapshot.json",
):
shutil.copy(source_dir / filename, tmp_path / filename)
def _valid_owner_response_submission() -> dict[str, object]:
return {
"submission_mode": "read_only_markdown_response",
"responses": [
{
"template_id": "target-awoooi-refs-blocked",
"github_repo": "owenhytsai/awoooi",
"owner_role_or_team": "platform-owner",
"decision": "hold_pending_refs_truth",
"decision_reason": "Need refs truth review before any sync action.",
"affected_scope": "awoooi github backup target",
"redacted_evidence_refs": [
"docs/security/GITEA-GITHUB-MIGRATION-SNAPSHOT.md",
"docs/security/source-control-ref-detail-diff.snapshot.json",
],
"evidence_refs": [
"docs/security/source-control-workflow-secret-name-inventory.snapshot.json"
],
"followup_owner": "platform-owner",
"rollback_owner": "platform-owner",
"maintenance_window": "not_authorized",
"validation_plan": "read-only refs truth review only",
"canonical_source": "gitea_main",
"github_target_disposition": "existing_private_candidate",
"visibility_review_owner": "platform-owner",
"refs_truth_review_owner": "platform-owner",
}
],
}

View File

@@ -92,3 +92,60 @@ def test_github_target_private_backup_evidence_gate_endpoint_returns_read_only_g
is False
)
assert "192.168.0." not in response.text
def test_github_target_owner_response_intake_preflight_endpoint_blocks_secrets():
app = FastAPI()
app.include_router(router, prefix="/api/v1")
client = TestClient(app)
response = client.post(
"/api/v1/agents/github-target-owner-response-intake-preflight",
json={
"submission_mode": "read_only_markdown_response",
"responses": [
{
"template_id": "target-awoooi-refs-blocked",
"github_repo": "owenhytsai/awoooi",
"owner_role_or_team": "platform-owner",
"decision": "hold_pending_refs_truth",
"decision_reason": "Need refs truth review before sync.",
"affected_scope": "awoooi github backup target",
"redacted_evidence_refs": [
"docs/security/GITEA-GITHUB-MIGRATION-SNAPSHOT.md"
],
"evidence_refs": [
"docs/security/source-control-ref-detail-diff.snapshot.json"
],
"followup_owner": "platform-owner",
"rollback_owner": "platform-owner",
"maintenance_window": "not_authorized",
"validation_plan": "read-only refs truth review only",
"canonical_source": "gitea_main",
"github_target_disposition": "existing_private_candidate",
"visibility_review_owner": "platform-owner",
"refs_truth_review_owner": "platform-owner",
"private_clone_url_credential": (
"https://owner:ghp_1234567890abcdefghijklmnopqrstu@github.com/owenhytsai/awoooi.git"
),
}
],
},
)
assert response.status_code == 200
data = response.json()
assert data["schema_version"] == "github_target_owner_response_intake_preflight_v1"
assert data["status"] == "blocked_owner_response_intake_preflight"
assert data["summary"]["preflight_passed_response_item_count"] == 0
assert data["summary"]["preflight_blocked_response_item_count"] == 1
assert data["summary"]["owner_response_received_count"] == 0
assert data["summary"]["owner_response_accepted_count"] == 0
assert data["summary"]["safe_credential_accepted_evidence_count"] == 0
assert data["operation_boundaries"]["persist_submission_allowed"] is False
assert data["operation_boundaries"]["github_api_write_allowed"] is False
assert data["operation_boundaries"]["private_clone_url_collection_allowed"] is False
assert data["authorization_flags"]["owner_response_execution_authorized"] is False
assert data["responses"][0]["accepted_for_read_only_intake"] is False
assert "forbidden_payload_detected" in data["responses"][0]["blockers"]
assert "192.168.0." not in response.text