Bind every security engagement in one governed container: three-mode scope, sequentially numbered runs, remediation campaigns, methodology checklists, and the firms and contracts that fund the work.
A project in PMAP is the container for a single security engagement: a penetration test, a recurring scan campaign, or a periodic review, scoped to exactly one customer company and owned by one or more consulting firms. Every finding, scan, run, and piece of evidence carries a project_id that traces back to it.
Around the project sit five companion domains: assessment runs (the individual waves of testing), remediation campaigns (deadline-bearing closure efforts), checklists (methodology coverage), framework agreements (the contracted man-day pool a firm draws on), and the cross-tenant consulting firm directory whose qualifications are tracked for vetting.

The design problem at enterprise scale is coordination, not storage. A large programme runs dozens of concurrent engagements across many firms and companies, each with its own scope, contract, and deadlines.
At a glance
- Backend domains: project, assessmentrun, campaign, checklist, frameworkagreement, consultingfirm (Go modular monolith)
- Scope model: Three modes per project: individual assets, asset groups, and attribute selectors merged into one effective scope
- Assessment runs: Gap-free run_number per project, five run types, one-click multi-scanner campaign launch
- Remediation campaigns: Enforced state machine, platform_admin scoped, live closure metrics on read
- Checklists: Reusable templates copied per project; progress server-computed, never trusted from the client
- Commercial layer: Framework and project_based agreements with man-day accounting recalculated on every project change
- Multi-tenancy: ScopeFilter and InScope checks across every list, export, and detail path; 404 on a mismatch
How it works
One engagement, modelled end to end. Scope, schedule, effort, methodology, and the commercial contract live as related records, so what was tested, by whom, and under which agreement is always answerable.
Defining what is in scope is the most error-prone step in setting up an engagement, because real target surfaces do not map onto a flat list of hosts. PMAP solves this with a composite scope combining three independent modes that merge into one effective scope, and every scan and run inherits it.
A remediation campaign is a named, time-bounded grouping of existing findings assigned to a responsible owner, letting a security manager drive closure across many vulnerabilities as one tracked effort. Campaigns do not create findings; they link existing ones, and every endpoint requires the platform_admin role.
Key capabilities
- Scope-safe membership and assignment. AddFindings inserts only findings belonging to the campaign company, enforced by a database-layer join, so an out-of-tenant UUID is silently ignored rather than leaked. BulkAssign attaches one owner to all linked findings or a named subset and emits a FindingAssigned event per affected finding.
- Live closure metrics. Reading a campaign returns progress computed at query time: total, closed, and overdue finding counts and a closure rate. These drive the KPI cards and progress bar so programme health is visible at a glance, never reconstructed by hand from a spreadsheet.
- Copy-on-instantiation checklists. A project checklist created from a template_id copies the template items into an independent instance, so later template edits do not propagate and a committed test plan stays stable and auditable. Templates carry a type: owasp_web, pci_dss, internal_pentest, or custom.
- Capacity you can trust. Remaining man-days are computed at query time as total minus used, never stored. Used man-days for a framework agreement are recalculated by summing each linked project actual or estimated days, triggered on every project mutation that touches the agreement.
Use cases
- Stand up a contracted engagement. A project lead creates a project under the customer company, links it to the firm framework agreement, and defines scope in three modes: pinned assets, two asset groups, and a wildcard-domain selector that reports its match counts before any scan runs. Used man-days update the moment the project is saved.
- Launch a multi-scanner wave. A pentest lead creates an assessment run with launch enabled, selecting Nessus and Qualys integrations and a high-severity filter. PMAP allocates the next gap-free run number, spawns one scan per integration, and returns the run immediately, so the wave is underway in a single action.
- Drive a remediation programme. A vulnerability manager, acting as platform admin, gathers open findings into a campaign with a due date and an owner, then bulk-assigns them in one action. The detail shows live total, closed, and overdue counts and a closure rate, and the state machine blocks any illegal jump.
One engagement, modelled end to end: scope, runs, campaigns, checklists, and contracts as related records.


