proc-jail 0.2.0__tar.gz
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.
- proc_jail-0.2.0/.github/workflows/ci.yml +145 -0
- proc_jail-0.2.0/.github/workflows/release.yml +164 -0
- proc_jail-0.2.0/.gitignore +16 -0
- proc_jail-0.2.0/CHANGELOG.md +57 -0
- proc_jail-0.2.0/Cargo.lock +364 -0
- proc_jail-0.2.0/Cargo.toml +30 -0
- proc_jail-0.2.0/LICENSE-APACHE +190 -0
- proc_jail-0.2.0/LICENSE-MIT +21 -0
- proc_jail-0.2.0/PKG-INFO +304 -0
- proc_jail-0.2.0/README.md +275 -0
- proc_jail-0.2.0/SECURITY.md +135 -0
- proc_jail-0.2.0/docs/design-decisions.md +85 -0
- proc_jail-0.2.0/docs/risky-binaries.md +131 -0
- proc_jail-0.2.0/docs/windows.md +86 -0
- proc_jail-0.2.0/proc_jail/__init__.py +27 -0
- proc_jail-0.2.0/proc_jail/__init__.pyi +282 -0
- proc_jail-0.2.0/proc_jail/py.typed +0 -0
- proc_jail-0.2.0/proc_jail_spec_v3.md +1078 -0
- proc_jail-0.2.0/pyproject.toml +40 -0
- proc_jail-0.2.0/python/Cargo.toml +18 -0
- proc_jail-0.2.0/python/README.md +198 -0
- proc_jail-0.2.0/python/src/lib.rs +645 -0
- proc_jail-0.2.0/python/tests/test_proc_jail.py +414 -0
- proc_jail-0.2.0/scripts/check_versions.py +54 -0
- proc_jail-0.2.0/src/arg_parser.rs +197 -0
- proc_jail-0.2.0/src/arg_rules.rs +305 -0
- proc_jail-0.2.0/src/canonical.rs +101 -0
- proc_jail-0.2.0/src/cwd_policy.rs +213 -0
- proc_jail-0.2.0/src/double_dash.rs +164 -0
- proc_jail-0.2.0/src/env_policy.rs +246 -0
- proc_jail-0.2.0/src/error.rs +145 -0
- proc_jail-0.2.0/src/file_check.rs +140 -0
- proc_jail-0.2.0/src/lib.rs +91 -0
- proc_jail-0.2.0/src/limits.rs +57 -0
- proc_jail-0.2.0/src/output.rs +38 -0
- proc_jail-0.2.0/src/policy.rs +357 -0
- proc_jail-0.2.0/src/prepared.rs +433 -0
- proc_jail-0.2.0/src/request.rs +75 -0
- proc_jail-0.2.0/src/risky.rs +209 -0
- proc_jail-0.2.0/tests/adversarial.rs +800 -0
- proc_jail-0.2.0/tests/integration.rs +299 -0
- proc_jail-0.2.0/tests/launch.rs +335 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
env:
|
|
13
|
+
CARGO_TERM_COLOR: always
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
versions:
|
|
17
|
+
name: Package versions
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.11"
|
|
24
|
+
- run: python scripts/check_versions.py
|
|
25
|
+
|
|
26
|
+
audit:
|
|
27
|
+
name: Dependency audit
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v4
|
|
31
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
32
|
+
- name: Generate Cargo.lock
|
|
33
|
+
run: cargo generate-lockfile
|
|
34
|
+
env:
|
|
35
|
+
CARGO_RESOLVER_INCOMPATIBLE_RUST_VERSIONS: fallback
|
|
36
|
+
- uses: rustsec/audit-check@v2
|
|
37
|
+
with:
|
|
38
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
39
|
+
|
|
40
|
+
test:
|
|
41
|
+
name: Test (${{ matrix.os }}, Rust ${{ matrix.rust }})
|
|
42
|
+
runs-on: ${{ matrix.os }}
|
|
43
|
+
strategy:
|
|
44
|
+
fail-fast: false
|
|
45
|
+
matrix:
|
|
46
|
+
os: [ubuntu-latest, macos-latest]
|
|
47
|
+
rust: [stable, "1.75"] # stable + MSRV
|
|
48
|
+
steps:
|
|
49
|
+
- uses: actions/checkout@v4
|
|
50
|
+
# Stable cargo resolves the lockfile; MSRV-aware fallback keeps
|
|
51
|
+
# dependencies compatible with rust-version on the MSRV job.
|
|
52
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
53
|
+
- uses: dtolnay/rust-toolchain@master
|
|
54
|
+
with:
|
|
55
|
+
toolchain: ${{ matrix.rust }}
|
|
56
|
+
- uses: Swatinem/rust-cache@v2
|
|
57
|
+
- name: Generate Cargo.lock
|
|
58
|
+
run: cargo +stable generate-lockfile
|
|
59
|
+
env:
|
|
60
|
+
CARGO_RESOLVER_INCOMPATIBLE_RUST_VERSIONS: fallback
|
|
61
|
+
- run: cargo +${{ matrix.rust }} test --features tracing
|
|
62
|
+
|
|
63
|
+
clippy:
|
|
64
|
+
name: Clippy
|
|
65
|
+
runs-on: ubuntu-latest
|
|
66
|
+
steps:
|
|
67
|
+
- uses: actions/checkout@v4
|
|
68
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
69
|
+
with:
|
|
70
|
+
components: clippy
|
|
71
|
+
- uses: Swatinem/rust-cache@v2
|
|
72
|
+
- run: cargo clippy --features tracing -- -D warnings
|
|
73
|
+
|
|
74
|
+
fmt:
|
|
75
|
+
name: Format
|
|
76
|
+
runs-on: ubuntu-latest
|
|
77
|
+
steps:
|
|
78
|
+
- uses: actions/checkout@v4
|
|
79
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
80
|
+
with:
|
|
81
|
+
components: rustfmt
|
|
82
|
+
- run: cargo fmt --check
|
|
83
|
+
|
|
84
|
+
docs:
|
|
85
|
+
name: Documentation
|
|
86
|
+
runs-on: ubuntu-latest
|
|
87
|
+
steps:
|
|
88
|
+
- uses: actions/checkout@v4
|
|
89
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
90
|
+
- uses: Swatinem/rust-cache@v2
|
|
91
|
+
- run: cargo doc --no-deps
|
|
92
|
+
env:
|
|
93
|
+
RUSTDOCFLAGS: -D warnings
|
|
94
|
+
|
|
95
|
+
python:
|
|
96
|
+
name: Python Bindings
|
|
97
|
+
runs-on: ubuntu-latest
|
|
98
|
+
steps:
|
|
99
|
+
- uses: actions/checkout@v4
|
|
100
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
101
|
+
- uses: actions/setup-python@v5
|
|
102
|
+
with:
|
|
103
|
+
python-version: "3.11"
|
|
104
|
+
- name: Install maturin
|
|
105
|
+
run: pip install maturin
|
|
106
|
+
- name: Build Python wheel
|
|
107
|
+
working-directory: python
|
|
108
|
+
run: maturin build
|
|
109
|
+
- name: Test imports
|
|
110
|
+
run: |
|
|
111
|
+
WHEEL=$(find target/wheels -maxdepth 1 -name '*.whl' -print -quit)
|
|
112
|
+
pip install "$WHEEL"
|
|
113
|
+
python -c "
|
|
114
|
+
from proc_jail import (
|
|
115
|
+
ProcPolicyBuilder, ProcRequest, ArgRules,
|
|
116
|
+
InjectDoubleDash, RiskyBinPolicy, RiskCategory,
|
|
117
|
+
PreparedCommand, Output, ProcPolicy
|
|
118
|
+
)
|
|
119
|
+
print('All imports OK')
|
|
120
|
+
"
|
|
121
|
+
|
|
122
|
+
python-tests:
|
|
123
|
+
name: Python Tests (${{ matrix.os }}, ${{ matrix.python }})
|
|
124
|
+
runs-on: ${{ matrix.os }}
|
|
125
|
+
strategy:
|
|
126
|
+
fail-fast: false
|
|
127
|
+
matrix:
|
|
128
|
+
os: [ubuntu-latest, macos-latest]
|
|
129
|
+
python: ["3.8", "3.15"]
|
|
130
|
+
steps:
|
|
131
|
+
- uses: actions/checkout@v4
|
|
132
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
133
|
+
- uses: actions/setup-python@v5
|
|
134
|
+
with:
|
|
135
|
+
python-version: ${{ matrix.python }}
|
|
136
|
+
- name: Install dependencies
|
|
137
|
+
run: pip install "maturin>=1,<2" pytest
|
|
138
|
+
- name: Build and install
|
|
139
|
+
run: |
|
|
140
|
+
cd python && maturin build
|
|
141
|
+
WHEEL=$(find ../target/wheels -maxdepth 1 -name '*.whl' -print -quit)
|
|
142
|
+
pip install "$WHEEL"
|
|
143
|
+
- name: Run Python tests
|
|
144
|
+
working-directory: python
|
|
145
|
+
run: pytest tests/ -v --tb=short
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
env:
|
|
12
|
+
CARGO_TERM_COLOR: always
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
preflight:
|
|
16
|
+
name: Release preflight
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
- uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: "3.15"
|
|
23
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
24
|
+
- name: Verify tag and package versions
|
|
25
|
+
run: python scripts/check_versions.py --tag "$GITHUB_REF_NAME"
|
|
26
|
+
- name: Test workspace
|
|
27
|
+
run: cargo test --all --all-features
|
|
28
|
+
- name: Verify crates.io package
|
|
29
|
+
run: cargo publish --dry-run
|
|
30
|
+
|
|
31
|
+
build-rust:
|
|
32
|
+
name: Build crates.io package
|
|
33
|
+
needs: preflight
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
steps:
|
|
36
|
+
- uses: actions/checkout@v4
|
|
37
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
38
|
+
- run: cargo package
|
|
39
|
+
- uses: actions/upload-artifact@v4
|
|
40
|
+
with:
|
|
41
|
+
name: rust-package
|
|
42
|
+
path: target/package/*.crate
|
|
43
|
+
if-no-files-found: error
|
|
44
|
+
|
|
45
|
+
build-python:
|
|
46
|
+
name: Build Python wheel (${{ matrix.target }})
|
|
47
|
+
needs: preflight
|
|
48
|
+
runs-on: ${{ matrix.os }}
|
|
49
|
+
strategy:
|
|
50
|
+
fail-fast: false
|
|
51
|
+
matrix:
|
|
52
|
+
include:
|
|
53
|
+
- os: ubuntu-24.04
|
|
54
|
+
target: x86_64
|
|
55
|
+
manylinux: auto
|
|
56
|
+
- os: ubuntu-24.04-arm
|
|
57
|
+
target: aarch64
|
|
58
|
+
manylinux: auto
|
|
59
|
+
- os: macos-15-intel
|
|
60
|
+
target: x86_64
|
|
61
|
+
manylinux: off
|
|
62
|
+
- os: macos-15
|
|
63
|
+
target: aarch64
|
|
64
|
+
manylinux: off
|
|
65
|
+
steps:
|
|
66
|
+
- uses: actions/checkout@v4
|
|
67
|
+
- uses: actions/setup-python@v5
|
|
68
|
+
with:
|
|
69
|
+
python-version: "3.15"
|
|
70
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
71
|
+
- name: Build wheel
|
|
72
|
+
uses: PyO3/maturin-action@v1
|
|
73
|
+
with:
|
|
74
|
+
working-directory: python
|
|
75
|
+
target: ${{ matrix.target }}
|
|
76
|
+
args: --release --out dist
|
|
77
|
+
manylinux: ${{ matrix.manylinux }}
|
|
78
|
+
- name: Smoke-test wheel
|
|
79
|
+
run: |
|
|
80
|
+
python -m pip install --force-reinstall python/dist/*.whl
|
|
81
|
+
python -c "import proc_jail, sys; assert proc_jail.__version__ == sys.argv[1]" "${GITHUB_REF_NAME#v}"
|
|
82
|
+
- uses: actions/upload-artifact@v4
|
|
83
|
+
with:
|
|
84
|
+
name: python-wheel-${{ matrix.target }}-${{ matrix.os }}
|
|
85
|
+
path: python/dist/*.whl
|
|
86
|
+
if-no-files-found: error
|
|
87
|
+
|
|
88
|
+
build-sdist:
|
|
89
|
+
name: Build Python source distribution
|
|
90
|
+
needs: preflight
|
|
91
|
+
runs-on: ubuntu-latest
|
|
92
|
+
steps:
|
|
93
|
+
- uses: actions/checkout@v4
|
|
94
|
+
- uses: actions/setup-python@v5
|
|
95
|
+
with:
|
|
96
|
+
python-version: "3.15"
|
|
97
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
98
|
+
- run: python -m pip install "maturin>=1,<2" twine
|
|
99
|
+
- run: maturin sdist --manifest-path python/Cargo.toml --out python/dist
|
|
100
|
+
- run: twine check python/dist/*
|
|
101
|
+
- uses: actions/upload-artifact@v4
|
|
102
|
+
with:
|
|
103
|
+
name: python-sdist
|
|
104
|
+
path: python/dist/*.tar.gz
|
|
105
|
+
if-no-files-found: error
|
|
106
|
+
|
|
107
|
+
validate-python:
|
|
108
|
+
name: Validate Python artifacts
|
|
109
|
+
needs: [build-python, build-sdist]
|
|
110
|
+
runs-on: ubuntu-latest
|
|
111
|
+
steps:
|
|
112
|
+
- uses: actions/setup-python@v5
|
|
113
|
+
with:
|
|
114
|
+
python-version: "3.15"
|
|
115
|
+
- uses: actions/download-artifact@v4
|
|
116
|
+
with:
|
|
117
|
+
pattern: python-*
|
|
118
|
+
path: dist
|
|
119
|
+
merge-multiple: true
|
|
120
|
+
- run: python -m pip install twine
|
|
121
|
+
- run: twine check dist/*
|
|
122
|
+
|
|
123
|
+
publish-rust:
|
|
124
|
+
name: Publish to crates.io
|
|
125
|
+
needs: [build-rust, validate-python]
|
|
126
|
+
runs-on: ubuntu-latest
|
|
127
|
+
steps:
|
|
128
|
+
- uses: actions/checkout@v4
|
|
129
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
130
|
+
- run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
|
131
|
+
|
|
132
|
+
publish-python:
|
|
133
|
+
name: Publish to PyPI
|
|
134
|
+
needs: [build-rust, validate-python]
|
|
135
|
+
runs-on: ubuntu-latest
|
|
136
|
+
steps:
|
|
137
|
+
- uses: actions/download-artifact@v4
|
|
138
|
+
with:
|
|
139
|
+
pattern: python-*
|
|
140
|
+
path: dist
|
|
141
|
+
merge-multiple: true
|
|
142
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
143
|
+
with:
|
|
144
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
145
|
+
|
|
146
|
+
github-release:
|
|
147
|
+
name: Create GitHub release
|
|
148
|
+
needs: [publish-rust, publish-python]
|
|
149
|
+
runs-on: ubuntu-latest
|
|
150
|
+
permissions:
|
|
151
|
+
contents: write
|
|
152
|
+
steps:
|
|
153
|
+
- uses: actions/checkout@v4
|
|
154
|
+
- uses: actions/download-artifact@v4
|
|
155
|
+
with:
|
|
156
|
+
path: dist
|
|
157
|
+
merge-multiple: true
|
|
158
|
+
- name: Generate checksums
|
|
159
|
+
working-directory: dist
|
|
160
|
+
run: sha256sum -- * > SHA256SUMS
|
|
161
|
+
- name: Create release
|
|
162
|
+
env:
|
|
163
|
+
GH_TOKEN: ${{ github.token }}
|
|
164
|
+
run: gh release create "$GITHUB_REF_NAME" dist/* --verify-tag --generate-notes
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.2.0] - 2026-10-25
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `PreparedCommand::wrap_with()` to launch the validated command through another program (for example an OS sandbox launcher), plus `launch_program()`/`launch_args()` accessors
|
|
15
|
+
- `PreparedCommand::with_launch_env()` and `launch_env()` for environment variables added after the env policy
|
|
16
|
+
- Python bindings for `wrap_with`, `with_launch_env`, `launch_program`, `launch_args`
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Commands are spawned in their own process group, and the whole group is killed on timeout or output limits
|
|
21
|
+
- An output limit on one stream no longer waits for the other stream to close
|
|
22
|
+
- Processes the command leaves running in its group are killed when it exits
|
|
23
|
+
- The timeout now also covers waiting for exit after the output pipes close
|
|
24
|
+
- Dropping the future returned by `spawn()` kills the command's process group
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- `spawn_sync()` no longer deadlocks when called from a current-thread Tokio runtime
|
|
29
|
+
- Python releases now include `abi3` wheels for Linux and macOS on x86-64 and ARM64, plus a source distribution
|
|
30
|
+
|
|
31
|
+
### Security
|
|
32
|
+
|
|
33
|
+
- Upgraded PyO3 to 0.29.3 to address RUSTSEC-2026-0176 and RUSTSEC-2026-0177
|
|
34
|
+
|
|
35
|
+
## [0.1.0] - 2026-01-11
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
|
|
39
|
+
- Initial release
|
|
40
|
+
- Core `ProcPolicy` with builder pattern
|
|
41
|
+
- `ArgRules` for argument validation
|
|
42
|
+
- Flag allowlist
|
|
43
|
+
- Subcommand pinning
|
|
44
|
+
- Double-dash injection
|
|
45
|
+
- `EnvPolicy` with ALWAYS_STRIP protection
|
|
46
|
+
- `CwdPolicy` for working directory control
|
|
47
|
+
- `ResourceLimits` (timeout, stdout/stderr caps)
|
|
48
|
+
- `RiskyBinPolicy` for shells, interpreters, spawners, privilege tools
|
|
49
|
+
- Path canonicalization with symlink resolution
|
|
50
|
+
- Python bindings via PyO3
|
|
51
|
+
|
|
52
|
+
### Security
|
|
53
|
+
|
|
54
|
+
- No shell interpretation (execve-style only)
|
|
55
|
+
- Absolute paths required
|
|
56
|
+
- Fail-closed design
|
|
57
|
+
- Environment variable sanitization
|