test: cover Amap production security gates
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 2m43s
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 2m43s
This commit is contained in:
@@ -36,6 +36,7 @@ function readConsoleReview() {
|
|||||||
auto_scaling: "not_verified",
|
auto_scaling: "not_verified",
|
||||||
paid_fallback: "not_verified",
|
paid_fallback: "not_verified",
|
||||||
qps: "not_verified",
|
qps: "not_verified",
|
||||||
|
qps_limit_per_second: null,
|
||||||
reviewed_at: null,
|
reviewed_at: null,
|
||||||
security_restriction: "not_verified",
|
security_restriction: "not_verified",
|
||||||
service_binding: "not_verified",
|
service_binding: "not_verified",
|
||||||
@@ -45,15 +46,18 @@ function readConsoleReview() {
|
|||||||
if (!raw) return fallback;
|
if (!raw) return fallback;
|
||||||
try {
|
try {
|
||||||
const parsed = JSON.parse(raw);
|
const parsed = JSON.parse(raw);
|
||||||
const requiredKeys = ["allowlist", "auto_scaling", "paid_fallback", "qps", "reviewed_at", "security_restriction", "service_binding", "source"];
|
const requiredKeys = ["allowlist", "auto_scaling", "paid_fallback", "qps", "qps_limit_per_second", "reviewed_at", "security_restriction", "service_binding", "source"];
|
||||||
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || Object.keys(parsed).sort().join("|") !== requiredKeys.sort().join("|")) {
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || Object.keys(parsed).sort().join("|") !== requiredKeys.sort().join("|")) {
|
||||||
return { ...fallback, source: "invalid_input", valid: false };
|
return { ...fallback, source: "invalid_input", valid: false };
|
||||||
}
|
}
|
||||||
const statusFields = ["allowlist", "qps", "security_restriction", "service_binding"];
|
const statusFields = ["allowlist", "qps", "security_restriction", "service_binding"];
|
||||||
const statusValid = statusFields.every((field) => ["failed", "not_verified", "passed"].includes(parsed[field]));
|
const statusValid = statusFields.every((field) => ["failed", "not_verified", "passed"].includes(parsed[field]));
|
||||||
const disabledFieldsValid = ["auto_scaling", "paid_fallback"].every((field) => ["disabled", "not_verified"].includes(parsed[field]));
|
const disabledFieldsValid = ["auto_scaling", "paid_fallback"].every((field) => ["disabled", "not_verified"].includes(parsed[field]));
|
||||||
|
const qpsLimitValid = parsed.qps === "passed"
|
||||||
|
? Number.isSafeInteger(parsed.qps_limit_per_second) && parsed.qps_limit_per_second >= 1 && parsed.qps_limit_per_second <= 1_000
|
||||||
|
: parsed.qps_limit_per_second === null;
|
||||||
const reviewedAtValid = typeof parsed.reviewed_at === "string" && Number.isFinite(Date.parse(parsed.reviewed_at));
|
const reviewedAtValid = typeof parsed.reviewed_at === "string" && Number.isFinite(Date.parse(parsed.reviewed_at));
|
||||||
if (!statusValid || !disabledFieldsValid || !reviewedAtValid || parsed.source !== "amap_console_manual_review") {
|
if (!statusValid || !disabledFieldsValid || !qpsLimitValid || !reviewedAtValid || parsed.source !== "amap_console_manual_review") {
|
||||||
return { ...fallback, source: "invalid_input", valid: false };
|
return { ...fallback, source: "invalid_input", valid: false };
|
||||||
}
|
}
|
||||||
return { ...parsed, valid: true };
|
return { ...parsed, valid: true };
|
||||||
@@ -90,17 +94,23 @@ const serviceRegression = build.exit_code === 0
|
|||||||
const localHardStop = build.exit_code === 0
|
const localHardStop = build.exit_code === 0
|
||||||
? run("pnpm", ["exec", "vitest", "run", "tests/api/wp7-04-amap-release-gate.test.ts"])
|
? run("pnpm", ["exec", "vitest", "run", "tests/api/wp7-04-amap-release-gate.test.ts"])
|
||||||
: skipped("pnpm exec vitest run tests/api/wp7-04-amap-release-gate.test.ts");
|
: skipped("pnpm exec vitest run tests/api/wp7-04-amap-release-gate.test.ts");
|
||||||
|
const productionAdapter = build.exit_code === 0
|
||||||
|
? run("pnpm", ["exec", "vitest", "run", "tests/api/wp7-04-amap-production-adapter.test.ts"])
|
||||||
|
: skipped("pnpm exec vitest run tests/api/wp7-04-amap-production-adapter.test.ts");
|
||||||
const consentFlow = build.exit_code === 0
|
const consentFlow = build.exit_code === 0
|
||||||
? run("pnpm", ["exec", "vitest", "run", "tests/unit/wp4-04-palette-dynamic.test.ts"])
|
? run("pnpm", ["exec", "vitest", "run", "tests/unit/wp4-04-palette-dynamic.test.ts"])
|
||||||
: skipped("pnpm exec vitest run tests/unit/wp4-04-palette-dynamic.test.ts");
|
: skipped("pnpm exec vitest run tests/unit/wp4-04-palette-dynamic.test.ts");
|
||||||
const supervisorBuild = run("dotnet", ["build", "supervisor/Dada.Supervisor/Dada.Supervisor.csproj", "--configuration", "Release"]);
|
const supervisorBuild = run("dotnet", ["build", "supervisor/Dada.Supervisor/Dada.Supervisor.csproj", "--configuration", "Release"]);
|
||||||
|
const supervisorSecurity = supervisorBuild.exit_code === 0
|
||||||
|
? run("dotnet", ["run", "--project", "supervisor/Dada.Supervisor.Tests/Dada.Supervisor.Tests.csproj", "--configuration", "Release"])
|
||||||
|
: skipped("dotnet run --project supervisor/Dada.Supervisor.Tests/Dada.Supervisor.Tests.csproj --configuration Release");
|
||||||
const supervisorExe = resolve("supervisor", "Dada.Supervisor", "bin", "Release", "net8.0-windows", "Dada.Supervisor.exe");
|
const supervisorExe = resolve("supervisor", "Dada.Supervisor", "bin", "Release", "net8.0-windows", "Dada.Supervisor.exe");
|
||||||
const external = supervisorBuild.exit_code === 0 && existsSync(supervisorExe)
|
const external = supervisorBuild.exit_code === 0 && existsSync(supervisorExe)
|
||||||
? run(supervisorExe, ["secrets", "probe", "api-amap"], "Dada.Supervisor.exe secrets probe api-amap")
|
? run(supervisorExe, ["secrets", "probe", "api-amap"], "Dada.Supervisor.exe secrets probe api-amap")
|
||||||
: skipped("Dada.Supervisor.exe secrets probe api-amap");
|
: skipped("Dada.Supervisor.exe secrets probe api-amap");
|
||||||
const trace = run("pnpm", ["validate:tdd-trace"]);
|
const trace = run("pnpm", ["validate:tdd-trace"]);
|
||||||
const security = run("pnpm", ["test:security"]);
|
const security = run("pnpm", ["test:security"]);
|
||||||
const commands = [build, locationRegression, serviceRegression, localHardStop, consentFlow, supervisorBuild, external, trace, security]
|
const commands = [build, locationRegression, serviceRegression, localHardStop, productionAdapter, consentFlow, supervisorBuild, supervisorSecurity, external, trace, security]
|
||||||
.map(({ command, exit_code, finished_at, started_at }) => ({ command, exit_code, finished_at, started_at }));
|
.map(({ command, exit_code, finished_at, started_at }) => ({ command, exit_code, finished_at, started_at }));
|
||||||
const parsedExternal = (() => {
|
const parsedExternal = (() => {
|
||||||
try { return JSON.parse(external.stdout.trim().split(/\r?\n/).at(-1) ?? ""); } catch { return {}; }
|
try { return JSON.parse(external.stdout.trim().split(/\r?\n/).at(-1) ?? ""); } catch { return {}; }
|
||||||
@@ -111,9 +121,11 @@ const realCalls = Number.isSafeInteger(parsedExternal.real_calls) && parsedExter
|
|||||||
: 0;
|
: 0;
|
||||||
const probePassed = external.exit_code === 0 && safeProbeCode === "amap_probe_passed" && realCalls === 2;
|
const probePassed = external.exit_code === 0 && safeProbeCode === "amap_probe_passed" && realCalls === 2;
|
||||||
const hardStopPassed = localHardStop.exit_code === 0;
|
const hardStopPassed = localHardStop.exit_code === 0;
|
||||||
|
const productionAdapterPassed = productionAdapter.exit_code === 0;
|
||||||
const consentPassed = consentFlow.exit_code === 0;
|
const consentPassed = consentFlow.exit_code === 0;
|
||||||
|
const supervisorSecurityPassed = supervisorSecurity.exit_code === 0;
|
||||||
const regressionPassed = locationRegression.exit_code === 0 && serviceRegression.exit_code === 0;
|
const regressionPassed = locationRegression.exit_code === 0 && serviceRegression.exit_code === 0;
|
||||||
const automatedPassed = build.exit_code === 0 && hardStopPassed && consentPassed && regressionPassed && trace.exit_code === 0 && security.exit_code === 0;
|
const automatedPassed = build.exit_code === 0 && hardStopPassed && productionAdapterPassed && consentPassed && supervisorSecurityPassed && regressionPassed && trace.exit_code === 0 && security.exit_code === 0;
|
||||||
const manualReviewPassed = consoleReview.valid
|
const manualReviewPassed = consoleReview.valid
|
||||||
&& consoleReview.service_binding === "passed"
|
&& consoleReview.service_binding === "passed"
|
||||||
&& consoleReview.qps === "passed"
|
&& consoleReview.qps === "passed"
|
||||||
@@ -131,7 +143,9 @@ if (consoleReview.security_restriction !== "passed") requiredBeforeRelease.push(
|
|||||||
if (consoleReview.paid_fallback !== "disabled") requiredBeforeRelease.push("paid_fallback_disabled");
|
if (consoleReview.paid_fallback !== "disabled") requiredBeforeRelease.push("paid_fallback_disabled");
|
||||||
if (consoleReview.auto_scaling !== "disabled") requiredBeforeRelease.push("auto_scaling_disabled");
|
if (consoleReview.auto_scaling !== "disabled") requiredBeforeRelease.push("auto_scaling_disabled");
|
||||||
if (!hardStopPassed) requiredBeforeRelease.push("monthly_1000_hard_stop");
|
if (!hardStopPassed) requiredBeforeRelease.push("monthly_1000_hard_stop");
|
||||||
|
if (!productionAdapterPassed) requiredBeforeRelease.push("production_amap_adapter");
|
||||||
if (!consentPassed) requiredBeforeRelease.push("dyn004_confirmation");
|
if (!consentPassed) requiredBeforeRelease.push("dyn004_confirmation");
|
||||||
|
if (!supervisorSecurityPassed) requiredBeforeRelease.push("controlled_probe_security");
|
||||||
|
|
||||||
const blocker = !automatedPassed
|
const blocker = !automatedPassed
|
||||||
? "automated_regression_failed"
|
? "automated_regression_failed"
|
||||||
@@ -153,11 +167,15 @@ const contractEvidence = {
|
|||||||
checks: {
|
checks: {
|
||||||
allowlist: consoleReview.allowlist === "passed" ? "manual_console_passed" : consoleReview.allowlist,
|
allowlist: consoleReview.allowlist === "passed" ? "manual_console_passed" : consoleReview.allowlist,
|
||||||
auto_scaling: consoleReview.auto_scaling,
|
auto_scaling: consoleReview.auto_scaling,
|
||||||
|
client_security_controls: productionAdapterPassed && supervisorSecurityPassed ? "automated_passed" : "failed",
|
||||||
|
controlled_probe_security: supervisorSecurityPassed ? "automated_passed" : "failed",
|
||||||
dyn004_hard_stop: consentPassed ? "confirmation_contract_passed" : "failed",
|
dyn004_hard_stop: consentPassed ? "confirmation_contract_passed" : "failed",
|
||||||
location_and_reverse_geocode: probePassed ? "real_probe_passed" : "not_verified",
|
location_and_reverse_geocode: probePassed ? "real_probe_passed" : "not_verified",
|
||||||
monthly_hard_limit_1000: hardStopPassed ? "local_pre_egress_passed" : "failed",
|
monthly_hard_limit_1000: hardStopPassed ? "local_pre_egress_passed" : "failed",
|
||||||
paid_fallback: consoleReview.paid_fallback,
|
paid_fallback: consoleReview.paid_fallback,
|
||||||
|
production_adapter: productionAdapterPassed ? "credential_channel_real_adapter_passed" : "failed",
|
||||||
provider_qps: consoleReview.qps === "passed" ? "manual_console_passed" : consoleReview.qps,
|
provider_qps: consoleReview.qps === "passed" ? "manual_console_passed" : consoleReview.qps,
|
||||||
|
provider_qps_limit_per_second: consoleReview.qps_limit_per_second,
|
||||||
security_binding: consoleReview.security_restriction === "passed" ? "manual_console_passed" : consoleReview.security_restriction,
|
security_binding: consoleReview.security_restriction === "passed" ? "manual_console_passed" : consoleReview.security_restriction,
|
||||||
service_binding: consoleReview.service_binding === "passed" ? "manual_console_passed" : consoleReview.service_binding,
|
service_binding: consoleReview.service_binding === "passed" ? "manual_console_passed" : consoleReview.service_binding,
|
||||||
},
|
},
|
||||||
@@ -183,6 +201,7 @@ const manualReviewEvidence = {
|
|||||||
auto_scaling: consoleReview.auto_scaling,
|
auto_scaling: consoleReview.auto_scaling,
|
||||||
paid_fallback: consoleReview.paid_fallback,
|
paid_fallback: consoleReview.paid_fallback,
|
||||||
qps: consoleReview.qps,
|
qps: consoleReview.qps,
|
||||||
|
qps_limit_per_second: consoleReview.qps_limit_per_second,
|
||||||
security_restriction: consoleReview.security_restriction,
|
security_restriction: consoleReview.security_restriction,
|
||||||
service_binding: consoleReview.service_binding,
|
service_binding: consoleReview.service_binding,
|
||||||
},
|
},
|
||||||
@@ -221,7 +240,7 @@ const redactionEvidence = {
|
|||||||
forbidden_fields_present: !evidenceRedactionPassed,
|
forbidden_fields_present: !evidenceRedactionPassed,
|
||||||
source_security_scan: security.exit_code === 0 ? "passed" : "failed",
|
source_security_scan: security.exit_code === 0 ? "passed" : "failed",
|
||||||
status: evidenceRedactionPassed && security.exit_code === 0 ? "passed" : "failed",
|
status: evidenceRedactionPassed && security.exit_code === 0 ? "passed" : "failed",
|
||||||
stored_fields: ["service", "status", "logical_limit", "manual_review_status"],
|
stored_fields: ["service", "status", "logical_limit", "manual_review_status", "qps_limit_per_second"],
|
||||||
schema_version: "1.1",
|
schema_version: "1.1",
|
||||||
};
|
};
|
||||||
if (redactionEvidence.status !== "passed") {
|
if (redactionEvidence.status !== "passed") {
|
||||||
|
|||||||
Reference in New Issue
Block a user