fix(SEC-ORCH-28+29): Add Valkey connection timeout + workItems MaxLength
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed

SEC-ORCH-28: Add connectTimeout (5000ms default) and commandTimeout
(3000ms default) to Valkey/Redis client to prevent indefinite connection
hangs. Both are configurable via VALKEY_CONNECT_TIMEOUT_MS and
VALKEY_COMMAND_TIMEOUT_MS environment variables.

SEC-ORCH-29: Add @ArrayMaxSize(50) and @MaxLength(2000) to workItems
in AgentContextDto to prevent memory exhaustion from unbounded input.
Also adds @ArrayMaxSize(20) and @MaxLength(200) to skills array.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jason Woltje
2026-02-06 15:19:44 -06:00
parent 144495ae6b
commit 3880993b60
7 changed files with 133 additions and 1 deletions

View File

@@ -122,6 +122,40 @@ describe("orchestratorConfig", () => {
});
});
describe("valkey timeout config (SEC-ORCH-28)", () => {
it("should use default connectTimeout of 5000 when not set", () => {
delete process.env.VALKEY_CONNECT_TIMEOUT_MS;
const config = orchestratorConfig();
expect(config.valkey.connectTimeout).toBe(5000);
});
it("should use provided connectTimeout when VALKEY_CONNECT_TIMEOUT_MS is set", () => {
process.env.VALKEY_CONNECT_TIMEOUT_MS = "10000";
const config = orchestratorConfig();
expect(config.valkey.connectTimeout).toBe(10000);
});
it("should use default commandTimeout of 3000 when not set", () => {
delete process.env.VALKEY_COMMAND_TIMEOUT_MS;
const config = orchestratorConfig();
expect(config.valkey.commandTimeout).toBe(3000);
});
it("should use provided commandTimeout when VALKEY_COMMAND_TIMEOUT_MS is set", () => {
process.env.VALKEY_COMMAND_TIMEOUT_MS = "8000";
const config = orchestratorConfig();
expect(config.valkey.commandTimeout).toBe(8000);
});
});
describe("spawner config", () => {
it("should use default maxConcurrentAgents of 20 when not set", () => {
delete process.env.MAX_CONCURRENT_AGENTS;

View File

@@ -8,6 +8,8 @@ export const orchestratorConfig = registerAs("orchestrator", () => ({
port: parseInt(process.env.VALKEY_PORT ?? "6379", 10),
password: process.env.VALKEY_PASSWORD,
url: process.env.VALKEY_URL ?? "redis://localhost:6379",
connectTimeout: parseInt(process.env.VALKEY_CONNECT_TIMEOUT_MS ?? "5000", 10),
commandTimeout: parseInt(process.env.VALKEY_COMMAND_TIMEOUT_MS ?? "3000", 10),
},
claude: {
apiKey: process.env.CLAUDE_API_KEY,