1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
//! Sandbox abstraction for platform-specific process isolation.
//!
//! This module provides the [`Sandbox`] trait — the internal mechanism that
//! applies isolation to a command at spawn time.
//!
//! Callers don't use `Sandbox` directly; they use the [`Jail`](super::Jail)
//! trait. Only [`Jailer`](super::Jailer) knows about sandboxes.
//!
//! # Implementations
//!
//! | Sandbox | Platform | Mechanism |
//! |---------|----------|-----------|
//! | [`BwrapSandbox`] | Linux | bubblewrap namespaces + cgroups |
//! | [`LandlockSandbox`] | Linux | Landlock filesystem/network ACL |
//! | [`SeatbeltSandbox`] | macOS | sandbox-exec SBPL |
//! | [`CompositeSandbox`] | any | chains multiple sandboxes |
//! | [`NoopSandbox`] | any | passthrough (no isolation) |
//!
//! # Composition
//!
//! Sandboxes compose naturally via [`CompositeSandbox`]:
//! ```ignore
//! let sandbox = CompositeSandbox::new(vec![
//! Box::new(BwrapSandbox::new()),
//! Box::new(LandlockSandbox::new()),
//! ]);
//! ```
//! Each child's `apply()` is called in order on the same `Command`.
pub use BwrapSandbox;
pub use CompositeSandbox;
pub use LandlockSandbox;
pub use SeatbeltSandbox;
use crateResourceLimits;
use BoxliteResult;
use ;
use Command;
// ============================================================================
// Sandbox Trait
// ============================================================================
/// Platform-specific process isolation.
///
/// Each sandbox modifies a `Command` via [`apply()`](Sandbox::apply):
/// - **Namespace sandboxes** (bwrap) replace the command with a wrapper
/// - **Restriction sandboxes** (Landlock) add `pre_exec` hooks
/// - **Composed sandboxes** chain multiple `apply()` calls
///
/// Multiple `pre_exec` hooks are safe — `Command` stores them in a `Vec`,
/// executed in registration order.
// ============================================================================
// PathAccess
// ============================================================================
/// A filesystem path with access permissions for the sandbox.
///
/// Pre-computed by the [`Jailer`](super::Jailer) from system directories
/// and user volumes. Sandbox implementations translate these to
/// platform-specific mechanisms:
/// - bwrap: `--bind` (writable) or `--ro-bind` (read-only)
/// - seatbelt: `file-read*` + `file-write*` subpath rules
// ============================================================================
// SandboxContext
// ============================================================================
/// What the sandbox needs to do its job.
///
/// Translated from [`SecurityOptions`](crate::runtime::advanced_options::SecurityOptions)
/// by the [`Jailer`](super::Jailer). The sandbox never sees `SecurityOptions`
/// or box-specific paths — only pre-computed access rules.
///
/// This is the abstraction boundary: the sandbox gets only the fields it needs,
/// not the entire config struct.
// ============================================================================
// PlatformSandbox type alias — single #[cfg] dispatch point
// ============================================================================
/// The sandbox for the current platform.
///
/// On Linux: [`CompositeSandbox`] combining bwrap (namespaces) + Landlock (filesystem ACL).
/// On macOS: [`SeatbeltSandbox`] (sandbox-exec).
/// On other: [`NoopSandbox`] (passthrough).
pub type PlatformSandbox = CompositeSandbox;
pub type PlatformSandbox = SeatbeltSandbox;
pub type PlatformSandbox = NoopSandbox;
// ============================================================================
// NoopSandbox — unsupported platforms or jailer disabled
// ============================================================================
/// Passthrough sandbox that applies no isolation.
///
/// Used on unsupported platforms. The command runs directly.
;