feat: add secure WP7-02 external executor
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 48s
Dada P0-A isolated Windows CI / validate-and-package (push) Failing after 48s
This commit is contained in:
@@ -16,6 +16,12 @@ internal static class Program
|
||||
return await RunCredentialChildAsync();
|
||||
}
|
||||
|
||||
if (args.FirstOrDefault() == "--credential-echo")
|
||||
{
|
||||
Console.Write(await Console.In.ReadToEndAsync());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (args.FirstOrDefault() == "--instance-probe")
|
||||
{
|
||||
using var instance = await SingleInstanceCoordinator.TryAcquireAsync(args[1], args[2]);
|
||||
@@ -120,6 +126,28 @@ internal static class Program
|
||||
|
||||
var workerProbe = await LaunchCredentialProbeAsync(ChildRole.Worker, store);
|
||||
EqualSequence(new[] { CredentialCatalog.WorkerAiGateway }, workerProbe.Names, "Worker credential scope");
|
||||
var leakProbe = await CredentialProcessLauncher.RunToCompletionAsync(
|
||||
new ProcessStartInfo(Environment.ProcessPath!, "--credential-echo"), ChildRole.Worker, store);
|
||||
True(leakProbe.SensitiveOutputDetected, "credential echo must be detected");
|
||||
Equal(string.Empty, leakProbe.StandardOutput, "credential echo output discarded");
|
||||
Equal(string.Empty, leakProbe.StandardError, "credential echo error discarded");
|
||||
|
||||
var externalArguments = new[]
|
||||
{
|
||||
"--service", "ai-gateway-service-id",
|
||||
"--model", "gpt-image-2",
|
||||
"--run-id", "wp7-02-supervisor-probe",
|
||||
"--candidate-record", "candidate.json",
|
||||
"--config-manifest", "config.json",
|
||||
"--evidence-dir", "evidence",
|
||||
"--max-real-calls", "120",
|
||||
"--confirm-controlled-real",
|
||||
"--execute-controlled-real",
|
||||
};
|
||||
EqualSequence(externalArguments, ControlledExternalValidationLauncher.ValidateArguments(externalArguments), "controlled external argument allowlist");
|
||||
Throws<ArgumentException>(
|
||||
() => ControlledExternalValidationLauncher.ValidateArguments(externalArguments.Where(value => value != "--confirm-controlled-real").ToArray()),
|
||||
"controlled external confirmation required");
|
||||
|
||||
store.Delete(CredentialCatalog.WorkerAiGateway);
|
||||
await ThrowsAsync<MissingCredentialException>(
|
||||
@@ -166,15 +194,10 @@ internal static class Program
|
||||
|
||||
private static async Task<CredentialProbe> LaunchCredentialProbeAsync(ChildRole role, ICredentialStore store)
|
||||
{
|
||||
var startInfo = new ProcessStartInfo(Environment.ProcessPath!, "--credential-child")
|
||||
{
|
||||
RedirectStandardOutput = true,
|
||||
};
|
||||
using var process = await CredentialProcessLauncher.StartAsync(startInfo, role, store);
|
||||
var output = await process.StandardOutput.ReadToEndAsync();
|
||||
await process.WaitForExitAsync();
|
||||
Equal(0, process.ExitCode, "credential child exit code");
|
||||
return JsonSerializer.Deserialize<CredentialProbe>(output, new JsonSerializerOptions { PropertyNameCaseInsensitive = true })
|
||||
var result = await CredentialProcessLauncher.RunToCompletionAsync(new ProcessStartInfo(Environment.ProcessPath!, "--credential-child"), role, store);
|
||||
Equal(0, result.ExitCode, "credential child exit code");
|
||||
False(result.SensitiveOutputDetected, "credential child output contains injected value");
|
||||
return JsonSerializer.Deserialize<CredentialProbe>(result.StandardOutput, new JsonSerializerOptions { PropertyNameCaseInsensitive = true })
|
||||
?? throw new InvalidOperationException("Credential child returned invalid JSON.");
|
||||
}
|
||||
|
||||
@@ -355,6 +378,19 @@ internal static class Program
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
||||
private static void Throws<TException>(Action action, string message) where TException : Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
action();
|
||||
}
|
||||
catch (TException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
||||
private sealed record CredentialProbe(string[] Names, bool EnvironmentContainsMarker, bool ArgumentsContainMarker);
|
||||
|
||||
private sealed class TestCredentialStore : ICredentialStore
|
||||
|
||||
Reference in New Issue
Block a user