Ingen beskrivning

Josef Straßl b6a44ab948 initial poc 3 veckor sedan
static b6a44ab948 initial poc 3 veckor sedan
templates b6a44ab948 initial poc 3 veckor sedan
.gitignore b6a44ab948 initial poc 3 veckor sedan
README.md b6a44ab948 initial poc 3 veckor sedan
app.py b6a44ab948 initial poc 3 veckor sedan
config.example.toml b6a44ab948 initial poc 3 veckor sedan
pps_client.py b6a44ab948 initial poc 3 veckor sedan
requirements.txt b6a44ab948 initial poc 3 veckor sedan
worker.py b6a44ab948 initial poc 3 veckor sedan

README.md

PPS Quarantine Manager (PoC)

A small web client for the Proofpoint Protection Server (PPS) quarantine. It lists quarantined mail by folder and runs bulk actions — Release, Report & Release, Delete, Move — as asynchronous background jobs, so the operator never waits on slow PPS API calls (deletes in particular).

Proof of concept: static login, plaintext secrets in a config file, no permission model. SAML/OIDC and RBAC come later.

How it works

  • Frontend (templates/, static/): one page. A folder switcher scopes the whole view to one quarantine folder; the list shows date / sender / recipient / subject with a checkbox per row. Clicking a row opens the message content in an overlay over the list (HTML parts render in a sandboxed iframe). Actions apply to all checked rows, which then disappear from the list immediately.
  • Backend (app.py, pps_client.py): Flask serves the UI and proxies the PPS Quarantine Search REST API. Actions are queued and return instantly (HTTP 202).
  • Worker (worker.py): a daemon thread drains a SQLite-backed job queue, batching message ids into chunked PPS POSTs. Jobs are persistent, so queued work survives a restart; a job left mid-flight is requeued on startup.

Action semantics

UI action PPS API call(s)
Release release without rescan; deletedfolder set so it leaves the folder
Report & Release release (in place, no rescan) then move a copy to report_release_folder
Delete delete with deletedfolder (moves to deleted items, not a hard delete)
Move move to the folder chosen in the dropdown

Report & Release keeps a copy in report_release_folder (default "Debugging - Josef") for manual false-positive submission while the mail is delivered. If this PPS deployment's release relocates the message to the deleted folder (like the admin GUI does), the worker re-finds it there by its stable guid and moves it from there — no configuration needed.

Setup

python3 -m venv venv
venv/bin/pip install -r requirements.txt
cp config.example.toml config.toml
# edit config.toml: PPS host, API credentials, folders, login
venv/bin/python app.py

Open http://127.0.0.1:8080 and sign in with the [auth] credentials from config.toml.

Configuration notes

  • Folders are maintained locally. The PPS API has no endpoint to list folders, so the folders array in config.toml is the source of truth for the switcher, the Move dropdown, and the delete/report targets. Names must match PPS exactly (case- and space-sensitive, e.g. "Debugging - Josef"); a wrong name only errors at action time.
  • list_query = "from=*". The search API requires a from/rcpt/subject filter — it can't list a folder by folder alone. A bare wildcard means "everything in the folder". If your PPS doesn't treat from=* as match-all, set it to something like rcpt=@yourdomain.com.
  • default_days_back. The search API alone returns only the last 24h; this widens the window (uses startdate).
  • Limits. Up to 1000 messages per search (API cap, no pagination). default_limit sets the UI default; the operator can raise it to 1000.
  • verify_tls. PPS admin certs are often self-signed; false skips verification (PoC). Point it at a CA bundle path to verify instead.
  • Mutual TLS (client certificate). If PPS is fronted by nginx requiring a client cert, requests without one fail with 400 No required SSL certificate was sent. Set client_cert (a combined cert+key PEM, or a cert PEM plus client_key for the key). Note this is a TLS client cert, separate from the [pps] Basic-auth credentials — the endpoint may require both.

API credentials

The account in [pps] must be a PPS admin with an API Role that has the Quarantine module enabled (see the PPS management interface / a Proofpoint support ticket for PoD). Auth is HTTP Basic against the admin port (default 10000).

Files

app.py               Flask app: routes, login, config, worker startup
pps_client.py        PPS Quarantine REST client (search / get_raw / act)
worker.py            SQLite job queue + background worker thread
config.example.toml  Config template (copy to config.toml)
templates/           login.html, index.html
static/              app.js, style.css