@highflame/policy 2.2.26 → 2.2.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_schemas/agent_ops/context.json +292 -5
- package/_schemas/agent_ops/schema.cedarschema +167 -0
- package/_schemas/agent_ops/templates/profiles/data_processing.cedar +114 -0
- package/_schemas/agent_ops/templates/profiles/gpu_training.cedar +117 -0
- package/_schemas/agent_ops/templates/profiles/locked_down.cedar +118 -0
- package/_schemas/agent_ops/templates/profiles/network_dev.cedar +117 -0
- package/_schemas/agent_ops/templates/templates.json +41 -0
- package/_schemas/guardrails/templates/mcp_server_allowlist.cedar +41 -0
- package/_schemas/guardrails/templates/templates.json +9 -0
- package/dist/actions.gen.d.ts +1 -0
- package/dist/actions.gen.js +1 -0
- package/dist/agent_ops-context.gen.d.ts +18 -1
- package/dist/agent_ops-context.gen.js +34 -0
- package/dist/agent_ops-defaults.gen.d.ts +1 -1
- package/dist/agent_ops-defaults.gen.js +548 -0
- package/dist/agent_ops-entities.gen.js +5 -1
- package/dist/guardrails-defaults.gen.js +60 -0
- package/dist/schema.gen.d.ts +1 -1
- package/dist/schema.gen.js +1 -0
- package/dist/service-schemas.gen.d.ts +1 -1
- package/dist/service-schemas.gen.js +216 -5
- package/package.json +1 -1
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Sandbox profile — Data processing
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Offline batch data work (ADR 0019 D4): read/write under /scratch, /data and
|
|
5
|
+
// /tmp; run python and a POSIX shell; no network egress; no mechanism toggles;
|
|
6
|
+
// kernel-tier isolation or stronger (Forge IsolationTier kernel/hardware).
|
|
7
|
+
//
|
|
8
|
+
// Enforcement model (ADR 0019 D1/D3): the ceiling is expressed as `forbid`
|
|
9
|
+
// rules so it overrides AgentOps' `organization.permit-baseline`; the single
|
|
10
|
+
// `permit` turns provisioning ON. Every forbid `has`-guards the optional
|
|
11
|
+
// attribute it reads — an absent-attribute access errors and silently voids the
|
|
12
|
+
// forbid (fail-open), so the guard is load-bearing.
|
|
13
|
+
//
|
|
14
|
+
// Context keys consumed: isolation_tier, writable_paths, network_egress,
|
|
15
|
+
// exec_allowlist, mechanism_capabilities.
|
|
16
|
+
//
|
|
17
|
+
// Category: sandbox
|
|
18
|
+
// Namespace: AgentOps
|
|
19
|
+
// =============================================================================
|
|
20
|
+
|
|
21
|
+
@id("sandbox.allow-data-processing")
|
|
22
|
+
@name("Permit data-processing sandbox provisioning")
|
|
23
|
+
@description("Permits provision_sandbox so this identity can create sandboxes within the data-processing ceiling enforced by the forbid rules below.")
|
|
24
|
+
@severity("high")
|
|
25
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
26
|
+
permit (
|
|
27
|
+
principal,
|
|
28
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
29
|
+
resource
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
@id("sandbox.block-data-processing-tier")
|
|
33
|
+
@name("Block weak isolation for data sandbox")
|
|
34
|
+
@description("Blocks provision_sandbox when the requested isolation tier is weaker than the kernel tier.")
|
|
35
|
+
@severity("high")
|
|
36
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
37
|
+
@reject_message("Sandbox provisioning blocked: data-processing profile requires kernel-tier isolation or stronger.")
|
|
38
|
+
forbid (
|
|
39
|
+
principal,
|
|
40
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
41
|
+
resource
|
|
42
|
+
)
|
|
43
|
+
when {
|
|
44
|
+
context has isolation_tier &&
|
|
45
|
+
!(["kernel", "hardware"].contains(context.isolation_tier))
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
@id("sandbox.block-data-processing-write")
|
|
49
|
+
@name("Block writable paths outside data dirs")
|
|
50
|
+
@description("Blocks provision_sandbox when a requested writable path prefix is outside /scratch, /data or /tmp.")
|
|
51
|
+
@severity("high")
|
|
52
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
53
|
+
@reject_message("Sandbox provisioning blocked: data-processing profile permits writes only under /scratch, /data or /tmp.")
|
|
54
|
+
forbid (
|
|
55
|
+
principal,
|
|
56
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
57
|
+
resource
|
|
58
|
+
)
|
|
59
|
+
when {
|
|
60
|
+
context has writable_paths &&
|
|
61
|
+
!(["/scratch", "/data", "/tmp"].containsAll(context.writable_paths))
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
@id("sandbox.block-data-processing-exec")
|
|
65
|
+
@name("Block executables outside python and shell")
|
|
66
|
+
@description("Blocks provision_sandbox when the requested exec allowlist includes anything other than python or a POSIX shell.")
|
|
67
|
+
@severity("high")
|
|
68
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
69
|
+
@reject_message("Sandbox provisioning blocked: data-processing profile permits only python, python3, bash and sh.")
|
|
70
|
+
forbid (
|
|
71
|
+
principal,
|
|
72
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
73
|
+
resource
|
|
74
|
+
)
|
|
75
|
+
when {
|
|
76
|
+
context has exec_allowlist &&
|
|
77
|
+
!(["python", "python3", "bash", "sh"].containsAll(context.exec_allowlist))
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
@id("sandbox.block-data-processing-egress")
|
|
81
|
+
@name("Block network egress for data sandbox")
|
|
82
|
+
@description("Blocks provision_sandbox when outbound network egress is requested.")
|
|
83
|
+
@severity("high")
|
|
84
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
85
|
+
@reject_message("Sandbox provisioning blocked: data-processing profile forbids all network egress.")
|
|
86
|
+
forbid (
|
|
87
|
+
principal,
|
|
88
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
89
|
+
resource
|
|
90
|
+
)
|
|
91
|
+
when {
|
|
92
|
+
(context has network_egress && context.network_egress == true) ||
|
|
93
|
+
(context has egress_hosts)
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
@id("sandbox.block-data-processing-mechanisms")
|
|
97
|
+
@name("Block mechanism toggles for data sandbox")
|
|
98
|
+
@description("Blocks provision_sandbox when any curated mechanism toggle is requested.")
|
|
99
|
+
@severity("high")
|
|
100
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
101
|
+
@reject_message("Sandbox provisioning blocked: data-processing profile forbids all mechanism toggles.")
|
|
102
|
+
forbid (
|
|
103
|
+
principal,
|
|
104
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
105
|
+
resource
|
|
106
|
+
)
|
|
107
|
+
when {
|
|
108
|
+
context has mechanism_capabilities &&
|
|
109
|
+
(context.mechanism_capabilities.contains("sys:ptrace") ||
|
|
110
|
+
context.mechanism_capabilities.contains("sys:bpf") ||
|
|
111
|
+
context.mechanism_capabilities.contains("sys:raw_socket") ||
|
|
112
|
+
context.mechanism_capabilities.contains("dev:gpu") ||
|
|
113
|
+
context.mechanism_capabilities.contains("virt:nested"))
|
|
114
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Sandbox profile — GPU training
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// GPU-accelerated training/fine-tuning (ADR 0019 D4): write under /scratch,
|
|
5
|
+
// /data, /workspace and /tmp; run python and the common launchers; reach model
|
|
6
|
+
// and dataset hubs; the ONLY permitted mechanism toggle is `dev:gpu`; kernel-tier
|
|
7
|
+
// isolation or stronger (Forge IsolationTier kernel/hardware — GPU passthrough
|
|
8
|
+
// needs a real kernel, ADR 0019 D4 "KERNEL-tier floor").
|
|
9
|
+
//
|
|
10
|
+
// Enforcement model (ADR 0019 D1/D3): the ceiling is expressed as `forbid`
|
|
11
|
+
// rules so it overrides AgentOps' `organization.permit-baseline`; the single
|
|
12
|
+
// `permit` turns provisioning ON. `dev:gpu` is allowed; every OTHER mechanism
|
|
13
|
+
// toggle (ptrace, bpf, raw_socket, nested virt) is still forbidden. Every forbid
|
|
14
|
+
// `has`-guards the optional attribute it reads (absent-attribute access errors
|
|
15
|
+
// and silently voids a forbid — fail-open).
|
|
16
|
+
//
|
|
17
|
+
// Context keys consumed: isolation_tier, writable_paths, exec_allowlist,
|
|
18
|
+
// egress_hosts, mechanism_capabilities.
|
|
19
|
+
//
|
|
20
|
+
// Category: sandbox
|
|
21
|
+
// Namespace: AgentOps
|
|
22
|
+
// =============================================================================
|
|
23
|
+
|
|
24
|
+
@id("sandbox.allow-gpu-training")
|
|
25
|
+
@name("Permit gpu-training sandbox provisioning")
|
|
26
|
+
@description("Permits provision_sandbox so this identity can create sandboxes within the gpu-training ceiling enforced by the forbid rules below.")
|
|
27
|
+
@severity("high")
|
|
28
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
29
|
+
permit (
|
|
30
|
+
principal,
|
|
31
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
32
|
+
resource
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
@id("sandbox.block-gpu-training-tier")
|
|
36
|
+
@name("Block weak isolation for gpu sandbox")
|
|
37
|
+
@description("Blocks provision_sandbox when the requested isolation tier is weaker than the kernel tier required for GPU passthrough.")
|
|
38
|
+
@severity("high")
|
|
39
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
40
|
+
@reject_message("Sandbox provisioning blocked: gpu-training profile requires kernel-tier isolation or stronger.")
|
|
41
|
+
forbid (
|
|
42
|
+
principal,
|
|
43
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
44
|
+
resource
|
|
45
|
+
)
|
|
46
|
+
when {
|
|
47
|
+
context has isolation_tier &&
|
|
48
|
+
!(["kernel", "hardware"].contains(context.isolation_tier))
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
@id("sandbox.block-gpu-training-write")
|
|
52
|
+
@name("Block writable paths outside training dirs")
|
|
53
|
+
@description("Blocks provision_sandbox when a requested writable path prefix is outside /scratch, /data, /workspace or /tmp.")
|
|
54
|
+
@severity("high")
|
|
55
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
56
|
+
@reject_message("Sandbox provisioning blocked: gpu-training profile permits writes only under /scratch, /data, /workspace or /tmp.")
|
|
57
|
+
forbid (
|
|
58
|
+
principal,
|
|
59
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
60
|
+
resource
|
|
61
|
+
)
|
|
62
|
+
when {
|
|
63
|
+
context has writable_paths &&
|
|
64
|
+
!(["/scratch", "/data", "/workspace", "/tmp"].containsAll(context.writable_paths))
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
@id("sandbox.block-gpu-training-exec")
|
|
68
|
+
@name("Block executables outside training launchers")
|
|
69
|
+
@description("Blocks provision_sandbox when the requested exec allowlist includes anything outside python and the approved launchers.")
|
|
70
|
+
@severity("high")
|
|
71
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
72
|
+
@reject_message("Sandbox provisioning blocked: gpu-training profile permits only python, bash, sh, accelerate and torchrun.")
|
|
73
|
+
forbid (
|
|
74
|
+
principal,
|
|
75
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
76
|
+
resource
|
|
77
|
+
)
|
|
78
|
+
when {
|
|
79
|
+
context has exec_allowlist &&
|
|
80
|
+
!(["python", "python3", "bash", "sh", "accelerate", "torchrun"].containsAll(context.exec_allowlist))
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
@id("sandbox.block-gpu-training-egress")
|
|
84
|
+
@name("Block egress outside model and dataset hubs")
|
|
85
|
+
@description("Blocks provision_sandbox when a requested egress host is outside the approved model and dataset hubs.")
|
|
86
|
+
@severity("high")
|
|
87
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
88
|
+
@reject_message("Sandbox provisioning blocked: gpu-training profile permits egress only to approved model and dataset hubs.")
|
|
89
|
+
forbid (
|
|
90
|
+
principal,
|
|
91
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
92
|
+
resource
|
|
93
|
+
)
|
|
94
|
+
when {
|
|
95
|
+
(context has egress_hosts &&
|
|
96
|
+
!(["huggingface.co", "cdn-lfs.huggingface.co", "pypi.org", "files.pythonhosted.org", "storage.googleapis.com"].containsAll(context.egress_hosts))) ||
|
|
97
|
+
(context has network_egress && context.network_egress == true && !(context has egress_hosts))
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
@id("sandbox.block-gpu-training-mechanisms")
|
|
101
|
+
@name("Block mechanism toggles beyond gpu")
|
|
102
|
+
@description("Blocks provision_sandbox when a mechanism toggle other than dev:gpu is requested.")
|
|
103
|
+
@severity("high")
|
|
104
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
105
|
+
@reject_message("Sandbox provisioning blocked: gpu-training profile permits only the dev:gpu mechanism toggle.")
|
|
106
|
+
forbid (
|
|
107
|
+
principal,
|
|
108
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
109
|
+
resource
|
|
110
|
+
)
|
|
111
|
+
when {
|
|
112
|
+
context has mechanism_capabilities &&
|
|
113
|
+
(context.mechanism_capabilities.contains("sys:ptrace") ||
|
|
114
|
+
context.mechanism_capabilities.contains("sys:bpf") ||
|
|
115
|
+
context.mechanism_capabilities.contains("sys:raw_socket") ||
|
|
116
|
+
context.mechanism_capabilities.contains("virt:nested"))
|
|
117
|
+
};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Sandbox profile — Locked down
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// The tightest Forge sandbox envelope (ADR 0019 D4): execute `python` only,
|
|
5
|
+
// write only under `/scratch`, no network egress, no mechanism toggles,
|
|
6
|
+
// kernel-tier isolation or stronger (Forge IsolationTier kernel/hardware).
|
|
7
|
+
// Deploy to an agent to let it provision sandboxes for pure, offline compute
|
|
8
|
+
// and nothing more.
|
|
9
|
+
//
|
|
10
|
+
// Enforcement model (ADR 0019 D1/D3): AgentOps ships `organization.permit-baseline`
|
|
11
|
+
// which permits every action — including provision_sandbox — so the ceiling here
|
|
12
|
+
// is expressed as `forbid` rules (forbid overrides permit in Cedar). The single
|
|
13
|
+
// `permit` below turns provisioning ON when this profile is deployed without the
|
|
14
|
+
// baseline. Every forbid `has`-guards the optional context attribute it reads:
|
|
15
|
+
// touching an absent attribute is a Cedar evaluation error that silently voids
|
|
16
|
+
// the forbid (fail-open), so the guard is load-bearing, not decorative.
|
|
17
|
+
//
|
|
18
|
+
// Context keys consumed: isolation_tier, writable_paths, network_egress,
|
|
19
|
+
// egress_hosts, exec_allowlist, mechanism_capabilities.
|
|
20
|
+
//
|
|
21
|
+
// Category: sandbox
|
|
22
|
+
// Namespace: AgentOps
|
|
23
|
+
// =============================================================================
|
|
24
|
+
|
|
25
|
+
@id("sandbox.allow-locked-down")
|
|
26
|
+
@name("Permit locked-down sandbox provisioning")
|
|
27
|
+
@description("Permits provision_sandbox so this identity can create sandboxes within the locked-down ceiling enforced by the forbid rules below.")
|
|
28
|
+
@severity("high")
|
|
29
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
30
|
+
permit (
|
|
31
|
+
principal,
|
|
32
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
33
|
+
resource
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
@id("sandbox.block-locked-down-tier")
|
|
37
|
+
@name("Block weak isolation for locked-down sandbox")
|
|
38
|
+
@description("Blocks provision_sandbox when the requested isolation tier is weaker than the kernel tier.")
|
|
39
|
+
@severity("high")
|
|
40
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
41
|
+
@reject_message("Sandbox provisioning blocked: locked-down profile requires kernel-tier isolation or stronger.")
|
|
42
|
+
forbid (
|
|
43
|
+
principal,
|
|
44
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
45
|
+
resource
|
|
46
|
+
)
|
|
47
|
+
when {
|
|
48
|
+
context has isolation_tier &&
|
|
49
|
+
!(["kernel", "hardware"].contains(context.isolation_tier))
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
@id("sandbox.block-locked-down-write")
|
|
53
|
+
@name("Block writable paths outside scratch")
|
|
54
|
+
@description("Blocks provision_sandbox when a requested writable path prefix is outside /scratch.")
|
|
55
|
+
@severity("high")
|
|
56
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
57
|
+
@reject_message("Sandbox provisioning blocked: locked-down profile permits writes only under /scratch.")
|
|
58
|
+
forbid (
|
|
59
|
+
principal,
|
|
60
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
61
|
+
resource
|
|
62
|
+
)
|
|
63
|
+
when {
|
|
64
|
+
context has writable_paths &&
|
|
65
|
+
!(["/scratch"].containsAll(context.writable_paths))
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
@id("sandbox.block-locked-down-exec")
|
|
69
|
+
@name("Block executables outside python")
|
|
70
|
+
@description("Blocks provision_sandbox when the requested exec allowlist includes anything other than python.")
|
|
71
|
+
@severity("high")
|
|
72
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
73
|
+
@reject_message("Sandbox provisioning blocked: locked-down profile permits only python and python3.")
|
|
74
|
+
forbid (
|
|
75
|
+
principal,
|
|
76
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
77
|
+
resource
|
|
78
|
+
)
|
|
79
|
+
when {
|
|
80
|
+
context has exec_allowlist &&
|
|
81
|
+
!(["python", "python3"].containsAll(context.exec_allowlist))
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
@id("sandbox.block-locked-down-egress")
|
|
85
|
+
@name("Block network egress for locked-down sandbox")
|
|
86
|
+
@description("Blocks provision_sandbox when outbound network egress is requested.")
|
|
87
|
+
@severity("high")
|
|
88
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
89
|
+
@reject_message("Sandbox provisioning blocked: locked-down profile forbids all network egress.")
|
|
90
|
+
forbid (
|
|
91
|
+
principal,
|
|
92
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
93
|
+
resource
|
|
94
|
+
)
|
|
95
|
+
when {
|
|
96
|
+
(context has network_egress && context.network_egress == true) ||
|
|
97
|
+
(context has egress_hosts)
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
@id("sandbox.block-locked-down-mechanisms")
|
|
101
|
+
@name("Block mechanism toggles for locked-down sandbox")
|
|
102
|
+
@description("Blocks provision_sandbox when any curated mechanism toggle is requested.")
|
|
103
|
+
@severity("high")
|
|
104
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
105
|
+
@reject_message("Sandbox provisioning blocked: locked-down profile forbids all mechanism toggles.")
|
|
106
|
+
forbid (
|
|
107
|
+
principal,
|
|
108
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
109
|
+
resource
|
|
110
|
+
)
|
|
111
|
+
when {
|
|
112
|
+
context has mechanism_capabilities &&
|
|
113
|
+
(context.mechanism_capabilities.contains("sys:ptrace") ||
|
|
114
|
+
context.mechanism_capabilities.contains("sys:bpf") ||
|
|
115
|
+
context.mechanism_capabilities.contains("sys:raw_socket") ||
|
|
116
|
+
context.mechanism_capabilities.contains("dev:gpu") ||
|
|
117
|
+
context.mechanism_capabilities.contains("virt:nested"))
|
|
118
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Sandbox profile — Network dev
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Interactive/dev workloads that need controlled egress (ADR 0019 D4): write
|
|
5
|
+
// under /scratch, /workspace and /tmp; run the common dev toolchain; reach ONLY
|
|
6
|
+
// an approved set of package and source hosts; no mechanism toggles; kernel-tier
|
|
7
|
+
// isolation or stronger (Forge IsolationTier kernel/hardware).
|
|
8
|
+
//
|
|
9
|
+
// Enforcement model (ADR 0019 D1/D3): the ceiling is expressed as `forbid`
|
|
10
|
+
// rules so it overrides AgentOps' `organization.permit-baseline`; the single
|
|
11
|
+
// `permit` turns provisioning ON. Network egress is PERMITTED here but the host
|
|
12
|
+
// allowlist is enforced by the egress forbid. Every forbid `has`-guards the
|
|
13
|
+
// optional attribute it reads (absent-attribute access errors and silently
|
|
14
|
+
// voids a forbid — fail-open).
|
|
15
|
+
//
|
|
16
|
+
// Context keys consumed: isolation_tier, writable_paths, exec_allowlist,
|
|
17
|
+
// egress_hosts, mechanism_capabilities.
|
|
18
|
+
//
|
|
19
|
+
// Category: sandbox
|
|
20
|
+
// Namespace: AgentOps
|
|
21
|
+
// =============================================================================
|
|
22
|
+
|
|
23
|
+
@id("sandbox.allow-network-dev")
|
|
24
|
+
@name("Permit network-dev sandbox provisioning")
|
|
25
|
+
@description("Permits provision_sandbox so this identity can create sandboxes within the network-dev ceiling enforced by the forbid rules below.")
|
|
26
|
+
@severity("high")
|
|
27
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
28
|
+
permit (
|
|
29
|
+
principal,
|
|
30
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
31
|
+
resource
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
@id("sandbox.block-network-dev-tier")
|
|
35
|
+
@name("Block weak isolation for network-dev sandbox")
|
|
36
|
+
@description("Blocks provision_sandbox when the requested isolation tier is weaker than the kernel tier.")
|
|
37
|
+
@severity("high")
|
|
38
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
39
|
+
@reject_message("Sandbox provisioning blocked: network-dev profile requires kernel-tier isolation or stronger.")
|
|
40
|
+
forbid (
|
|
41
|
+
principal,
|
|
42
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
43
|
+
resource
|
|
44
|
+
)
|
|
45
|
+
when {
|
|
46
|
+
context has isolation_tier &&
|
|
47
|
+
!(["kernel", "hardware"].contains(context.isolation_tier))
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
@id("sandbox.block-network-dev-write")
|
|
51
|
+
@name("Block writable paths outside workspace")
|
|
52
|
+
@description("Blocks provision_sandbox when a requested writable path prefix is outside /scratch, /workspace or /tmp.")
|
|
53
|
+
@severity("high")
|
|
54
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
55
|
+
@reject_message("Sandbox provisioning blocked: network-dev profile permits writes only under /scratch, /workspace or /tmp.")
|
|
56
|
+
forbid (
|
|
57
|
+
principal,
|
|
58
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
59
|
+
resource
|
|
60
|
+
)
|
|
61
|
+
when {
|
|
62
|
+
context has writable_paths &&
|
|
63
|
+
!(["/scratch", "/workspace", "/tmp"].containsAll(context.writable_paths))
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
@id("sandbox.block-network-dev-exec")
|
|
67
|
+
@name("Block executables outside the dev toolchain")
|
|
68
|
+
@description("Blocks provision_sandbox when the requested exec allowlist includes anything outside the approved dev toolchain.")
|
|
69
|
+
@severity("high")
|
|
70
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
71
|
+
@reject_message("Sandbox provisioning blocked: network-dev profile permits only python, node, npm, pip, git and a POSIX shell.")
|
|
72
|
+
forbid (
|
|
73
|
+
principal,
|
|
74
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
75
|
+
resource
|
|
76
|
+
)
|
|
77
|
+
when {
|
|
78
|
+
context has exec_allowlist &&
|
|
79
|
+
!(["python", "python3", "node", "npm", "pip", "git", "bash", "sh"].containsAll(context.exec_allowlist))
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
@id("sandbox.block-network-dev-egress")
|
|
83
|
+
@name("Block egress outside approved hosts")
|
|
84
|
+
@description("Blocks provision_sandbox when a requested egress host is outside the approved package and source hosts.")
|
|
85
|
+
@severity("high")
|
|
86
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
87
|
+
@reject_message("Sandbox provisioning blocked: network-dev profile permits egress only to approved package and source hosts.")
|
|
88
|
+
forbid (
|
|
89
|
+
principal,
|
|
90
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
91
|
+
resource
|
|
92
|
+
)
|
|
93
|
+
when {
|
|
94
|
+
(context has egress_hosts &&
|
|
95
|
+
!(["pypi.org", "files.pythonhosted.org", "registry.npmjs.org", "github.com", "objects.githubusercontent.com"].containsAll(context.egress_hosts))) ||
|
|
96
|
+
(context has network_egress && context.network_egress == true && !(context has egress_hosts))
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
@id("sandbox.block-network-dev-mechanisms")
|
|
100
|
+
@name("Block mechanism toggles for network-dev sandbox")
|
|
101
|
+
@description("Blocks provision_sandbox when any curated mechanism toggle is requested.")
|
|
102
|
+
@severity("high")
|
|
103
|
+
@tags("category:sandbox,surface:provision-sandbox,scope:per-agent,posture:deny-default")
|
|
104
|
+
@reject_message("Sandbox provisioning blocked: network-dev profile forbids all mechanism toggles.")
|
|
105
|
+
forbid (
|
|
106
|
+
principal,
|
|
107
|
+
action == AgentOps::Action::"provision_sandbox",
|
|
108
|
+
resource
|
|
109
|
+
)
|
|
110
|
+
when {
|
|
111
|
+
context has mechanism_capabilities &&
|
|
112
|
+
(context.mechanism_capabilities.contains("sys:ptrace") ||
|
|
113
|
+
context.mechanism_capabilities.contains("sys:bpf") ||
|
|
114
|
+
context.mechanism_capabilities.contains("sys:raw_socket") ||
|
|
115
|
+
context.mechanism_capabilities.contains("dev:gpu") ||
|
|
116
|
+
context.mechanism_capabilities.contains("virt:nested"))
|
|
117
|
+
};
|
|
@@ -37,6 +37,11 @@
|
|
|
37
37
|
"id": "organization",
|
|
38
38
|
"name": "Organization",
|
|
39
39
|
"description": "Organization-wide baselines and default permit/deny policies."
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"id": "sandbox",
|
|
43
|
+
"name": "Sandbox",
|
|
44
|
+
"description": "Forge sandbox provisioning profiles — capability ceilings for the OS-layer envelope (writable paths, egress, exec, mechanism toggles, isolation tier)."
|
|
40
45
|
}
|
|
41
46
|
],
|
|
42
47
|
"defaults": [
|
|
@@ -61,6 +66,42 @@
|
|
|
61
66
|
"severity": "low",
|
|
62
67
|
"tags": ["category:organization", "posture:permit-default"],
|
|
63
68
|
"auto_deploy": true
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"id": "sandbox.locked-down",
|
|
72
|
+
"name": "Sandbox: Locked down",
|
|
73
|
+
"description": "Permits sandbox provisioning within the tightest ceiling: python only, writes under /scratch, no network, no mechanism toggles, kernel-tier isolation or stronger.",
|
|
74
|
+
"category": "sandbox",
|
|
75
|
+
"file": "profiles/locked_down.cedar",
|
|
76
|
+
"severity": "high",
|
|
77
|
+
"tags": ["category:sandbox", "surface:provision-sandbox", "scope:per-agent", "posture:deny-default"]
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"id": "sandbox.data-processing",
|
|
81
|
+
"name": "Sandbox: Data processing",
|
|
82
|
+
"description": "Permits sandbox provisioning for offline batch data work: python and a POSIX shell, writes under /scratch, /data and /tmp, no network, no mechanism toggles.",
|
|
83
|
+
"category": "sandbox",
|
|
84
|
+
"file": "profiles/data_processing.cedar",
|
|
85
|
+
"severity": "high",
|
|
86
|
+
"tags": ["category:sandbox", "surface:provision-sandbox", "scope:per-agent", "posture:deny-default"]
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"id": "sandbox.network-dev",
|
|
90
|
+
"name": "Sandbox: Network dev",
|
|
91
|
+
"description": "Permits sandbox provisioning for dev workloads with controlled egress: common dev toolchain, writes under /scratch, /workspace and /tmp, egress limited to approved package and source hosts.",
|
|
92
|
+
"category": "sandbox",
|
|
93
|
+
"file": "profiles/network_dev.cedar",
|
|
94
|
+
"severity": "high",
|
|
95
|
+
"tags": ["category:sandbox", "surface:provision-sandbox", "scope:per-agent", "posture:deny-default"]
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"id": "sandbox.gpu-training",
|
|
99
|
+
"name": "Sandbox: GPU training",
|
|
100
|
+
"description": "Permits sandbox provisioning for GPU training: dev:gpu the only mechanism toggle, kernel-tier isolation or stronger, writes under training dirs, egress limited to model and dataset hubs.",
|
|
101
|
+
"category": "sandbox",
|
|
102
|
+
"file": "profiles/gpu_training.cedar",
|
|
103
|
+
"severity": "high",
|
|
104
|
+
"tags": ["category:sandbox", "surface:provision-sandbox", "scope:per-agent", "posture:deny-default"]
|
|
64
105
|
}
|
|
65
106
|
]
|
|
66
107
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// MCP Server Allowlist
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Restricts MCP server connections to a pre-approved list. Customize the
|
|
5
|
+
// `context.mcp_server` values in the permit rule to match the allowed
|
|
6
|
+
// servers for your environment.
|
|
7
|
+
//
|
|
8
|
+
// Context keys consumed:
|
|
9
|
+
// - mcp_server: String
|
|
10
|
+
//
|
|
11
|
+
// Category: tools
|
|
12
|
+
// Namespace: Guardrails
|
|
13
|
+
// =============================================================================
|
|
14
|
+
|
|
15
|
+
@id("tools.allow-mcp-allowlist")
|
|
16
|
+
@name("Allow allowlisted MCP servers")
|
|
17
|
+
@description("Permits connect_server when mcp_server is in the allowlist.")
|
|
18
|
+
@severity("medium")
|
|
19
|
+
@tags("category:tools,surface:connect-server,scope:org-wide,posture:deny-default")
|
|
20
|
+
permit (
|
|
21
|
+
principal,
|
|
22
|
+
action == Guardrails::Action::"connect_server",
|
|
23
|
+
resource
|
|
24
|
+
)
|
|
25
|
+
when {
|
|
26
|
+
context has mcp_server &&
|
|
27
|
+
(context.mcp_server == "filesystem" ||
|
|
28
|
+
context.mcp_server == "playwright")
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
@id("tools.deny-non-allowlisted-mcp")
|
|
32
|
+
@name("Block non-allowlisted MCP servers")
|
|
33
|
+
@description("Blocks connect_server unconditionally so only the allowlist permit applies.")
|
|
34
|
+
@severity("medium")
|
|
35
|
+
@tags("category:tools,surface:connect-server,scope:org-wide,posture:deny-default")
|
|
36
|
+
@reject_message("MCP server connection blocked: server is not on the allowlist.")
|
|
37
|
+
forbid (
|
|
38
|
+
principal,
|
|
39
|
+
action == Guardrails::Action::"connect_server",
|
|
40
|
+
resource
|
|
41
|
+
);
|
|
@@ -231,6 +231,15 @@
|
|
|
231
231
|
"severity": "critical",
|
|
232
232
|
"tags": ["category:tools", "threat:supply-chain", "posture:deny-default"]
|
|
233
233
|
},
|
|
234
|
+
{
|
|
235
|
+
"id": "tools.mcp-server-allowlist",
|
|
236
|
+
"name": "MCP Server Allowlist",
|
|
237
|
+
"description": "Restrict MCP server connections to a pre-approved list. Customize the allowlist values to match the servers permitted in your environment.",
|
|
238
|
+
"category": "tools",
|
|
239
|
+
"file": "mcp_server_allowlist.cedar",
|
|
240
|
+
"severity": "medium",
|
|
241
|
+
"tags": ["category:tools", "surface:connect-server", "scope:org-wide", "posture:deny-default"]
|
|
242
|
+
},
|
|
234
243
|
{
|
|
235
244
|
"id": "security.chat-assistant",
|
|
236
245
|
"name": "Chat Assistant — Security",
|
package/dist/actions.gen.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ export declare const ActionType: {
|
|
|
28
28
|
readonly LoadModel: "load_model";
|
|
29
29
|
readonly ProcessPrompt: "process_prompt";
|
|
30
30
|
readonly ProcessResponse: "process_response";
|
|
31
|
+
readonly ProvisionSandbox: "provision_sandbox";
|
|
31
32
|
readonly QuarantineArtifact: "quarantine_artifact";
|
|
32
33
|
readonly ReadFile: "read_file";
|
|
33
34
|
readonly RunBuild: "run_build";
|
package/dist/actions.gen.js
CHANGED
|
@@ -29,6 +29,7 @@ export const ActionType = {
|
|
|
29
29
|
LoadModel: 'load_model',
|
|
30
30
|
ProcessPrompt: 'process_prompt',
|
|
31
31
|
ProcessResponse: 'process_response',
|
|
32
|
+
ProvisionSandbox: 'provision_sandbox',
|
|
32
33
|
QuarantineArtifact: 'quarantine_artifact',
|
|
33
34
|
ReadFile: 'read_file',
|
|
34
35
|
RunBuild: 'run_build',
|