cage-ai 0.1.1__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.
- cage_ai-0.1.1/.github/CODEOWNERS +14 -0
- cage_ai-0.1.1/.github/workflows/build.yml +75 -0
- cage_ai-0.1.1/.github/workflows/release.yml +212 -0
- cage_ai-0.1.1/.gitignore +48 -0
- cage_ai-0.1.1/.python-version +1 -0
- cage_ai-0.1.1/Cargo.lock +888 -0
- cage_ai-0.1.1/Cargo.toml +39 -0
- cage_ai-0.1.1/DEPLOY.md +181 -0
- cage_ai-0.1.1/LICENSE +202 -0
- cage_ai-0.1.1/PATENT_PLEDGE.md +60 -0
- cage_ai-0.1.1/PKG-INFO +213 -0
- cage_ai-0.1.1/README.md +175 -0
- cage_ai-0.1.1/SECURITY.md +70 -0
- cage_ai-0.1.1/crates/cage-core/Cargo.toml +30 -0
- cage_ai-0.1.1/crates/cage-core/src/error.rs +59 -0
- cage_ai-0.1.1/crates/cage-core/src/gate.rs +2397 -0
- cage_ai-0.1.1/crates/cage-core/src/lib.rs +34 -0
- cage_ai-0.1.1/crates/cage-core/src/operator.rs +209 -0
- cage_ai-0.1.1/crates/cage-core/src/release.rs +493 -0
- cage_ai-0.1.1/crates/cage-core/src/transport.rs +616 -0
- cage_ai-0.1.1/crates/cage-core/src/vault.rs +865 -0
- cage_ai-0.1.1/examples/agent_broker_adapter.py +94 -0
- cage_ai-0.1.1/examples/broker_demo.py +378 -0
- cage_ai-0.1.1/examples/env_migration_demo.py +234 -0
- cage_ai-0.1.1/examples/showcase.sh +26 -0
- cage_ai-0.1.1/pyproject.toml +68 -0
- cage_ai-0.1.1/python/cage/__init__.py +75 -0
- cage_ai-0.1.1/python/cage/adapters.py +164 -0
- cage_ai-0.1.1/python/cage/broker.py +663 -0
- cage_ai-0.1.1/python/cage/core/__init__.py +18 -0
- cage_ai-0.1.1/python/cage/core/gate.py +688 -0
- cage_ai-0.1.1/python/cage/exceptions.py +20 -0
- cage_ai-0.1.1/python/cage/token.py +77 -0
- cage_ai-0.1.1/python/cage/vault.py +830 -0
- cage_ai-0.1.1/rust-toolchain.toml +15 -0
- cage_ai-0.1.1/src/lib.rs +452 -0
- cage_ai-0.1.1/tests/test_adapters.py +133 -0
- cage_ai-0.1.1/tests/test_audit_anchor.py +80 -0
- cage_ai-0.1.1/tests/test_authority_bypass_closed.py +119 -0
- cage_ai-0.1.1/tests/test_broker_client.py +407 -0
- cage_ai-0.1.1/tests/test_broker_launcher.py +364 -0
- cage_ai-0.1.1/tests/test_gate.py +144 -0
- cage_ai-0.1.1/tests/test_lazy_core_import.py +86 -0
- cage_ai-0.1.1/tests/test_public_api.py +79 -0
- cage_ai-0.1.1/tests/test_silent_downgrades.py +62 -0
- cage_ai-0.1.1/tests/test_smoke.py +687 -0
- cage_ai-0.1.1/uv.lock +372 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# CODEOWNERS for cage
|
|
2
|
+
#
|
|
3
|
+
# The load-bearing crypto surface. Takes effect once branch protection
|
|
4
|
+
# requires code-owner review.
|
|
5
|
+
|
|
6
|
+
# Pure-Rust crypto core: authority, secret and transport surface.
|
|
7
|
+
/crates/cage-core/src/vault.rs @derdelean
|
|
8
|
+
/crates/cage-core/src/gate.rs @derdelean
|
|
9
|
+
/crates/cage-core/src/transport.rs @derdelean
|
|
10
|
+
/crates/cage-core/src/release.rs @derdelean
|
|
11
|
+
/crates/cage-core/src/operator.rs @derdelean
|
|
12
|
+
|
|
13
|
+
# PyO3 authority shell (RustGate, authority and secret co-located).
|
|
14
|
+
/src/lib.rs @derdelean
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
name: build
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
|
|
8
|
+
env:
|
|
9
|
+
CARGO_TERM_COLOR: always
|
|
10
|
+
RUSTFLAGS: "-D warnings"
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
name: test (${{ matrix.os }} / py${{ matrix.python-version }})
|
|
15
|
+
runs-on: ${{ matrix.os }}
|
|
16
|
+
strategy:
|
|
17
|
+
fail-fast: false
|
|
18
|
+
matrix:
|
|
19
|
+
os: [ubuntu-latest, macos-latest]
|
|
20
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
24
|
+
|
|
25
|
+
- name: Install Rust toolchain
|
|
26
|
+
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable @ 2026-06-15
|
|
27
|
+
with:
|
|
28
|
+
# Keep in lockstep with rust-toolchain.toml — that file is what makes a
|
|
29
|
+
# local `cargo clippy` the same check as this one. Bump both together.
|
|
30
|
+
toolchain: "1.97.0"
|
|
31
|
+
components: rustfmt, clippy
|
|
32
|
+
|
|
33
|
+
- name: Cache cargo
|
|
34
|
+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
|
|
35
|
+
with:
|
|
36
|
+
path: |
|
|
37
|
+
~/.cargo/registry
|
|
38
|
+
~/.cargo/git
|
|
39
|
+
target
|
|
40
|
+
key: ${{ matrix.os }}-cargo-${{ hashFiles('Cargo.lock') }}
|
|
41
|
+
|
|
42
|
+
- name: Install uv
|
|
43
|
+
uses: astral-sh/setup-uv@caf0cab7a618c569241d31dcd442f54681755d39 # v3
|
|
44
|
+
with:
|
|
45
|
+
enable-cache: true
|
|
46
|
+
|
|
47
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
48
|
+
run: uv venv --python ${{ matrix.python-version }}
|
|
49
|
+
|
|
50
|
+
- name: Install dev deps
|
|
51
|
+
run: |
|
|
52
|
+
source .venv/bin/activate
|
|
53
|
+
uv pip install maturin pytest pytest-asyncio cryptography httpx
|
|
54
|
+
|
|
55
|
+
- name: Build Rust extension (release)
|
|
56
|
+
run: |
|
|
57
|
+
source .venv/bin/activate
|
|
58
|
+
maturin develop --release
|
|
59
|
+
|
|
60
|
+
- name: Cargo fmt --check
|
|
61
|
+
run: cargo fmt --all -- --check
|
|
62
|
+
|
|
63
|
+
- name: Cargo clippy
|
|
64
|
+
run: |
|
|
65
|
+
source .venv/bin/activate
|
|
66
|
+
cargo clippy --workspace --all-targets -- -D warnings
|
|
67
|
+
|
|
68
|
+
# The PyO3 binding crate has no Rust tests. pytest covers it.
|
|
69
|
+
- name: Cargo test
|
|
70
|
+
run: cargo test --workspace --exclude cage
|
|
71
|
+
|
|
72
|
+
- name: Pytest
|
|
73
|
+
run: |
|
|
74
|
+
source .venv/bin/activate
|
|
75
|
+
pytest -v
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
# Sigstore-signed release pipeline.
|
|
4
|
+
#
|
|
5
|
+
# When a tag v* is pushed:
|
|
6
|
+
# 1. Build manylinux + macOS wheels via maturin (Python 3.11–3.14) and an sdist
|
|
7
|
+
# 2. Sign every wheel via cosign with GitHub Actions OIDC + Fulcio
|
|
8
|
+
# (keyless: no long-lived signing key lives in this repo or in CI)
|
|
9
|
+
# 3. Publish a GitHub Release with the wheels alongside their .sig + .cert files
|
|
10
|
+
# 4. Each signature is recorded in the public Sigstore Rekor transparency log.
|
|
11
|
+
# Verification proves the wheel was built by THIS repository's release.yml
|
|
12
|
+
# at the tagged commit.
|
|
13
|
+
# 5. Publish the wheels and the sdist to PyPI as cage-ai through trusted
|
|
14
|
+
# publishing (OIDC, no API token). PyPI attaches a Sigstore attestation.
|
|
15
|
+
#
|
|
16
|
+
# cage proposes credential containment through capability tokens and an audit
|
|
17
|
+
# chain, and its own releases are signed with the same Sigstore, Fulcio and
|
|
18
|
+
# Rekor model.
|
|
19
|
+
|
|
20
|
+
on:
|
|
21
|
+
push:
|
|
22
|
+
tags:
|
|
23
|
+
- "v*"
|
|
24
|
+
|
|
25
|
+
permissions:
|
|
26
|
+
contents: write # publish GitHub Releases
|
|
27
|
+
id-token: write # OIDC token for cosign keyless signing
|
|
28
|
+
|
|
29
|
+
jobs:
|
|
30
|
+
build-wheels:
|
|
31
|
+
name: build wheel (${{ matrix.os }} / py${{ matrix.python-version }})
|
|
32
|
+
runs-on: ${{ matrix.os }}
|
|
33
|
+
strategy:
|
|
34
|
+
fail-fast: false
|
|
35
|
+
matrix:
|
|
36
|
+
os: [ubuntu-latest, macos-latest]
|
|
37
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
38
|
+
|
|
39
|
+
steps:
|
|
40
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
41
|
+
|
|
42
|
+
- name: Install Rust toolchain
|
|
43
|
+
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable @ 2026-06-15
|
|
44
|
+
with:
|
|
45
|
+
toolchain: stable
|
|
46
|
+
|
|
47
|
+
- name: Install uv
|
|
48
|
+
uses: astral-sh/setup-uv@caf0cab7a618c569241d31dcd442f54681755d39 # v3
|
|
49
|
+
|
|
50
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
51
|
+
run: uv venv --python ${{ matrix.python-version }}
|
|
52
|
+
|
|
53
|
+
- name: Install maturin
|
|
54
|
+
run: |
|
|
55
|
+
source .venv/bin/activate
|
|
56
|
+
uv pip install maturin
|
|
57
|
+
|
|
58
|
+
# Built inside the manylinux_2_28 container: the runner's own glibc is newer
|
|
59
|
+
# than the manylinux_2_28 tag allows, so a native build fails the check.
|
|
60
|
+
- name: Build wheel (manylinux on Linux)
|
|
61
|
+
if: runner.os == 'Linux'
|
|
62
|
+
uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
|
|
63
|
+
with:
|
|
64
|
+
manylinux: 2_28
|
|
65
|
+
args: --release --strip -i python${{ matrix.python-version }}
|
|
66
|
+
|
|
67
|
+
- name: Build wheel (macOS)
|
|
68
|
+
if: runner.os == 'macOS'
|
|
69
|
+
run: |
|
|
70
|
+
source .venv/bin/activate
|
|
71
|
+
maturin build --release --strip -i python${{ matrix.python-version }}
|
|
72
|
+
|
|
73
|
+
- name: Upload wheel artifact
|
|
74
|
+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
|
75
|
+
with:
|
|
76
|
+
name: wheel-${{ matrix.os }}-py${{ matrix.python-version }}
|
|
77
|
+
path: target/wheels/*.whl
|
|
78
|
+
if-no-files-found: error
|
|
79
|
+
|
|
80
|
+
sign-and-release:
|
|
81
|
+
name: sign + release
|
|
82
|
+
needs: build-wheels
|
|
83
|
+
runs-on: ubuntu-latest
|
|
84
|
+
|
|
85
|
+
steps:
|
|
86
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
87
|
+
|
|
88
|
+
- name: Download all wheel artifacts
|
|
89
|
+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
|
90
|
+
with:
|
|
91
|
+
path: artifacts
|
|
92
|
+
pattern: wheel-*
|
|
93
|
+
merge-multiple: true
|
|
94
|
+
|
|
95
|
+
- name: List downloaded wheels
|
|
96
|
+
run: ls -la artifacts/
|
|
97
|
+
|
|
98
|
+
- name: Install cosign
|
|
99
|
+
uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3
|
|
100
|
+
with:
|
|
101
|
+
cosign-release: v2.4.1
|
|
102
|
+
|
|
103
|
+
- name: Sign wheels (keyless, OIDC → Fulcio → Rekor)
|
|
104
|
+
env:
|
|
105
|
+
COSIGN_EXPERIMENTAL: "1"
|
|
106
|
+
run: |
|
|
107
|
+
set -euo pipefail
|
|
108
|
+
mkdir -p signed
|
|
109
|
+
for wheel in artifacts/*.whl; do
|
|
110
|
+
base=$(basename "$wheel")
|
|
111
|
+
echo "Signing $base"
|
|
112
|
+
cosign sign-blob --yes \
|
|
113
|
+
--output-signature "signed/${base}.sig" \
|
|
114
|
+
--output-certificate "signed/${base}.cert" \
|
|
115
|
+
"$wheel"
|
|
116
|
+
cp "$wheel" "signed/"
|
|
117
|
+
done
|
|
118
|
+
ls -la signed/
|
|
119
|
+
|
|
120
|
+
- name: Verify signatures locally (sanity check)
|
|
121
|
+
env:
|
|
122
|
+
COSIGN_EXPERIMENTAL: "1"
|
|
123
|
+
run: |
|
|
124
|
+
set -euo pipefail
|
|
125
|
+
for wheel in signed/*.whl; do
|
|
126
|
+
base=$(basename "$wheel")
|
|
127
|
+
echo "Verifying $base"
|
|
128
|
+
cosign verify-blob \
|
|
129
|
+
--certificate "signed/${base}.cert" \
|
|
130
|
+
--signature "signed/${base}.sig" \
|
|
131
|
+
--certificate-identity-regexp "https://github.com/${{ github.repository }}/\.github/workflows/release\.yml@.*" \
|
|
132
|
+
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
|
|
133
|
+
"$wheel"
|
|
134
|
+
done
|
|
135
|
+
|
|
136
|
+
- name: Publish GitHub Release
|
|
137
|
+
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
|
|
138
|
+
with:
|
|
139
|
+
name: ${{ github.ref_name }}
|
|
140
|
+
body: |
|
|
141
|
+
CAGE ${{ github.ref_name }}, Sigstore-signed. Also on PyPI as `cage-ai`.
|
|
142
|
+
|
|
143
|
+
Every wheel below is signed with Sigstore (keyless OIDC and Fulcio),
|
|
144
|
+
and the signature is recorded in the public Rekor transparency log.
|
|
145
|
+
|
|
146
|
+
**Verify before installing:**
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
cosign verify-blob \
|
|
150
|
+
--certificate cage_ai-*.whl.cert \
|
|
151
|
+
--signature cage_ai-*.whl.sig \
|
|
152
|
+
--certificate-identity-regexp \
|
|
153
|
+
"https://github.com/${{ github.repository }}/\.github/workflows/release\.yml@.*" \
|
|
154
|
+
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
|
|
155
|
+
cage_ai-*.whl
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
A passing verification proves the wheel was built by this
|
|
159
|
+
repository's release workflow at the tagged commit, and the proof
|
|
160
|
+
is recorded in Rekor.
|
|
161
|
+
files: |
|
|
162
|
+
signed/*.whl
|
|
163
|
+
signed/*.sig
|
|
164
|
+
signed/*.cert
|
|
165
|
+
fail_on_unmatched_files: true
|
|
166
|
+
|
|
167
|
+
sdist:
|
|
168
|
+
name: build sdist
|
|
169
|
+
runs-on: ubuntu-latest
|
|
170
|
+
steps:
|
|
171
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
172
|
+
|
|
173
|
+
- name: Build sdist
|
|
174
|
+
uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
|
|
175
|
+
with:
|
|
176
|
+
command: sdist
|
|
177
|
+
args: --out dist
|
|
178
|
+
|
|
179
|
+
- name: Upload sdist artifact
|
|
180
|
+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
|
181
|
+
with:
|
|
182
|
+
name: sdist
|
|
183
|
+
path: dist/*.tar.gz
|
|
184
|
+
if-no-files-found: error
|
|
185
|
+
|
|
186
|
+
publish-pypi:
|
|
187
|
+
name: publish to PyPI
|
|
188
|
+
# Only files that passed signing and the GitHub release go to PyPI.
|
|
189
|
+
needs: [sign-and-release, sdist]
|
|
190
|
+
runs-on: ubuntu-latest
|
|
191
|
+
environment:
|
|
192
|
+
name: pypi
|
|
193
|
+
url: https://pypi.org/project/cage-ai/
|
|
194
|
+
permissions:
|
|
195
|
+
id-token: write # PyPI trusted publishing over OIDC, no API token
|
|
196
|
+
|
|
197
|
+
steps:
|
|
198
|
+
- name: Download wheels
|
|
199
|
+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
|
200
|
+
with:
|
|
201
|
+
path: dist
|
|
202
|
+
pattern: wheel-*
|
|
203
|
+
merge-multiple: true
|
|
204
|
+
|
|
205
|
+
- name: Download sdist
|
|
206
|
+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
|
207
|
+
with:
|
|
208
|
+
name: sdist
|
|
209
|
+
path: dist
|
|
210
|
+
|
|
211
|
+
- name: Publish (trusted publishing, PEP 740 attestations)
|
|
212
|
+
uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3
|
cage_ai-0.1.1/.gitignore
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.pyc
|
|
4
|
+
*.pyo
|
|
5
|
+
.venv/
|
|
6
|
+
*.egg-info/
|
|
7
|
+
build/
|
|
8
|
+
dist/
|
|
9
|
+
wheelhouse/
|
|
10
|
+
.pytest_cache/
|
|
11
|
+
.ruff_cache/
|
|
12
|
+
.mypy_cache/
|
|
13
|
+
|
|
14
|
+
# Rust
|
|
15
|
+
target/
|
|
16
|
+
**/*.rs.bk
|
|
17
|
+
*.pdb
|
|
18
|
+
Cargo.lock.bak
|
|
19
|
+
|
|
20
|
+
# Maturin
|
|
21
|
+
*.so
|
|
22
|
+
*.pyd
|
|
23
|
+
*.dylib
|
|
24
|
+
|
|
25
|
+
# Secrets — never commit
|
|
26
|
+
.env
|
|
27
|
+
.env.*
|
|
28
|
+
*.pem
|
|
29
|
+
*.key
|
|
30
|
+
credentials.json
|
|
31
|
+
|
|
32
|
+
# OS
|
|
33
|
+
.DS_Store
|
|
34
|
+
Thumbs.db
|
|
35
|
+
|
|
36
|
+
# Editor
|
|
37
|
+
.vscode/
|
|
38
|
+
.idea/
|
|
39
|
+
*.swp
|
|
40
|
+
|
|
41
|
+
# Personal notes & exported conversation history — never push
|
|
42
|
+
all-notes-*.txt
|
|
43
|
+
conversation-*.md
|
|
44
|
+
conversation-*.txt
|
|
45
|
+
release-prep/
|
|
46
|
+
|
|
47
|
+
# Claude Code local state (settings, scheduler, locks) — never push
|
|
48
|
+
.claude/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|