|
|
5 days ago | |
|---|---|---|
| certs | 3 weeks ago | |
| deploy | 2 weeks ago | |
| docs | 5 days ago | |
| static | 5 days ago | |
| templates | 5 days ago | |
| tests | 5 days ago | |
| .gitignore | 2 weeks ago | |
| AGENTS.md | 5 days ago | |
| README.md | 5 days ago | |
| admin.py | 2 weeks ago | |
| app.py | 2 weeks ago | |
| auth.py | 2 weeks ago | |
| config.example.toml | 5 days ago | |
| config_store.py | 5 days ago | |
| logs.py | 2 weeks ago | |
| pipeline.py | 5 days ago | |
| pps_client.py | 3 weeks ago | |
| prefs.py | 2 weeks ago | |
| pytest.ini | 2 weeks ago | |
| requirements-dev.txt | 2 weeks ago | |
| requirements.lock | 2 weeks ago | |
| requirements.txt | 2 weeks ago | |
| worker.py | 5 days ago | |
| wsgi.py | 2 weeks ago |
A web app for operators to manage a Proofpoint Protection Server (PPS) email quarantine: list quarantined mail by folder, read messages (headers, body, attachments, raw headers), and run bulk actions — Release, Report & Release, Delete, Move — as asynchronous background jobs, so slow PPS calls never block the operator.
/admin, admin-only) to manage users, the PPS connection, folders,
defaults, the Report & Release pipeline, background jobs, and logs — editing config.toml
live (comment-preserving), with write-only credentials.python3 -m venv venv
venv/bin/pip install -r requirements.txt
cp config.example.toml config.toml # edit: [okta], [pps] creds, [[auth.users]], secret_key
venv/bin/python wsgi.py # http://127.0.0.1:8080
Generate a session key: python -c "import secrets; print(secrets.token_urlsafe(48))".
Local dev without Okta: set [auth] mode = "static", use [auth.static] credentials,
and run with PPSQ_CONFIG=/tmp/dev.toml PPSQ_ALLOW_INSECURE=1 venv/bin/python wsgi.py.
See docs/development.md.
wsgi.py is the single-process entrypoint: it builds the config store, the SQLite-backed
job queue, and the per-user prefs store, starts one background worker thread, and serves via
waitress. The browser fires an action and gets an immediate 202; the worker drains the
queue and calls PPS. Jobs survive a restart. Run as a single process only.
Report & Release is a configurable pipeline of steps (move → release, pick either or
both) — move files the mail into a report folder, release delivers it from there. It never
deletes; Delete is its own action. Configured with checkboxes in the admin panel. Between
steps the job waits
step_delay_seconds for PPS's backend to settle and then re-reads where the messages
actually are; while it waits it is parked back on the queue, so other jobs keep running.
| Doc | | |-----|--| | AGENTS.md | Start here. Module map + the invariants you must not break. | | docs/architecture.md | System design, request/job lifecycle, hot-reload. | | docs/configuration.md | Every config key, zones, live-vs-restart. | | docs/api.md | HTTP API reference. | | docs/okta-setup.md | Okta OIDC app setup + access model. | | docs/operations.md | Deploy, logs, backup, credential rotation, troubleshooting. | | docs/development.md | Dev setup, running without Okta/PPS, tests. | | docs/security.md | Auth, sessions/CSRF, secrets, known limitations. |
venv/bin/pip install -r requirements-dev.txt
venv/bin/python -m pytest # ~57 tests, no Okta tenant or real config needed
Python 3.11+ (uses tomllib/tomlkit; developed on 3.12). Flask, Authlib, tomlkit, requests,
waitress — see requirements.txt (ranges) / requirements.lock (pinned).
Internal production release, evolved from the original PoC. Single-process; secrets are plaintext-on-disk (0600); roles are app-managed, not Okta groups. See docs/security.md for the accepted limitations.