Skip to content

Commit 2d465d8

Browse files
committed
test(cua): assert effective inference policy
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
1 parent c067833 commit 2d465d8

2 files changed

Lines changed: 25 additions & 76 deletions

File tree

src/lib/onboard/initial-policy-real-policy.test.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,32 @@ describe("initial sandbox policy real preset merge", () => {
181181
),
182182
);
183183

184+
const managedInference = effective.network_policies?.managed_inference;
185+
184186
expect(effective.filesystem_policy?.read_only).toContain(MANAGED_STARTUP_MERGED_CA_FILE);
185-
expect(
186-
effective.network_policies?.managed_inference?.binaries?.map((binary) => binary.path),
187-
).toEqual(["/usr/bin/python3", "/usr/local/bin/python3", "/usr/bin/curl"]);
187+
expect(managedInference).toEqual({
188+
name: "managed_inference",
189+
endpoints: [
190+
{
191+
host: "inference.local",
192+
port: 443,
193+
protocol: "rest",
194+
enforcement: "enforce",
195+
rules: [
196+
{ allow: { method: "POST", path: "/v1/chat/completions" } },
197+
{ allow: { method: "POST", path: "/v1/responses" } },
198+
{ allow: { method: "GET", path: "/v1/models" } },
199+
{ allow: { method: "GET", path: "/v1/models/**" } },
200+
],
201+
},
202+
],
203+
binaries: [
204+
{ path: "/usr/bin/python3" },
205+
{ path: "/usr/local/bin/python3" },
206+
{ path: "/usr/bin/curl" },
207+
],
208+
});
209+
expect(managedInference?.endpoints?.[0]).not.toHaveProperty("access");
188210
});
189211

190212
it("uses Hermes channel YAML when the Hermes base policy path implies the agent", () => {

test/package-contract/openshell-policy-boundary.test.ts

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -24,48 +24,6 @@ function packageFiles(packageRoot: string): string[] {
2424
return packageJson.files ?? [];
2525
}
2626

27-
type ManagedInferenceRequest = {
28-
binary: string;
29-
host: string;
30-
port: number;
31-
method: string;
32-
path: string;
33-
};
34-
35-
type ManagedInferencePolicy = {
36-
binaries?: Array<{ path?: string }>;
37-
endpoints?: Array<{
38-
host?: string;
39-
port?: number;
40-
rules?: Array<{ allow?: { method?: string; path?: string } }>;
41-
}>;
42-
};
43-
44-
function restPathMatches(pattern: string, requestPath: string): boolean {
45-
return (
46-
pattern === requestPath ||
47-
(pattern.endsWith("/**") && requestPath.startsWith(pattern.slice(0, -2)))
48-
);
49-
}
50-
51-
function managedInferenceAllows(
52-
policy: ManagedInferencePolicy,
53-
request: ManagedInferenceRequest,
54-
): boolean {
55-
const endpoint = (policy.endpoints ?? []).find(
56-
(candidate) => candidate.host === request.host && candidate.port === request.port,
57-
);
58-
return (
59-
(policy.binaries ?? []).some((binary) => binary.path === request.binary) &&
60-
endpoint?.rules?.some(
61-
(rule) =>
62-
rule.allow?.method === request.method &&
63-
typeof rule.allow.path === "string" &&
64-
restPathMatches(rule.allow.path, request.path),
65-
) === true
66-
);
67-
}
68-
6927
describe("OpenShell policy boundary package contract", () => {
7028
it.each([repoRoot, path.join(repoRoot, "nemoclaw")])(
7129
"pins the YAML parser used by both production package boundaries [case %#]",
@@ -277,37 +235,6 @@ describe("OpenShell policy boundary package contract", () => {
277235
);
278236
});
279237

280-
it.each(["/usr/bin/python3", "/usr/local/bin/python3", "/usr/bin/curl"])(
281-
"keeps NemoCUA managed inference deny-by-default for %s (#9649)",
282-
(binary) => {
283-
const rawPolicy = YAML.parse(
284-
fs.readFileSync(path.join(repoRoot, "agents", "nemocua", "policy-additions.yaml"), "utf8"),
285-
) as { network_policies?: { managed_inference?: ManagedInferencePolicy } };
286-
const policy = rawPolicy.network_policies?.managed_inference;
287-
expect(policy).toBeDefined();
288-
289-
const decide = (overrides: Partial<ManagedInferenceRequest> = {}) =>
290-
managedInferenceAllows(policy!, {
291-
binary,
292-
host: "inference.local",
293-
port: 443,
294-
method: "POST",
295-
path: "/v1/chat/completions",
296-
...overrides,
297-
});
298-
299-
expect(decide()).toBe(true);
300-
expect(decide({ method: "GET" })).toBe(false);
301-
expect(decide({ path: "/v1/embeddings" })).toBe(false);
302-
expect(decide({ host: "api.example.invalid" })).toBe(false);
303-
expect(decide({ port: 80 })).toBe(false);
304-
expect(decide({ binary: "/bin/sh" })).toBe(false);
305-
expect(decide({ method: "GET", path: "/v1/models" })).toBe(true);
306-
expect(decide({ method: "GET", path: "/v1/models/example" })).toBe(true);
307-
expect(decide({ method: "POST", path: "/v1/models/example" })).toBe(false);
308-
},
309-
);
310-
311238
it("ships an out-of-tree runtime sandbox-policy schema validator", { timeout: 240_000 }, () => {
312239
const productionDependencyTree = spawnSync(
313240
"npm",

0 commit comments

Comments
 (0)