590 lines
19 KiB
JSON
590 lines
19 KiB
JSON
{
|
||
"config_preflight_rows": [
|
||
{
|
||
"acme_route_count": 2,
|
||
"admin_route_count": 2,
|
||
"config_id": "host188_all_sites",
|
||
"control_tier": "C0",
|
||
"host": "192.168.0.188",
|
||
"live_conf_evidence_received": false,
|
||
"live_path": "/etc/nginx/sites-enabled/all-sites.conf",
|
||
"maintenance_window_accepted": false,
|
||
"nginx_test_evidence_received": false,
|
||
"owner_gate": "public_gateway_owner_response_required",
|
||
"owner_response_accepted": false,
|
||
"owner_response_received": false,
|
||
"rendered_diff_ready": false,
|
||
"repo_source_hash_ready": true,
|
||
"repo_source_path": "infra/ansible/roles/nginx/templates/188-all-sites.conf.j2",
|
||
"role": "public_gateway_all_sites",
|
||
"rollback_owner_accepted": false,
|
||
"route_smoke_evidence_received": false,
|
||
"runtime_gate_open": false,
|
||
"server_block_count": 15,
|
||
"server_name_count": 9,
|
||
"tls_certificate_path_count": 7,
|
||
"upstream_count": 10,
|
||
"websocket_route_count": 5
|
||
},
|
||
{
|
||
"acme_route_count": 1,
|
||
"admin_route_count": 0,
|
||
"config_id": "host188_internal_tools_https",
|
||
"control_tier": "C0",
|
||
"host": "192.168.0.188",
|
||
"live_conf_evidence_received": false,
|
||
"live_path": "owner_confirmation_required",
|
||
"maintenance_window_accepted": false,
|
||
"nginx_test_evidence_received": false,
|
||
"owner_gate": "public_tools_owner_response_required",
|
||
"owner_response_accepted": false,
|
||
"owner_response_received": false,
|
||
"rendered_diff_ready": false,
|
||
"repo_source_hash_ready": true,
|
||
"repo_source_path": "infra/ansible/roles/nginx/templates/188-internal-tools-https.conf.j2",
|
||
"role": "public_internal_tools_https",
|
||
"rollback_owner_accepted": false,
|
||
"route_smoke_evidence_received": false,
|
||
"runtime_gate_open": false,
|
||
"server_block_count": 8,
|
||
"server_name_count": 7,
|
||
"tls_certificate_path_count": 4,
|
||
"upstream_count": 6,
|
||
"websocket_route_count": 2
|
||
},
|
||
{
|
||
"acme_route_count": 0,
|
||
"admin_route_count": 0,
|
||
"config_id": "host110_ollama_proxy",
|
||
"control_tier": "C1",
|
||
"host": "192.168.0.110",
|
||
"live_conf_evidence_received": false,
|
||
"live_path": "/etc/nginx/sites-enabled/110-ollama-proxy.conf",
|
||
"maintenance_window_accepted": false,
|
||
"nginx_test_evidence_received": false,
|
||
"owner_gate": "ai_provider_proxy_owner_response_required",
|
||
"owner_response_accepted": false,
|
||
"owner_response_received": false,
|
||
"rendered_diff_ready": false,
|
||
"repo_source_hash_ready": true,
|
||
"repo_source_path": "infra/ansible/roles/nginx/templates/110-ollama-proxy.conf.j2",
|
||
"role": "ollama_proxy_gateway",
|
||
"rollback_owner_accepted": false,
|
||
"route_smoke_evidence_received": false,
|
||
"runtime_gate_open": false,
|
||
"server_block_count": 3,
|
||
"server_name_count": 0,
|
||
"tls_certificate_path_count": 0,
|
||
"upstream_count": 3,
|
||
"websocket_route_count": 0
|
||
}
|
||
],
|
||
"execution_boundaries": {
|
||
"acme_challenge_change_authorized": false,
|
||
"action_buttons_allowed": false,
|
||
"admin_route_change_authorized": false,
|
||
"certbot_renew_authorized": false,
|
||
"certbot_renew_executed": false,
|
||
"dns_query_executed": false,
|
||
"host_live_conf_read_authorized": false,
|
||
"host_write_authorized": false,
|
||
"live_tls_probe_executed": false,
|
||
"nginx_reload_authorized": false,
|
||
"nginx_reload_executed": false,
|
||
"nginx_test_authorized": false,
|
||
"nginx_test_executed": false,
|
||
"public_gateway_reload_authorized": false,
|
||
"public_route_change_authorized": false,
|
||
"rollback_executed": false,
|
||
"route_smoke_authorized": false,
|
||
"route_smoke_executed": false,
|
||
"runtime_execution_authorized": false,
|
||
"secret_value_collection_allowed": false,
|
||
"ssh_read_authorized": false,
|
||
"ssh_write_authorized": false,
|
||
"websocket_route_change_authorized": false
|
||
},
|
||
"generated_at": "2026-06-12T10:30:00+08:00",
|
||
"git_commit": "e4747722",
|
||
"next_collection_order": [
|
||
"public_gateway_owner_response",
|
||
"owner_provided_live_conf_export",
|
||
"source_to_live_rendered_diff",
|
||
"nginx_t_evidence",
|
||
"affected_public_route_smoke",
|
||
"admin_route_smoke_if_affected",
|
||
"websocket_or_api_smoke_if_affected",
|
||
"tls_certificate_owner_confirmation",
|
||
"maintenance_window",
|
||
"rollback_owner_and_ref"
|
||
],
|
||
"operator_interpretation": [
|
||
"這是 Nginx public gateway 變更前置控管清冊,不是 reload 授權。",
|
||
"repo-only ready 只代表 source hash 與 affected route list 已能重跑產生。",
|
||
"owner response、live conf、rendered diff、nginx -t、route smoke、maintenance window 與 rollback owner 全部仍為 0。",
|
||
"若未來發現 live drift,只能建立 evidence 與 owner decision,不得自動覆寫 live。"
|
||
],
|
||
"required_owner_fields": [
|
||
"owner_role_or_team",
|
||
"decision",
|
||
"decision_reason",
|
||
"affected_scope",
|
||
"redacted_evidence_refs",
|
||
"followup_owner",
|
||
"rollback_owner",
|
||
"maintenance_window",
|
||
"validation_plan",
|
||
"nginx_test_evidence_ref",
|
||
"route_smoke_evidence_ref"
|
||
],
|
||
"required_preflight_gates": [
|
||
{
|
||
"gate_id": "PG1",
|
||
"label": "source-of-truth hash",
|
||
"owner_acceptance_required": false,
|
||
"repo_only_ready": true,
|
||
"required_evidence": "repo_source_raw_and_normalized_sha256"
|
||
},
|
||
{
|
||
"gate_id": "PG2",
|
||
"label": "affected route list",
|
||
"owner_acceptance_required": false,
|
||
"repo_only_ready": true,
|
||
"required_evidence": "domain_route_upstream_tls_admin_websocket_acme_inventory"
|
||
},
|
||
{
|
||
"gate_id": "PG3",
|
||
"label": "owner response",
|
||
"owner_acceptance_required": true,
|
||
"repo_only_ready": false,
|
||
"required_evidence": "owner role/team, decision, reason, affected scope, redacted refs, followup owner"
|
||
},
|
||
{
|
||
"gate_id": "PG4",
|
||
"label": "owner-provided live config",
|
||
"owner_acceptance_required": true,
|
||
"repo_only_ready": false,
|
||
"required_evidence": "redacted live conf export or owner statement"
|
||
},
|
||
{
|
||
"gate_id": "PG5",
|
||
"label": "rendered diff",
|
||
"owner_acceptance_required": true,
|
||
"repo_only_ready": false,
|
||
"required_evidence": "source-to-live rendered diff with redaction"
|
||
},
|
||
{
|
||
"gate_id": "PG6",
|
||
"label": "nginx -t evidence",
|
||
"owner_acceptance_required": true,
|
||
"repo_only_ready": false,
|
||
"required_evidence": "syntax test output captured by approved maintainer"
|
||
},
|
||
{
|
||
"gate_id": "PG7",
|
||
"label": "public route smoke",
|
||
"owner_acceptance_required": true,
|
||
"repo_only_ready": false,
|
||
"required_evidence": "public route smoke plan and result for affected domains"
|
||
},
|
||
{
|
||
"gate_id": "PG8",
|
||
"label": "admin route smoke",
|
||
"owner_acceptance_required": true,
|
||
"repo_only_ready": false,
|
||
"required_evidence": "admin/auth route smoke when admin path is affected"
|
||
},
|
||
{
|
||
"gate_id": "PG9",
|
||
"label": "WebSocket / API smoke",
|
||
"owner_acceptance_required": true,
|
||
"repo_only_ready": false,
|
||
"required_evidence": "WebSocket or API smoke when upstream or upgrade header is affected"
|
||
},
|
||
{
|
||
"gate_id": "PG10",
|
||
"label": "ACME / TLS owner check",
|
||
"owner_acceptance_required": true,
|
||
"repo_only_ready": false,
|
||
"required_evidence": "certificate path, SAN/wildcard/shared-cert statement, ACME impact"
|
||
},
|
||
{
|
||
"gate_id": "PG11",
|
||
"label": "maintenance window",
|
||
"owner_acceptance_required": true,
|
||
"repo_only_ready": false,
|
||
"required_evidence": "approved window and notification scope"
|
||
},
|
||
{
|
||
"gate_id": "PG12",
|
||
"label": "rollback owner and ref",
|
||
"owner_acceptance_required": true,
|
||
"repo_only_ready": false,
|
||
"required_evidence": "rollback owner, rollback file/ref, post-rollback smoke"
|
||
}
|
||
],
|
||
"route_impacts": [
|
||
{
|
||
"acme_challenge_present": false,
|
||
"admin_route_count": 0,
|
||
"admin_route_smoke_required": false,
|
||
"certificate_owner_confirmation_required": false,
|
||
"config_ids": [
|
||
"host188_all_sites"
|
||
],
|
||
"control_tier": "C0",
|
||
"domain": "aiops.wooo.work",
|
||
"has_tls_certificate_path": true,
|
||
"hosts": [
|
||
"192.168.0.188"
|
||
],
|
||
"owner_response_accepted": false,
|
||
"public_route_smoke_required": true,
|
||
"route_smoke_accepted": false,
|
||
"tls_owner_check_required": false,
|
||
"upstream_count": 3,
|
||
"websocket_or_api_smoke_required": true,
|
||
"websocket_route_count": 1
|
||
},
|
||
{
|
||
"acme_challenge_present": false,
|
||
"admin_route_count": 0,
|
||
"admin_route_smoke_required": false,
|
||
"certificate_owner_confirmation_required": false,
|
||
"config_ids": [
|
||
"host188_all_sites"
|
||
],
|
||
"control_tier": "C0",
|
||
"domain": "bitan.wooo.work",
|
||
"has_tls_certificate_path": true,
|
||
"hosts": [
|
||
"192.168.0.188"
|
||
],
|
||
"owner_response_accepted": false,
|
||
"public_route_smoke_required": true,
|
||
"route_smoke_accepted": false,
|
||
"tls_owner_check_required": false,
|
||
"upstream_count": 1,
|
||
"websocket_or_api_smoke_required": true,
|
||
"websocket_route_count": 1
|
||
},
|
||
{
|
||
"acme_challenge_present": true,
|
||
"admin_route_count": 0,
|
||
"admin_route_smoke_required": false,
|
||
"certificate_owner_confirmation_required": true,
|
||
"config_ids": [
|
||
"host188_internal_tools_https"
|
||
],
|
||
"control_tier": "C0",
|
||
"domain": "gitea.wooo.work",
|
||
"has_tls_certificate_path": true,
|
||
"hosts": [
|
||
"192.168.0.188"
|
||
],
|
||
"owner_response_accepted": false,
|
||
"public_route_smoke_required": true,
|
||
"route_smoke_accepted": false,
|
||
"tls_owner_check_required": true,
|
||
"upstream_count": 1,
|
||
"websocket_or_api_smoke_required": true,
|
||
"websocket_route_count": 1
|
||
},
|
||
{
|
||
"acme_challenge_present": false,
|
||
"admin_route_count": 0,
|
||
"admin_route_smoke_required": false,
|
||
"certificate_owner_confirmation_required": false,
|
||
"config_ids": [
|
||
"host188_all_sites"
|
||
],
|
||
"control_tier": "C0",
|
||
"domain": "gitlab.wooo.work",
|
||
"has_tls_certificate_path": true,
|
||
"hosts": [
|
||
"192.168.0.188"
|
||
],
|
||
"owner_response_accepted": false,
|
||
"public_route_smoke_required": true,
|
||
"route_smoke_accepted": false,
|
||
"tls_owner_check_required": false,
|
||
"upstream_count": 1,
|
||
"websocket_or_api_smoke_required": true,
|
||
"websocket_route_count": 0
|
||
},
|
||
{
|
||
"acme_challenge_present": true,
|
||
"admin_route_count": 0,
|
||
"admin_route_smoke_required": false,
|
||
"certificate_owner_confirmation_required": false,
|
||
"config_ids": [
|
||
"host188_internal_tools_https"
|
||
],
|
||
"control_tier": "C0",
|
||
"domain": "harbor.wooo.work",
|
||
"has_tls_certificate_path": true,
|
||
"hosts": [
|
||
"192.168.0.188"
|
||
],
|
||
"owner_response_accepted": false,
|
||
"public_route_smoke_required": true,
|
||
"route_smoke_accepted": false,
|
||
"tls_owner_check_required": false,
|
||
"upstream_count": 1,
|
||
"websocket_or_api_smoke_required": true,
|
||
"websocket_route_count": 0
|
||
},
|
||
{
|
||
"acme_challenge_present": true,
|
||
"admin_route_count": 0,
|
||
"admin_route_smoke_required": false,
|
||
"certificate_owner_confirmation_required": true,
|
||
"config_ids": [
|
||
"host188_internal_tools_https"
|
||
],
|
||
"control_tier": "C0",
|
||
"domain": "langfuse.wooo.work",
|
||
"has_tls_certificate_path": true,
|
||
"hosts": [
|
||
"192.168.0.188"
|
||
],
|
||
"owner_response_accepted": false,
|
||
"public_route_smoke_required": true,
|
||
"route_smoke_accepted": false,
|
||
"tls_owner_check_required": true,
|
||
"upstream_count": 1,
|
||
"websocket_or_api_smoke_required": true,
|
||
"websocket_route_count": 0
|
||
},
|
||
{
|
||
"acme_challenge_present": false,
|
||
"admin_route_count": 0,
|
||
"admin_route_smoke_required": false,
|
||
"certificate_owner_confirmation_required": false,
|
||
"config_ids": [
|
||
"host188_all_sites"
|
||
],
|
||
"control_tier": "C0",
|
||
"domain": "mo.wooo.work",
|
||
"has_tls_certificate_path": true,
|
||
"hosts": [
|
||
"192.168.0.188"
|
||
],
|
||
"owner_response_accepted": false,
|
||
"public_route_smoke_required": true,
|
||
"route_smoke_accepted": false,
|
||
"tls_owner_check_required": false,
|
||
"upstream_count": 1,
|
||
"websocket_or_api_smoke_required": true,
|
||
"websocket_route_count": 0
|
||
},
|
||
{
|
||
"acme_challenge_present": true,
|
||
"admin_route_count": 0,
|
||
"admin_route_smoke_required": false,
|
||
"certificate_owner_confirmation_required": false,
|
||
"config_ids": [
|
||
"host188_internal_tools_https"
|
||
],
|
||
"control_tier": "C0",
|
||
"domain": "registry.wooo.work",
|
||
"has_tls_certificate_path": true,
|
||
"hosts": [
|
||
"192.168.0.188"
|
||
],
|
||
"owner_response_accepted": false,
|
||
"public_route_smoke_required": true,
|
||
"route_smoke_accepted": false,
|
||
"tls_owner_check_required": false,
|
||
"upstream_count": 1,
|
||
"websocket_or_api_smoke_required": true,
|
||
"websocket_route_count": 0
|
||
},
|
||
{
|
||
"acme_challenge_present": true,
|
||
"admin_route_count": 0,
|
||
"admin_route_smoke_required": false,
|
||
"certificate_owner_confirmation_required": false,
|
||
"config_ids": [
|
||
"host188_internal_tools_https"
|
||
],
|
||
"control_tier": "C0",
|
||
"domain": "sentry.wooo.work",
|
||
"has_tls_certificate_path": true,
|
||
"hosts": [
|
||
"192.168.0.188"
|
||
],
|
||
"owner_response_accepted": false,
|
||
"public_route_smoke_required": true,
|
||
"route_smoke_accepted": false,
|
||
"tls_owner_check_required": false,
|
||
"upstream_count": 1,
|
||
"websocket_or_api_smoke_required": true,
|
||
"websocket_route_count": 0
|
||
},
|
||
{
|
||
"acme_challenge_present": false,
|
||
"admin_route_count": 0,
|
||
"admin_route_smoke_required": false,
|
||
"certificate_owner_confirmation_required": true,
|
||
"config_ids": [
|
||
"host188_all_sites",
|
||
"host188_internal_tools_https"
|
||
],
|
||
"control_tier": "C0",
|
||
"domain": "signoz.wooo.work",
|
||
"has_tls_certificate_path": true,
|
||
"hosts": [
|
||
"192.168.0.188"
|
||
],
|
||
"owner_response_accepted": false,
|
||
"public_route_smoke_required": true,
|
||
"route_smoke_accepted": false,
|
||
"tls_owner_check_required": true,
|
||
"upstream_count": 1,
|
||
"websocket_or_api_smoke_required": true,
|
||
"websocket_route_count": 1
|
||
},
|
||
{
|
||
"acme_challenge_present": true,
|
||
"admin_route_count": 2,
|
||
"admin_route_smoke_required": true,
|
||
"certificate_owner_confirmation_required": false,
|
||
"config_ids": [
|
||
"host188_all_sites",
|
||
"host188_internal_tools_https"
|
||
],
|
||
"control_tier": "C0",
|
||
"domain": "stock.wooo.work",
|
||
"has_tls_certificate_path": true,
|
||
"hosts": [
|
||
"192.168.0.188"
|
||
],
|
||
"owner_response_accepted": false,
|
||
"public_route_smoke_required": true,
|
||
"route_smoke_accepted": false,
|
||
"tls_owner_check_required": false,
|
||
"upstream_count": 1,
|
||
"websocket_or_api_smoke_required": true,
|
||
"websocket_route_count": 2
|
||
},
|
||
{
|
||
"acme_challenge_present": false,
|
||
"admin_route_count": 0,
|
||
"admin_route_smoke_required": false,
|
||
"certificate_owner_confirmation_required": true,
|
||
"config_ids": [
|
||
"host188_all_sites"
|
||
],
|
||
"control_tier": "C0",
|
||
"domain": "tsenyang.com",
|
||
"has_tls_certificate_path": true,
|
||
"hosts": [
|
||
"192.168.0.188"
|
||
],
|
||
"owner_response_accepted": false,
|
||
"public_route_smoke_required": true,
|
||
"route_smoke_accepted": false,
|
||
"tls_owner_check_required": true,
|
||
"upstream_count": 1,
|
||
"websocket_or_api_smoke_required": true,
|
||
"websocket_route_count": 0
|
||
},
|
||
{
|
||
"acme_challenge_present": true,
|
||
"admin_route_count": 0,
|
||
"admin_route_smoke_required": false,
|
||
"certificate_owner_confirmation_required": false,
|
||
"config_ids": [
|
||
"host188_all_sites"
|
||
],
|
||
"control_tier": "C0",
|
||
"domain": "vtuber.wooo.work",
|
||
"has_tls_certificate_path": true,
|
||
"hosts": [
|
||
"192.168.0.188"
|
||
],
|
||
"owner_response_accepted": false,
|
||
"public_route_smoke_required": true,
|
||
"route_smoke_accepted": false,
|
||
"tls_owner_check_required": false,
|
||
"upstream_count": 1,
|
||
"websocket_or_api_smoke_required": true,
|
||
"websocket_route_count": 1
|
||
},
|
||
{
|
||
"acme_challenge_present": false,
|
||
"admin_route_count": 0,
|
||
"admin_route_smoke_required": false,
|
||
"certificate_owner_confirmation_required": false,
|
||
"config_ids": [
|
||
"host188_all_sites"
|
||
],
|
||
"control_tier": "C0",
|
||
"domain": "www.tsenyang.com",
|
||
"has_tls_certificate_path": true,
|
||
"hosts": [
|
||
"192.168.0.188"
|
||
],
|
||
"owner_response_accepted": false,
|
||
"public_route_smoke_required": true,
|
||
"route_smoke_accepted": false,
|
||
"tls_owner_check_required": false,
|
||
"upstream_count": 1,
|
||
"websocket_or_api_smoke_required": true,
|
||
"websocket_route_count": 0
|
||
}
|
||
],
|
||
"schema_version": "public_gateway_preflight_inventory_v1",
|
||
"source_reports": [
|
||
"docs/security/nginx-config-drift-repo.snapshot.json",
|
||
"docs/security/domain-tls-certbot-inventory.snapshot.json"
|
||
],
|
||
"source_scope": "committed_nginx_and_domain_tls_snapshots_only",
|
||
"status": "repo_only_preflight_contract_ready",
|
||
"summary": {
|
||
"acme_challenge_domain_count": 7,
|
||
"action_button_count": 0,
|
||
"admin_route_domain_count": 1,
|
||
"c0_source_config_count": 2,
|
||
"certificate_owner_confirmation_required_count": 4,
|
||
"coverage_percent_after_preflight": 84,
|
||
"coverage_percent_before_preflight": 78,
|
||
"maintenance_window_accepted_count": 0,
|
||
"managed_domain_count": 14,
|
||
"nginx_test_evidence_count": 0,
|
||
"owner_acceptance_required_gate_count": 10,
|
||
"owner_provided_live_conf_received_count": 0,
|
||
"owner_response_accepted_count": 0,
|
||
"owner_response_received_count": 0,
|
||
"preflight_gate_accepted_count": 0,
|
||
"preflight_gate_count": 12,
|
||
"rendered_diff_ready_count": 0,
|
||
"repo_only_preflight_ready_count": 2,
|
||
"rollback_owner_accepted_count": 0,
|
||
"route_impact_count": 14,
|
||
"route_smoke_evidence_count": 0,
|
||
"runtime_gate_count": 0,
|
||
"source_config_count": 3,
|
||
"tls_certificate_path_count": 10,
|
||
"unique_upstream_count": 14,
|
||
"websocket_route_domain_count": 6
|
||
},
|
||
"unique_upstreams": [
|
||
"http://127.0.0.1:3000",
|
||
"http://127.0.0.1:3301",
|
||
"http://127.0.0.1:5003",
|
||
"http://192.168.0.110:3001",
|
||
"http://192.168.0.110:3003",
|
||
"http://192.168.0.110:3100",
|
||
"http://192.168.0.110:31235",
|
||
"http://192.168.0.110:5000",
|
||
"http://192.168.0.110:8929",
|
||
"http://192.168.0.110:9000",
|
||
"http://192.168.0.125:32334/api/",
|
||
"http://192.168.0.125:32334/api/v1/ws",
|
||
"http://192.168.0.125:32335",
|
||
"https://192.168.0.110"
|
||
]
|
||
}
|