csc-runner 0.5.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.
- csc_runner-0.5.0/.github/SECURITY_ADVISORY_TEMPLATE.md +79 -0
- csc_runner-0.5.0/.github/SECURITY_RELEASE_TEMPLATE.md +39 -0
- csc_runner-0.5.0/.github/dependabot.yml +47 -0
- csc_runner-0.5.0/.github/workflows/ci.yml +36 -0
- csc_runner-0.5.0/.github/workflows/hardened-tests.yml +81 -0
- csc_runner-0.5.0/.github/workflows/release.yml +173 -0
- csc_runner-0.5.0/.gitignore +40 -0
- csc_runner-0.5.0/CHANGELOG.md +78 -0
- csc_runner-0.5.0/CODE_OF_CONDUCT.md +29 -0
- csc_runner-0.5.0/CONTRIBUTING.md +44 -0
- csc_runner-0.5.0/Dockerfile +78 -0
- csc_runner-0.5.0/GOVERNANCE.md +48 -0
- csc_runner-0.5.0/LICENSE +201 -0
- csc_runner-0.5.0/Makefile +23 -0
- csc_runner-0.5.0/PKG-INFO +172 -0
- csc_runner-0.5.0/README.md +146 -0
- csc_runner-0.5.0/SECURITY.md +98 -0
- csc_runner-0.5.0/adapters/claude-code/README.md +3 -0
- csc_runner-0.5.0/adapters/langgraph/README.md +3 -0
- csc_runner-0.5.0/adapters/openai-agents/README.md +3 -0
- csc_runner-0.5.0/csc_runner/__init__.py +1 -0
- csc_runner-0.5.0/csc_runner/approval.py +128 -0
- csc_runner-0.5.0/csc_runner/cli.py +470 -0
- csc_runner-0.5.0/csc_runner/executor.py +1071 -0
- csc_runner-0.5.0/csc_runner/limits.py +109 -0
- csc_runner-0.5.0/csc_runner/models.py +73 -0
- csc_runner-0.5.0/csc_runner/pathutil.py +215 -0
- csc_runner-0.5.0/csc_runner/policy.py +355 -0
- csc_runner-0.5.0/csc_runner/receipts.py +11 -0
- csc_runner-0.5.0/csc_runner/sandbox.py +629 -0
- csc_runner-0.5.0/csc_runner/signing.py +305 -0
- csc_runner-0.5.0/csc_runner/utils.py +17 -0
- csc_runner-0.5.0/docs/canonicalization.md +100 -0
- csc_runner-0.5.0/docs/compatibility-matrix.md +27 -0
- csc_runner-0.5.0/docs/deployment-modes.md +177 -0
- csc_runner-0.5.0/docs/key-management.md +161 -0
- csc_runner-0.5.0/docs/non-goals.md +15 -0
- csc_runner-0.5.0/docs/pic-mapping.md +115 -0
- csc_runner-0.5.0/docs/policy-packs.md +140 -0
- csc_runner-0.5.0/docs/production-readiness-gate.md +97 -0
- csc_runner-0.5.0/docs/production-readiness-plan.md +799 -0
- csc_runner-0.5.0/docs/profiles.md +13 -0
- csc_runner-0.5.0/docs/reason-codes.md +53 -0
- csc_runner-0.5.0/docs/roadmap.md +25 -0
- csc_runner-0.5.0/docs/security-targets.md +67 -0
- csc_runner-0.5.0/docs/spec-v0.1.md +370 -0
- csc_runner-0.5.0/docs/support-matrix.md +81 -0
- csc_runner-0.5.0/docs/threat-model.md +142 -0
- csc_runner-0.5.0/docs/versioning.md +90 -0
- csc_runner-0.5.0/examples/contracts/.gitkeep +0 -0
- csc_runner-0.5.0/examples/contracts/curl-denied.json +31 -0
- csc_runner-0.5.0/examples/contracts/git-status.json +31 -0
- csc_runner-0.5.0/examples/contracts/npm-test.json +31 -0
- csc_runner-0.5.0/examples/policies/.gitkeep +0 -0
- csc_runner-0.5.0/examples/policies/dev-readonly.yaml +32 -0
- csc_runner-0.5.0/examples/policies/dev-test-no-network.yaml +37 -0
- csc_runner-0.5.0/examples/policies/regulated-restricted.yaml +41 -0
- csc_runner-0.5.0/examples/receipts/.gitkeep +0 -0
- csc_runner-0.5.0/examples/receipts/curl-denied.json +12 -0
- csc_runner-0.5.0/examples/receipts/git-status.success.json +21 -0
- csc_runner-0.5.0/pyproject.toml +52 -0
- csc_runner-0.5.0/rfcs/0001-csc-core.md +47 -0
- csc_runner-0.5.0/rfcs/0002-pic-alignment.md +171 -0
- csc_runner-0.5.0/rfcs/RFC_PROCESS.md +78 -0
- csc_runner-0.5.0/rfcs/index.yaml +36 -0
- csc_runner-0.5.0/schemas/.gitkeep +0 -0
- csc_runner-0.5.0/schemas/csc.approval.v0.1.schema.json +81 -0
- csc_runner-0.5.0/schemas/csc.contract.v0.1.schema.json +165 -0
- csc_runner-0.5.0/schemas/csc.execution-receipt.v0.1.schema.json +121 -0
- csc_runner-0.5.0/schemas/csc.policy-decision.v0.1.schema.json +39 -0
- csc_runner-0.5.0/schemas/csc.policy.v0.1.schema.json +131 -0
- csc_runner-0.5.0/scripts/check_schemas.py +40 -0
- csc_runner-0.5.0/tests/__init__.py +0 -0
- csc_runner-0.5.0/tests/conformance/.gitkeep +0 -0
- csc_runner-0.5.0/tests/conformance/README.md +99 -0
- csc_runner-0.5.0/tests/conformance/contracts/invalid.json +331 -0
- csc_runner-0.5.0/tests/conformance/contracts/valid.json +190 -0
- csc_runner-0.5.0/tests/conformance/decisions/decisions.json +930 -0
- csc_runner-0.5.0/tests/conformance/policies/loader.json +46 -0
- csc_runner-0.5.0/tests/conformance/policies/schema.json +187 -0
- csc_runner-0.5.0/tests/conformance/receipts/invalid.json +148 -0
- csc_runner-0.5.0/tests/conformance/receipts/valid.json +113 -0
- csc_runner-0.5.0/tests/fixtures/.gitkeep +0 -0
- csc_runner-0.5.0/tests/fixtures/dev-readonly.yaml +32 -0
- csc_runner-0.5.0/tests/fixtures/git-status.json +31 -0
- csc_runner-0.5.0/tests/helpers.py +31 -0
- csc_runner-0.5.0/tests/test_adversarial.py +469 -0
- csc_runner-0.5.0/tests/test_approval.py +193 -0
- csc_runner-0.5.0/tests/test_cli.py +417 -0
- csc_runner-0.5.0/tests/test_conformance.py +220 -0
- csc_runner-0.5.0/tests/test_executor.py +397 -0
- csc_runner-0.5.0/tests/test_integration_hardened.py +552 -0
- csc_runner-0.5.0/tests/test_limits.py +230 -0
- csc_runner-0.5.0/tests/test_pathutil.py +289 -0
- csc_runner-0.5.0/tests/test_policy.py +315 -0
- csc_runner-0.5.0/tests/test_policy_loading.py +143 -0
- csc_runner-0.5.0/tests/test_receipt_integrity.py +324 -0
- csc_runner-0.5.0/tests/test_sandbox.py +619 -0
- csc_runner-0.5.0/tests/test_schema.py +88 -0
- csc_runner-0.5.0/tests/test_signing.py +319 -0
- csc_runner-0.5.0/tests/test_smoke.py +4 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Security Advisory Template
|
|
2
|
+
|
|
3
|
+
## Summary
|
|
4
|
+
|
|
5
|
+
<!-- One-sentence description of the vulnerability -->
|
|
6
|
+
|
|
7
|
+
## Affected Versions
|
|
8
|
+
|
|
9
|
+
<!-- Which versions are affected? -->
|
|
10
|
+
|
|
11
|
+
- 0.x.y and earlier
|
|
12
|
+
|
|
13
|
+
## Affected Components
|
|
14
|
+
|
|
15
|
+
<!-- Check all that apply -->
|
|
16
|
+
|
|
17
|
+
- [ ] Executor (`csc_runner/executor.py`)
|
|
18
|
+
- [ ] Sandbox (`csc_runner/sandbox.py`)
|
|
19
|
+
- [ ] Signing (`csc_runner/signing.py`)
|
|
20
|
+
- [ ] Approval (`csc_runner/approval.py`)
|
|
21
|
+
- [ ] Policy (`csc_runner/policy.py`)
|
|
22
|
+
- [ ] Path enforcement (`csc_runner/pathutil.py`)
|
|
23
|
+
- [ ] Resource limits (`csc_runner/limits.py`)
|
|
24
|
+
- [ ] CLI (`csc_runner/cli.py`)
|
|
25
|
+
- [ ] Schemas
|
|
26
|
+
- [ ] Dockerfile / container image
|
|
27
|
+
|
|
28
|
+
## Affected Modes
|
|
29
|
+
|
|
30
|
+
- [ ] Local mode
|
|
31
|
+
- [ ] Hardened mode
|
|
32
|
+
- [ ] Both
|
|
33
|
+
|
|
34
|
+
## Severity
|
|
35
|
+
|
|
36
|
+
<!-- Critical / High / Medium / Low — see SECURITY.md for rubric -->
|
|
37
|
+
|
|
38
|
+
## Bounded Production Claim Impact
|
|
39
|
+
|
|
40
|
+
<!-- Does this issue block or weaken the bounded production claim?
|
|
41
|
+
High/critical issues block the claim until resolved.
|
|
42
|
+
Medium issues require an explicit acceptance note. -->
|
|
43
|
+
|
|
44
|
+
- [ ] Blocks bounded production claim
|
|
45
|
+
- [ ] Weakens claim (requires acceptance note)
|
|
46
|
+
- [ ] No impact on claim
|
|
47
|
+
|
|
48
|
+
## Description
|
|
49
|
+
|
|
50
|
+
<!-- Detailed description of the vulnerability, including root cause -->
|
|
51
|
+
|
|
52
|
+
## Impact
|
|
53
|
+
|
|
54
|
+
<!-- What can an attacker do? What is the blast radius? -->
|
|
55
|
+
|
|
56
|
+
## Reproduction
|
|
57
|
+
|
|
58
|
+
<!-- Steps to reproduce, proof of concept, or test case -->
|
|
59
|
+
|
|
60
|
+
## Fix
|
|
61
|
+
|
|
62
|
+
<!-- Description of the fix, PR reference -->
|
|
63
|
+
|
|
64
|
+
## Mitigation
|
|
65
|
+
|
|
66
|
+
<!-- Workarounds available before applying the fix -->
|
|
67
|
+
|
|
68
|
+
## Regression Test
|
|
69
|
+
|
|
70
|
+
<!-- Reference to the regression test added for this vulnerability.
|
|
71
|
+
Required before closing the advisory. -->
|
|
72
|
+
|
|
73
|
+
- Test file: <!-- e.g. tests/test_adversarial.py, tests/test_executor.py -->
|
|
74
|
+
- Test name: <!-- e.g. test_vuln_123_path_traversal_regression -->
|
|
75
|
+
- [ ] Regression test merged
|
|
76
|
+
|
|
77
|
+
## Credit
|
|
78
|
+
|
|
79
|
+
<!-- Reporter attribution (unless they request anonymity) -->
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Security Release Notes Template
|
|
2
|
+
|
|
3
|
+
## Release vX.Y.Z — Security Fix
|
|
4
|
+
|
|
5
|
+
### Security
|
|
6
|
+
|
|
7
|
+
#### [SEVERITY] — Brief title
|
|
8
|
+
|
|
9
|
+
**Advisory:** GHSA-xxxx-xxxx-xxxx
|
|
10
|
+
|
|
11
|
+
**Affected versions:** 0.x.y and earlier
|
|
12
|
+
|
|
13
|
+
**Affected component(s):** <!-- e.g. sandbox, signing, executor -->
|
|
14
|
+
|
|
15
|
+
**Affected mode:** <!-- local / hardened / both -->
|
|
16
|
+
|
|
17
|
+
**Bounded production claim impact:** <!-- blocks claim / weakens claim / no impact -->
|
|
18
|
+
|
|
19
|
+
**Description:**
|
|
20
|
+
|
|
21
|
+
<!-- 2-3 sentence description of the vulnerability and its impact, suitable for public disclosure. Do not include exploitation details beyond what is needed for users to assess their exposure. -->
|
|
22
|
+
|
|
23
|
+
**Fix:**
|
|
24
|
+
|
|
25
|
+
<!-- Brief description of what was changed to fix the vulnerability. -->
|
|
26
|
+
|
|
27
|
+
**Mitigation for users who cannot upgrade immediately:**
|
|
28
|
+
|
|
29
|
+
<!-- Workarounds, if any. "No workaround; upgrade required." if none. -->
|
|
30
|
+
|
|
31
|
+
**Regression test:** <!-- e.g. tests/test_adversarial.py::test_vuln_123 -->
|
|
32
|
+
|
|
33
|
+
**Credit:** <!-- Reporter attribution, or "Reported internally" -->
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
### Other Changes
|
|
38
|
+
|
|
39
|
+
<!-- Non-security changes in this release, if any. -->
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Dependabot configuration
|
|
2
|
+
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates
|
|
3
|
+
#
|
|
4
|
+
# Notes:
|
|
5
|
+
# - Docker entry watches root Dockerfile only. Add entries for subdirectory
|
|
6
|
+
# Dockerfiles if needed later.
|
|
7
|
+
# - If update noise gets high, add groups to batch minor/patch updates.
|
|
8
|
+
|
|
9
|
+
version: 2
|
|
10
|
+
updates:
|
|
11
|
+
# Python dependencies (pip)
|
|
12
|
+
- package-ecosystem: "pip"
|
|
13
|
+
directory: "/"
|
|
14
|
+
schedule:
|
|
15
|
+
interval: "weekly"
|
|
16
|
+
day: "monday"
|
|
17
|
+
commit-message:
|
|
18
|
+
prefix: "deps"
|
|
19
|
+
open-pull-requests-limit: 10
|
|
20
|
+
labels:
|
|
21
|
+
- "dependencies"
|
|
22
|
+
|
|
23
|
+
# GitHub Actions
|
|
24
|
+
- package-ecosystem: "github-actions"
|
|
25
|
+
directory: "/"
|
|
26
|
+
schedule:
|
|
27
|
+
interval: "weekly"
|
|
28
|
+
day: "monday"
|
|
29
|
+
commit-message:
|
|
30
|
+
prefix: "ci"
|
|
31
|
+
open-pull-requests-limit: 5
|
|
32
|
+
labels:
|
|
33
|
+
- "dependencies"
|
|
34
|
+
- "ci"
|
|
35
|
+
|
|
36
|
+
# Docker
|
|
37
|
+
- package-ecosystem: "docker"
|
|
38
|
+
directory: "/"
|
|
39
|
+
schedule:
|
|
40
|
+
interval: "weekly"
|
|
41
|
+
day: "monday"
|
|
42
|
+
commit-message:
|
|
43
|
+
prefix: "deps"
|
|
44
|
+
open-pull-requests-limit: 3
|
|
45
|
+
labels:
|
|
46
|
+
- "dependencies"
|
|
47
|
+
- "docker"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
check:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ["3.11", "3.12"]
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
21
|
+
uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: ${{ matrix.python-version }}
|
|
24
|
+
cache: pip
|
|
25
|
+
|
|
26
|
+
- name: Install dependencies
|
|
27
|
+
run: pip install -e ".[dev]"
|
|
28
|
+
|
|
29
|
+
- name: Lint
|
|
30
|
+
run: ruff check .
|
|
31
|
+
|
|
32
|
+
- name: Format check
|
|
33
|
+
run: ruff format --check .
|
|
34
|
+
|
|
35
|
+
- name: Test
|
|
36
|
+
run: python -m pytest tests/ -v
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
name: Hardened Integration Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, scaffold]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main, scaffold]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
# This workflow runs:
|
|
13
|
+
# 1. Standard tests on Linux (ubuntu-latest) across Python versions.
|
|
14
|
+
# Full platform matrix (Windows, macOS) belongs in ci.yml.
|
|
15
|
+
# 2. Hardened integration tests inside the Docker container.
|
|
16
|
+
# The outer container runs as root with --privileged and AppArmor
|
|
17
|
+
# disabled so bwrap can create namespaces and configure loopback.
|
|
18
|
+
# Running as root is a CI-only requirement — bwrap --unshare-net
|
|
19
|
+
# needs CAP_NET_ADMIN to set up loopback in its network namespace.
|
|
20
|
+
# The product Dockerfile runs as non-root (csc-runner).
|
|
21
|
+
# Network isolation is enforced and tested by bwrap --unshare-net
|
|
22
|
+
# inside the sandbox — the primary hardened-mode boundary.
|
|
23
|
+
#
|
|
24
|
+
# Action versions are not yet pinned to SHA — that is a Stage 3 Step C task.
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
standard-tests:
|
|
28
|
+
name: Standard Tests (Linux)
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
strategy:
|
|
31
|
+
matrix:
|
|
32
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@v4
|
|
35
|
+
|
|
36
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
37
|
+
uses: actions/setup-python@v5
|
|
38
|
+
with:
|
|
39
|
+
python-version: ${{ matrix.python-version }}
|
|
40
|
+
|
|
41
|
+
- name: Install dependencies
|
|
42
|
+
run: pip install -e ".[dev]"
|
|
43
|
+
|
|
44
|
+
- name: Lint
|
|
45
|
+
run: |
|
|
46
|
+
ruff check .
|
|
47
|
+
ruff format --check .
|
|
48
|
+
|
|
49
|
+
- name: Run standard tests
|
|
50
|
+
run: python -m pytest --tb=short -q --ignore=tests/test_integration_hardened.py
|
|
51
|
+
timeout-minutes: 5
|
|
52
|
+
|
|
53
|
+
hardened-tests:
|
|
54
|
+
name: Hardened Integration Tests (Docker)
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
needs: standard-tests
|
|
57
|
+
steps:
|
|
58
|
+
- uses: actions/checkout@v4
|
|
59
|
+
|
|
60
|
+
- name: Build hardened image
|
|
61
|
+
run: docker build -t csc-hardened .
|
|
62
|
+
|
|
63
|
+
- name: Verify sandbox tools available
|
|
64
|
+
run: |
|
|
65
|
+
docker run --rm --entrypoint bwrap csc-hardened --version
|
|
66
|
+
docker run --rm --entrypoint setpriv csc-hardened --version
|
|
67
|
+
docker run --rm --entrypoint prlimit csc-hardened --version
|
|
68
|
+
|
|
69
|
+
- name: Run hardened integration tests
|
|
70
|
+
run: |
|
|
71
|
+
docker run \
|
|
72
|
+
--rm \
|
|
73
|
+
--privileged \
|
|
74
|
+
--security-opt apparmor=unconfined \
|
|
75
|
+
--user 0 \
|
|
76
|
+
--entrypoint python \
|
|
77
|
+
-v ${{ github.workspace }}:/repo:ro \
|
|
78
|
+
-w /app \
|
|
79
|
+
csc-hardened \
|
|
80
|
+
-m pytest /repo/tests/test_integration_hardened.py -v --tb=short
|
|
81
|
+
timeout-minutes: 10
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
# This workflow handles:
|
|
12
|
+
# 1. Build wheel + sdist
|
|
13
|
+
# 2. Dependency audit
|
|
14
|
+
# 3. Generate SBOM from clean wheel install
|
|
15
|
+
# 4. Publish to PyPI (trusted publishing — handles attestations)
|
|
16
|
+
# 5. Sign release artifacts (sigstore) for GitHub release only
|
|
17
|
+
# 6. Create GitHub release with signed artifacts + SBOM
|
|
18
|
+
#
|
|
19
|
+
# Prerequisites:
|
|
20
|
+
# - PyPI trusted publishing configured for this repository
|
|
21
|
+
# (environment: pypi, package URL set)
|
|
22
|
+
# - Repository has GitHub Actions allowed to create releases
|
|
23
|
+
#
|
|
24
|
+
# Action versions are not yet pinned to SHA — that is a follow-up task.
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
build:
|
|
28
|
+
name: Build Distribution
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
steps:
|
|
31
|
+
- uses: actions/checkout@v4
|
|
32
|
+
|
|
33
|
+
- name: Set up Python
|
|
34
|
+
uses: actions/setup-python@v5
|
|
35
|
+
with:
|
|
36
|
+
python-version: "3.11"
|
|
37
|
+
|
|
38
|
+
- name: Install build tools
|
|
39
|
+
run: pip install build
|
|
40
|
+
|
|
41
|
+
- name: Build wheel and sdist
|
|
42
|
+
run: python -m build
|
|
43
|
+
|
|
44
|
+
- name: Upload build artifacts
|
|
45
|
+
uses: actions/upload-artifact@v4
|
|
46
|
+
with:
|
|
47
|
+
name: dist
|
|
48
|
+
path: dist/
|
|
49
|
+
|
|
50
|
+
audit:
|
|
51
|
+
name: Dependency Audit
|
|
52
|
+
runs-on: ubuntu-latest
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@v4
|
|
55
|
+
|
|
56
|
+
- name: Set up Python
|
|
57
|
+
uses: actions/setup-python@v5
|
|
58
|
+
with:
|
|
59
|
+
python-version: "3.11"
|
|
60
|
+
|
|
61
|
+
- name: Install package and audit tool
|
|
62
|
+
run: |
|
|
63
|
+
pip install -e .
|
|
64
|
+
pip install pip-audit
|
|
65
|
+
|
|
66
|
+
- name: Run pip-audit
|
|
67
|
+
run: pip-audit
|
|
68
|
+
|
|
69
|
+
sbom:
|
|
70
|
+
name: Generate SBOM
|
|
71
|
+
runs-on: ubuntu-latest
|
|
72
|
+
needs: build
|
|
73
|
+
steps:
|
|
74
|
+
- name: Set up Python
|
|
75
|
+
uses: actions/setup-python@v5
|
|
76
|
+
with:
|
|
77
|
+
python-version: "3.11"
|
|
78
|
+
|
|
79
|
+
- name: Download build artifacts
|
|
80
|
+
uses: actions/download-artifact@v4
|
|
81
|
+
with:
|
|
82
|
+
name: dist
|
|
83
|
+
path: dist/
|
|
84
|
+
|
|
85
|
+
- name: Install wheel in clean environment
|
|
86
|
+
run: |
|
|
87
|
+
python -m venv sbom-env
|
|
88
|
+
sbom-env/bin/pip install dist/*.whl
|
|
89
|
+
|
|
90
|
+
- name: Generate CycloneDX SBOM
|
|
91
|
+
run: |
|
|
92
|
+
sbom-env/bin/pip install cyclonedx-bom
|
|
93
|
+
sbom-env/bin/cyclonedx-py environment \
|
|
94
|
+
--output sbom.json \
|
|
95
|
+
--output-format json
|
|
96
|
+
|
|
97
|
+
- name: Upload SBOM
|
|
98
|
+
uses: actions/upload-artifact@v4
|
|
99
|
+
with:
|
|
100
|
+
name: sbom
|
|
101
|
+
path: sbom.json
|
|
102
|
+
|
|
103
|
+
publish-pypi:
|
|
104
|
+
name: Publish to PyPI
|
|
105
|
+
runs-on: ubuntu-latest
|
|
106
|
+
needs: [build, audit]
|
|
107
|
+
environment:
|
|
108
|
+
name: pypi
|
|
109
|
+
url: https://pypi.org/p/csc-runner
|
|
110
|
+
permissions:
|
|
111
|
+
id-token: write
|
|
112
|
+
steps:
|
|
113
|
+
- name: Download build artifacts
|
|
114
|
+
uses: actions/download-artifact@v4
|
|
115
|
+
with:
|
|
116
|
+
name: dist
|
|
117
|
+
path: dist/
|
|
118
|
+
|
|
119
|
+
- name: Publish to PyPI
|
|
120
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
121
|
+
with:
|
|
122
|
+
packages-dir: dist/
|
|
123
|
+
|
|
124
|
+
sign-for-release:
|
|
125
|
+
name: Sign Artifacts for GitHub Release
|
|
126
|
+
runs-on: ubuntu-latest
|
|
127
|
+
needs: build
|
|
128
|
+
permissions:
|
|
129
|
+
id-token: write
|
|
130
|
+
steps:
|
|
131
|
+
- name: Download build artifacts
|
|
132
|
+
uses: actions/download-artifact@v4
|
|
133
|
+
with:
|
|
134
|
+
name: dist
|
|
135
|
+
path: dist/
|
|
136
|
+
|
|
137
|
+
- name: Sign with sigstore
|
|
138
|
+
uses: sigstore/gh-action-sigstore-python@v3
|
|
139
|
+
with:
|
|
140
|
+
inputs: ./dist/*
|
|
141
|
+
|
|
142
|
+
- name: Upload signed artifacts
|
|
143
|
+
uses: actions/upload-artifact@v4
|
|
144
|
+
with:
|
|
145
|
+
name: dist-signed
|
|
146
|
+
path: dist/
|
|
147
|
+
|
|
148
|
+
github-release:
|
|
149
|
+
name: Create GitHub Release
|
|
150
|
+
runs-on: ubuntu-latest
|
|
151
|
+
needs: [publish-pypi, sign-for-release, sbom]
|
|
152
|
+
permissions:
|
|
153
|
+
contents: write
|
|
154
|
+
steps:
|
|
155
|
+
- name: Download signed artifacts
|
|
156
|
+
uses: actions/download-artifact@v4
|
|
157
|
+
with:
|
|
158
|
+
name: dist-signed
|
|
159
|
+
path: dist/
|
|
160
|
+
|
|
161
|
+
- name: Download SBOM
|
|
162
|
+
uses: actions/download-artifact@v4
|
|
163
|
+
with:
|
|
164
|
+
name: sbom
|
|
165
|
+
path: .
|
|
166
|
+
|
|
167
|
+
- name: Create release
|
|
168
|
+
uses: softprops/action-gh-release@v2
|
|
169
|
+
with:
|
|
170
|
+
files: |
|
|
171
|
+
dist/*
|
|
172
|
+
sbom.json
|
|
173
|
+
generate_release_notes: true
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.egg-info/
|
|
6
|
+
*.egg
|
|
7
|
+
dist/
|
|
8
|
+
build/
|
|
9
|
+
.eggs/
|
|
10
|
+
|
|
11
|
+
# Virtual environments
|
|
12
|
+
.venv/
|
|
13
|
+
venv/
|
|
14
|
+
ENV/
|
|
15
|
+
.python-version
|
|
16
|
+
|
|
17
|
+
# Testing
|
|
18
|
+
.pytest_cache/
|
|
19
|
+
htmlcov/
|
|
20
|
+
.coverage
|
|
21
|
+
.coverage.*
|
|
22
|
+
coverage.xml
|
|
23
|
+
|
|
24
|
+
# Linting / type checking
|
|
25
|
+
.ruff_cache/
|
|
26
|
+
.mypy_cache/
|
|
27
|
+
|
|
28
|
+
# IDE
|
|
29
|
+
.idea/
|
|
30
|
+
.vscode/
|
|
31
|
+
*.swp
|
|
32
|
+
*.swo
|
|
33
|
+
|
|
34
|
+
# OS
|
|
35
|
+
.DS_Store
|
|
36
|
+
Thumbs.db
|
|
37
|
+
|
|
38
|
+
# CSC runtime output (root-level only, not test fixtures)
|
|
39
|
+
/out/
|
|
40
|
+
/receipts/
|
|
@@ -0,0 +1,78 @@
|
|
|
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
|
+
## [0.5.0] - 2026-03-24
|
|
9
|
+
|
|
10
|
+
### Added — Stage 1a (Protocol Complete)
|
|
11
|
+
|
|
12
|
+
- Conformance test suite with golden fixtures (contracts, decisions, receipts)
|
|
13
|
+
- Policy schema validation on load (`policy_schema_version` field)
|
|
14
|
+
- Structured reason codes in PolicyDecision (ALLOW, COMMAND_NOT_ALLOWED, ARGV_PREFIX_DENIED, etc.)
|
|
15
|
+
- Receipt field semantics: policy provenance, runner provenance, blocked vs failed distinction
|
|
16
|
+
- Conditional receipt schema: success/failed require exit_code, stdout_hash, stderr_hash
|
|
17
|
+
- Security targets, support matrix, compatibility matrix, canonicalization spec
|
|
18
|
+
- PIC alignment RFC-0002 and mapping document
|
|
19
|
+
- Reason-code registry (`docs/reason-codes.md`)
|
|
20
|
+
|
|
21
|
+
### Added — Stage 1b (Hardened Defaults)
|
|
22
|
+
|
|
23
|
+
- Resource exhaustion controls (`csc_runner/limits.py`): command count, argv size, pipeline depth, justification length, output capture caps
|
|
24
|
+
- Filesystem path enforcement (`csc_runner/pathutil.py`): realpath resolution, symlink rejection, mixed-flavour fail-closed, glob prefix extraction
|
|
25
|
+
- Popen-based executor with capped output capture, OS-pipe pipelines, ownership-based cleanup
|
|
26
|
+
- Receipt integrity: hash-bound to contract, deterministic structure, truncation flags (stdout_truncated, stderr_truncated)
|
|
27
|
+
- Adversarial test suite: shell escapes, path tricks, env leakage, timeout abuse, Unicode edge cases
|
|
28
|
+
- Emergency deny-all policy mode
|
|
29
|
+
- Policy provenance in receipts (policy_sha256, policy_schema_version)
|
|
30
|
+
|
|
31
|
+
### Added — Stage 2 (First Hardened Mode)
|
|
32
|
+
|
|
33
|
+
- Approval artifacts (`csc_runner/approval.py`): hash-bound to contract_sha256, expiry enforcement, temporal ordering, schema validation
|
|
34
|
+
- Ed25519 receipt signing (`csc_runner/signing.py`): standalone `cryptography` library, CSC-native PublicKeyResolver protocol, authenticated signing metadata
|
|
35
|
+
- Linux sandbox backend (`csc_runner/sandbox.py`): bubblewrap + setpriv + prlimit launcher, kernel-enforced namespace isolation, advisory command blocking
|
|
36
|
+
- Hardened CLI: `--mode hardened`, `--sign`, `--signing-key`, `--key-id`, `--approval`, `--sandbox-debug`
|
|
37
|
+
- `verify-receipt` CLI command
|
|
38
|
+
- Executor integration: approval before sandbox, signing after execution, fail-closed on signing failure in hardened mode
|
|
39
|
+
- In-memory approval consumption store with replay prevention (single-execution scope)
|
|
40
|
+
- Dockerfile for hardened mode container image
|
|
41
|
+
- End-to-end hardened integration tests (19 tests): filesystem boundaries, network isolation, no_new_privs, signed receipt verification
|
|
42
|
+
- `docs/deployment-modes.md`: local vs hardened, security claims per mode
|
|
43
|
+
- `docs/key-management.md`: rotation, revocation, CSC/PIC dependency boundary
|
|
44
|
+
- `docs/policy-packs.md`: organizational conventions, not engine features
|
|
45
|
+
- `cryptography` added as runtime dependency
|
|
46
|
+
|
|
47
|
+
### Added — Stage 3 (Production Candidate)
|
|
48
|
+
|
|
49
|
+
- Production readiness gate (`docs/production-readiness-gate.md`): formal checklist for bounded production claim
|
|
50
|
+
- CI workflow for hardened integration tests (`.github/workflows/hardened-tests.yml`): Docker build, privileged container, bwrap `--unshare-net` for network isolation
|
|
51
|
+
- Release workflow (`.github/workflows/release.yml`): sigstore signing, SBOM generation, PyPI trusted publishing
|
|
52
|
+
- Security policy (`SECURITY.md`): severity rubric, SLA targets, disclosure process
|
|
53
|
+
- Security advisory template (`.github/SECURITY_ADVISORY_TEMPLATE.md`)
|
|
54
|
+
- Security release notes template (`.github/SECURITY_RELEASE_TEMPLATE.md`)
|
|
55
|
+
- Dependabot configuration (`.github/dependabot.yml`): pip, GitHub Actions, Docker
|
|
56
|
+
- Threat model (`docs/threat-model.md`): trust boundaries, 7 threat classes, known unsafe conditions
|
|
57
|
+
- README updated to reflect hardened mode availability and bounded production claim
|
|
58
|
+
- Branch protection on main: required status checks, PR review, no force push
|
|
59
|
+
- Dependabot alerts, security updates, and private vulnerability reporting enabled
|
|
60
|
+
|
|
61
|
+
### Changed
|
|
62
|
+
|
|
63
|
+
- Version bumped from 0.1.0 to 0.5.0 to reflect protocol maturity
|
|
64
|
+
- Receipt schema: conditional rules require exit_code/stdout_hash/stderr_hash for success/failed status
|
|
65
|
+
- Executor signature: `run_contract()` accepts mode, approval, signing, and sandbox config
|
|
66
|
+
- CLI: `run` command accepts hardened mode flags; `check` command unchanged
|
|
67
|
+
|
|
68
|
+
## [0.1.0] - 2026-03-20
|
|
69
|
+
|
|
70
|
+
### Added
|
|
71
|
+
|
|
72
|
+
- Initial project scaffold
|
|
73
|
+
- CSC v0.1 specification draft
|
|
74
|
+
- JSON Schemas for CommandContract, PolicyDecision, ExecutionReceipt
|
|
75
|
+
- Reference Python runner (`csc-runner`)
|
|
76
|
+
- YAML policy profiles: dev-readonly, dev-test-no-network, regulated-restricted
|
|
77
|
+
- Example contracts and receipts
|
|
78
|
+
- RFC process with artifact integrity rules
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our pledge
|
|
4
|
+
|
|
5
|
+
We are committed to providing a friendly, safe, and welcoming environment for all contributors, regardless of experience level, gender identity, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
|
|
6
|
+
|
|
7
|
+
## Our standards
|
|
8
|
+
|
|
9
|
+
Examples of behavior that contributes to a positive environment:
|
|
10
|
+
|
|
11
|
+
- Using welcoming and inclusive language
|
|
12
|
+
- Being respectful of differing viewpoints and experiences
|
|
13
|
+
- Gracefully accepting constructive criticism
|
|
14
|
+
- Focusing on what is best for the community
|
|
15
|
+
|
|
16
|
+
Examples of unacceptable behavior:
|
|
17
|
+
|
|
18
|
+
- Trolling, insulting or derogatory comments, and personal or political attacks
|
|
19
|
+
- Public or private harassment
|
|
20
|
+
- Publishing others' private information without explicit permission
|
|
21
|
+
- Other conduct which could reasonably be considered inappropriate in a professional setting
|
|
22
|
+
|
|
23
|
+
## Enforcement
|
|
24
|
+
|
|
25
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project maintainers. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances.
|
|
26
|
+
|
|
27
|
+
## Attribution
|
|
28
|
+
|
|
29
|
+
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Contributing to CSC
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to the Command Scope Contract project.
|
|
4
|
+
|
|
5
|
+
## Getting started
|
|
6
|
+
|
|
7
|
+
1. Fork the repository
|
|
8
|
+
2. Clone your fork
|
|
9
|
+
3. Install dev dependencies: `pip install -e ".[dev]"`
|
|
10
|
+
4. Create a feature branch: `git checkout -b my-feature`
|
|
11
|
+
5. Make your changes
|
|
12
|
+
6. Run checks: `make check`
|
|
13
|
+
7. Submit a pull request
|
|
14
|
+
|
|
15
|
+
## Where to start
|
|
16
|
+
|
|
17
|
+
- Read the spec: `docs/spec-v0.1.md`
|
|
18
|
+
- Review the schemas: `schemas/`
|
|
19
|
+
- Look at example contracts: `examples/contracts/`
|
|
20
|
+
|
|
21
|
+
## Code style
|
|
22
|
+
|
|
23
|
+
This project uses [ruff](https://docs.astral.sh/ruff/) for linting and formatting.
|
|
24
|
+
|
|
25
|
+
- `make lint` — check for issues
|
|
26
|
+
- `make fmt` — auto-format
|
|
27
|
+
|
|
28
|
+
## Tests
|
|
29
|
+
|
|
30
|
+
Run the test suite with:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
make test
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
All pull requests must pass CI before merging.
|
|
37
|
+
|
|
38
|
+
## RFCs
|
|
39
|
+
|
|
40
|
+
For changes to the protocol or significant design decisions, follow the RFC process described in `rfcs/RFC_PROCESS.md`.
|
|
41
|
+
|
|
42
|
+
## Code of conduct
|
|
43
|
+
|
|
44
|
+
Please follow our [Code of Conduct](CODE_OF_CONDUCT.md).
|