mirror of
https://github.com/saymrwulf/puncture.git
synced 2026-05-14 20:48:10 +00:00
master
| goapp | ||
| puncture | ||
| tests | ||
| .gitignore | ||
| pyproject.toml | ||
| README.md | ||
| requirements.txt | ||
Puncture: Zero-Trust Cloud-Wide Forward Secrecy
Python implementation of puncturable encryption (PE) over a GGM tree, with:
- a master app (key management + provider management + asset encryption mapping)
- a secondary app (read-only live mirror with password auth and kill-switch login)
Core cryptographic model
- 256-bit master seed root.
- HMAC-SHA256 left/right derivation for GGM child nodes.
- Non-sequential puncture with minimal co-path replacement.
- Tag schema:
[7 bits provider_id] | [25 bits file_time_id]. - Active-state model stores only active prefix nodes (not per-file keys).
- Immediate zeroization of replaced node material on puncture.
- Puncture log export/import (
list[str]of bit strings).
Setup (venv)
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Run
Master app on 9122:
python -m puncture.web_app --host 0.0.0.0 --port 9122
Secondary app on 9222:
python -m puncture.view_app --host 0.0.0.0 --port 9222
Master app (:9122) workflow
/: main puncture lab (derive/puncture, history, active frontier roots view)./providers: add/edit/delete providers./assets: pick a cleartext file from asset root, select provider/key, encrypt, and register mapping.
Asset behavior
- Ciphertext is written in the same folder as the cleartext file.
- Decryption writes recovered cleartext back into the same folder tree (versioned filenames).
- One cleartext file can have multiple provider-key mappings.
- One provider-key can encrypt multiple files.
- After key puncture:
- affected mappings are shown in red (
blocked by puncture) - if the same cleartext file still has another accessible mapping, that mapping glows
- affected mappings are shown in red (
Secondary app (:9222) behavior
- Password-gated access.
- Live read-only mirror from master (
GET /api/live/state). - No share setup and no independent derivation state.
- Kill-switch login format:
- normal login:
<password> - kill-switch login:
<password><provider_id> - example:
puncture-view42punctures provider42immediately on master.
- normal login:
Environment variables
Master app:
PUNCTURE_PORT(default9122)PUNCTURE_ASSET_ROOT(default<cwd>/assets)PUNCTURE_REMOTE_TOKEN(optional; required for remote puncture endpoint)PUNCTURE_VIEW_SYNC_KEY(optional signing key for/api/view-bundle)
Secondary app:
PUNCTURE_VIEW_PORT(default9222)PUNCTURE_MASTER_URL(defaulthttp://127.0.0.1:9122)PUNCTURE_SECONDARY_PASSWORD(defaultpuncture-view)PUNCTURE_SECONDARY_SECRET(Flask session secret)PUNCTURE_REMOTE_TOKEN(optional; sent asX-Puncture-Token)
API quick reference
GET /api/state(master full state)GET /api/live/state(master live data for secondary app)POST /api/remote/puncture-provider(master remote provider kill endpoint)GET /api/export/POST /api/importPOST /api/puncture-logGET /api/view-bundle(legacy signed/unsigned viewer bundle export)
Tests
pytest -q