fix: 限定 Aipod 工具凭据最小集合

This commit is contained in:
Codex
2026-07-12 09:28:56 +02:00
parent 54f4379511
commit 1fbb3c9660
2 changed files with 77 additions and 32 deletions
+66 -27
View File
@@ -852,10 +852,45 @@ describe("AgentRun YAML tool credential binding", () => {
expect(JSON.stringify({ githubSsh, sources })).not.toContain("/root/.ssh");
});
test("preserves multi-key credentials across Aipod render and queue admission and rejects conflicts", async () => {
test("preserves explicit credential subsets across Aipod admission and rejects unknown identities or conflicts", async () => {
const renderBodies: Record<string, any>[] = [];
const submittedBodies: Record<string, any>[] = [];
let conflictingKeys = false;
let credentialMode: "all" | "subset" | "conflict" | "unknown" = "all";
const renderedToolCredentials = (): Record<string, unknown>[] => {
const credentials = [
{
tool: "github",
purpose: "github-pr",
secretRef: { name: "agentrun-v01-tool-github-pr", keys: ["GH_TOKEN"] },
projection: { kind: "env", envName: "GH_TOKEN", secretKey: "GH_TOKEN" },
},
{
tool: "unidesk-ssh",
purpose: "ssh-passthrough",
secretRef: { name: "agentrun-v01-tool-unidesk-ssh", keys: ["UNIDESK_SSH_CLIENT_TOKEN"] },
projection: { kind: "env", envName: "UNIDESK_SSH_CLIENT_TOKEN", secretKey: "UNIDESK_SSH_CLIENT_TOKEN" },
},
{
tool: "github",
purpose: "github-ssh",
secretRef: {
name: "agentrun-v01-tool-github-ssh",
keys: credentialMode === "conflict" ? ["id_ed25519", "known_hosts", "config"] : ["id_ed25519", "known_hosts"],
},
projection: { kind: "volume", mountPath: "/home/agentrun/.ssh" },
},
];
if (credentialMode === "subset") return credentials.slice(0, 1);
if (credentialMode === "unknown") {
return [{
tool: "artifact-store",
purpose: "publish",
secretRef: { name: "agentrun-artifact-store", keys: ["TOKEN"] },
projection: { kind: "env", envName: "ARTIFACT_TOKEN", secretKey: "TOKEN" },
}];
}
return credentials;
};
const renderedTask = () => ({
tenantId: "unidesk",
projectId: "pikasTech/unidesk",
@@ -875,29 +910,7 @@ describe("AgentRun YAML tool credential binding", () => {
profile: "codex",
secretRef: { name: "agentrun-v01-provider-codex", keys: ["auth.json", "config.toml"] },
}],
toolCredentials: [
{
tool: "github",
purpose: "github-pr",
secretRef: { name: "agentrun-v01-tool-github-pr", keys: ["GH_TOKEN"] },
projection: { kind: "env", envName: "GH_TOKEN", secretKey: "GH_TOKEN" },
},
{
tool: "unidesk-ssh",
purpose: "ssh-passthrough",
secretRef: { name: "agentrun-v01-tool-unidesk-ssh", keys: ["UNIDESK_SSH_CLIENT_TOKEN"] },
projection: { kind: "env", envName: "UNIDESK_SSH_CLIENT_TOKEN", secretKey: "UNIDESK_SSH_CLIENT_TOKEN" },
},
{
tool: "github",
purpose: "github-ssh",
secretRef: {
name: "agentrun-v01-tool-github-ssh",
keys: conflictingKeys ? ["id_ed25519", "known_hosts", "config"] : ["id_ed25519", "known_hosts"],
},
projection: { kind: "volume", mountPath: "/home/agentrun/.ssh" },
},
],
toolCredentials: renderedToolCredentials(),
},
},
payload: { prompt: "fixture" },
@@ -930,6 +943,11 @@ describe("AgentRun YAML tool credential binding", () => {
expect(accepted.ok).toBe(true);
expect(renderBodies).toHaveLength(1);
expect(submittedBodies).toHaveLength(1);
expect(renderBodies[0]?.executionPolicy?.secretScope?.toolCredentials?.map((credential: Record<string, unknown>) => `${credential.tool}/${credential.purpose}`)).toEqual([
"github/github-pr",
"unidesk-ssh/ssh-passthrough",
"github/github-ssh",
]);
for (const body of [renderBodies[0], submittedBodies[0]]) {
const githubSsh = body?.executionPolicy?.secretScope?.toolCredentials?.filter((credential: Record<string, unknown>) => credential.tool === "github" && credential.purpose === "github-ssh");
expect(githubSsh).toEqual([{
@@ -940,14 +958,35 @@ describe("AgentRun YAML tool credential binding", () => {
}]);
}
conflictingKeys = true;
credentialMode = "subset";
const subsetAccepted = await runAgentRunCommand(null, ["create", "task", "--aipod", "Artificer", "--prompt", "fixture", "-o", "json"]);
expect(subsetAccepted.ok).toBe(true);
expect(renderBodies).toHaveLength(2);
expect(submittedBodies).toHaveLength(2);
expect(submittedBodies[1]?.executionPolicy?.secretScope?.toolCredentials).toEqual([{
tool: "github",
purpose: "github-pr",
secretRef: { name: "agentrun-v01-tool-github-pr", keys: ["GH_TOKEN"] },
projection: { kind: "env", envName: "GH_TOKEN", secretKey: "GH_TOKEN" },
}]);
credentialMode = "conflict";
const rejected = await runAgentRunCommand(null, ["create", "task", "--aipod", "Artificer", "--prompt", "fixture", "-o", "json"]);
expect(rejected.ok).toBe(false);
expect(submittedBodies).toHaveLength(1);
expect(submittedBodies).toHaveLength(2);
const rejectedText = renderedTextOf(rejected);
expect(rejectedText).toContain("validation-failed");
expect(rejectedText).toContain("github/github-ssh keys conflict");
expect(Buffer.byteLength(rejectedText, "utf8")).toBeLessThan(2400);
credentialMode = "unknown";
const unknownRejected = await runAgentRunCommand(null, ["create", "task", "--aipod", "Artificer", "--prompt", "fixture", "-o", "json"]);
expect(unknownRejected.ok).toBe(false);
expect(submittedBodies).toHaveLength(2);
const unknownText = renderedTextOf(unknownRejected);
expect(unknownText).toContain("validation-failed");
expect(unknownText).toContain("artifact-store/publish is not declared by YAML lane");
expect(Buffer.byteLength(unknownText, "utf8")).toBeLessThan(2400);
} finally {
server.stop(true);
if (previousConfig === undefined) delete process.env.AGENTRUN_CLIENT_CONFIG;