Vulnerability Management

Running Remediation Campaigns From Draft to Done

By PMAP Security Team 19 min read

Most vulnerability management programmes are good at finding problems and bad at closing them. Scanners run, findings pile up, and a dashboard somewhere shows a number that never seems to go down. The gap is rarely about effort. It is about coordination. When every finding is assigned and chased individually, nobody can answer the questions a security manager actually has to answer. How much of this batch is done. What is overdue. Who owns the rest. When will it close.

PMAP closes that gap with remediation campaigns. A campaign is a named, time-bounded grouping of existing findings, assigned to a responsible owner, that you drive toward closure as a single coordinated programme. This article explains why finding-by-finding tracking runs out of road at scale, how the campaign state machine keeps a programme honest from draft to completion, and what the live closure metrics tell you while the work is in flight. The focus here is the why and the operating model. For the step-by-step procedure, the companion guide walks through the clicks.

If you want the wider context first, remediation campaigns sit inside PMAP’s broader security assessment management story, where assessments, engagements and remediation all share one governed backbone.

Why Finding-by-Finding Assignment Falls Short

Assigning a single finding to a single engineer works fine when you have ten findings. It stops working the moment a quarter-end scan returns several hundred. Individual assignment gives you a queue. It does not give you a programme.

The missing piece is a coordination layer. When findings are tracked one at a time, there is no shared deadline, no shared owner, and no single object that represents “the remediation effort for this batch.” A manager who wants to know whether the Q2 critical-patch push is on track has to reconstruct that answer from dozens of individual records, each with its own status, its own due date, and its own assignee. The reconstruction is manual, it is error-prone, and it is stale the moment it is finished.

This is the exact problem PMAP campaigns are built to solve. At enterprise scale, individual finding assignment lacks the coordination layer needed to track remediation progress against committed deadlines. A campaign supplies that layer. It is a governed container with its own lifecycle, its own owner, its own due date, and its own live metrics, sitting on top of findings that already exist in the platform. The findings do not change identity. They simply gain membership in a coordinated effort that can be reported on as a whole.

Think of the difference this way. Finding-by-finding assignment answers “is this one fixed.” A campaign answers “is the programme on track.” Those are different questions, and only the second one matters in a steering review.

A Campaign Is a Time-Bounded Group of Findings

Before the mechanics, it helps to be precise about what a campaign actually is in PMAP, because the definition drives everything else.

A remediation campaign is a named, time-bounded grouping of existing findings assigned to a responsible owner. Each campaign carries a small but deliberate set of attributes. It has a name, so the programme has an identity people can refer to in a standup. It has an owner, so accountability is unambiguous. It has start and due dates, so the effort is bounded in time rather than open-ended. It belongs to a single company, so multi-tenant boundaries are respected. And it carries a status that moves through a defined lifecycle.

What a campaign is not is a finding generator. Campaigns do not create findings. They link existing findings to a coordinated effort. The findings are the raw material. The campaign is the programme wrapped around them. This separation matters operationally. Deleting a campaign does not delete or modify its linked findings. Finding data is independent of campaign membership, so you can spin up, complete, and retire campaigns without ever putting the underlying vulnerability records at risk.

That independence also means a finding can be managed in its own right while it participates in a campaign. The campaign is a lens for coordination, not a cage. You group findings to drive a deadline, and when the deadline is met or the effort is retired, the findings carry on living in the platform exactly as they did before.

The Campaign State Machine

The single most important thing to understand about PMAP campaigns is that their lifecycle is governed by an enforced state machine, not by free-text status fields that anyone can set to anything. A campaign moves through a fixed set of states, and the allowed transitions between them are validated on the server.

The states are draft, active, review, completed, and cancelled. The allowed transitions look like this.

draft -> active, cancelled
active -> review, cancelled
review -> completed, active, cancelled
completed -> (terminal)
cancelled -> (terminal)

A campaign starts life in draft. This is where you assemble it. You give it a name, an owner, a due date, and you attach the findings that belong in scope, all without signalling to the wider team that the programme is live. When the scope is set and the work is ready to begin, you move it to active. Active is the working state. This is where remediation actually happens, where owners chase fixes, and where the closure metrics earn their keep.

From active, a campaign can move to review. Review is the checkpoint where someone confirms the work is genuinely done rather than merely marked done. From review, the campaign can advance to completed, which signals the programme has closed cleanly. At any non-terminal point a campaign can also move to cancelled, which is the honest way to retire a programme that is no longer relevant.

The enforcement is real. Transitions are restricted to the valid set. An illegal move, for example trying to jump a campaign straight from draft to completed, is rejected by the API with an HTTP 400 and an invalid-transition error, and the campaign stays exactly where it was. The interface reinforces this. When you open the inline status menu on a campaign, only the valid next states are offered. Invalid targets are greyed out with a lock icon, so the lifecycle is communicated visually before anyone even tries to break it.

This is a small design decision with a large governance payoff. Because the state machine is enforced rather than advisory, a campaign’s status is trustworthy. When a steering report says forty campaigns are in review, that number means something specific and verifiable, not whatever forty different people happened to type.

Why Review Can Revert to Active

One transition deserves its own note because it reflects how real remediation works. From the review state, a campaign can move forward to completed, or it can move back to active.

Review is reversible by design. A campaign can move back to active from review if the review raises new concerns. This matters because review is the point where a closure claim gets tested. Maybe a finding was marked resolved but the fix did not hold. Maybe a retest surfaced a regression. Maybe the reviewer simply is not satisfied that the evidence is sufficient. In any of those cases, forcing the campaign forward to completed would be dishonest, and forcing it to cancelled would be wasteful. Sending it back to active is the correct move, and the state machine allows exactly that.

Contrast this with the terminal states. Completed and cancelled are terminal. Once a campaign reaches either, further transitions are locked. A completed programme cannot be quietly reopened to absorb new work, and a cancelled programme cannot be revived to hide that it was abandoned. The asymmetry is deliberate. Review stays flexible because judgement calls happen there. Closure stays final because a closed programme should mean what it says.

Managing Finding Membership Safely

A campaign is only as useful as the findings inside it, and PMAP treats membership as something to manage continuously rather than fix at creation time. You add findings, you remove findings, and the campaign scope tracks reality as the effort proceeds.

Findings are added and removed by their UUIDs, in arbitrary sets. You can attach a single finding or a large batch in one action. You can attach findings at the moment you create a campaign, which is how the workflow runs when you start from the Findings page and group a filtered set straight into a new programme. You can also add more later, from the campaign detail itself, through a searchable and severity-filtered picker that excludes anything already linked so you never accidentally double-add.

Two safety properties make this trustworthy in a multi-tenant platform. First, membership is company-scoped at the database layer. When you submit a set of finding UUIDs to add, any UUIDs that belong to a different company are silently rejected and produce zero inserted rows. The cross-tenant boundary is enforced where it cannot be bypassed, not in a UI check that a crafted request could skip. Second, adding findings is idempotent. Re-adding a finding that is already linked does not create a duplicate membership row. The database handles the conflict cleanly, so repeated or overlapping add operations converge on the correct state instead of corrupting it.

Removal is just as safe and just as decoupled. Removing a finding from a campaign takes it out of the programme’s scope without touching the finding itself. The vulnerability record, its history, and its assignment all survive. Scope is something you curate freely, because curating it carries no risk to the underlying data.

The net effect is that campaign scope stays accurate over the life of the programme. As priorities shift, as new findings land, or as some findings turn out to belong to a different effort, you adjust membership with confidence that you are changing the programme’s boundary and nothing more.

Bulk-Assigning a Remediation Owner

Grouping findings is half the value. The other half is staffing them, and this is where bulk assignment turns a campaign from a list into a sprint.

In one action, you can assign a single user to every finding in a campaign, or to a chosen subset. The default behaviour targets the whole campaign. When you run a bulk assign without specifying particular findings, every finding currently linked to the campaign is assigned to the chosen owner. When you do want finer control, you pass an explicit list, and the assignment is restricted to exactly that subset. Either way, the work goes from “a batch of findings” to “a batch of findings with a clear owner” in a single step, without the per-finding clicking that makes staffing a sprint feel like data entry.

Bulk assignment is also scoped defensively. The operation constrains the findings it can affect to those genuinely linked to the campaign through its membership join. If a request somehow carries finding UUIDs that are not part of the campaign or belong to another tenant, those UUIDs simply produce zero affected rows. You cannot use a campaign’s bulk-assign endpoint as a side door to touch findings outside its scope.

Crucially, assignment is not a silent database write. Each affected finding triggers a finding-assigned notification event, dispatched per finding after the assignment is committed. That means the people who just picked up work actually learn about it through the platform’s notification path rather than discovering it the next time they happen to open a screen. A campaign owner can staff an entire remediation sprint in seconds and trust that everyone in it has been told.

This is the moment where the coordination layer pays off most visibly. Instead of opening dozens of findings and setting an assignee on each, the owner stages the whole programme, picks a responsible engineer, and the platform fans the work out with notifications attached.

Live Closure Metrics Managers Watch

A governed lifecycle and clean staffing get a campaign started. Live metrics are what let a manager steer it. PMAP computes a small set of counters on the campaign detail that answer the questions a remediation programme is actually judged on.

When you open a campaign, its detail returns four computed values. Total findings is the size of the programme. Closed findings is how many are done. Overdue findings is how many have blown their deadline and need escalation. And closure rate is the proportion of the programme that is complete, the single percentage that tells you at a glance whether the effort is converging. These surface as KPI cards and a full-width progress bar on the campaign detail, alongside the owner and the due date, so the health of the programme reads in one glance.

These metrics are computed at query time when the campaign detail is fetched, which is what makes them live rather than a snapshot someone has to refresh by hand. The example the platform’s own acceptance criteria use is concrete. A campaign with ten linked findings, of which four are closed and two are overdue, returns a total of ten, four closed, two overdue, and a closure rate of 0.4. The numbers are derived from the actual state of the linked findings, not from a manually maintained tally that drifts out of date the moment work continues.

There is one practical nuance worth knowing. The campaign detail recomputes these metrics live, while the campaign list page uses a cached closure rate stored on each row rather than recalculating every campaign on every list load. This is the right trade. The list stays fast across a long registry of campaigns, and the detail gives you the authoritative live figure for the one programme you are actually steering. When you want the precise current state of a campaign, you open it.

For a security manager, this is the difference between managing a programme and merely hosting it. Overdue count tells you where to escalate today. Closure rate tells you whether the deadline is realistic. Total and closed together tell you the shape of what remains. None of it requires a spreadsheet, because the platform computes it from the findings themselves.

Access Control: Campaigns Are Platform-Admin Scoped

Remediation campaigns are a programme-level governance tool, and PMAP scopes them accordingly. Every campaign endpoint is mounted under the platform’s admin route block, which means the platform-admin role is required for every campaign operation without exception. Creating, editing, transitioning, staffing, and reporting on campaigns are all admin-only actions.

This is a deliberate boundary, not an oversight. A campaign sets deadlines, assigns owners across a programme, and produces the closure metrics that feed steering reviews. Those are coordination decisions that belong with the people accountable for the remediation programme, typically platform admins and security managers, rather than with every individual contributor working a single finding. The admin mount enforces that at the routing layer. A user without the platform-admin role is rejected by the admin middleware before the request ever reaches the campaign logic, so the access rule cannot be argued with inside the feature.

Multi-tenancy is enforced just as firmly. Listing campaigns applies a scope filter from the authenticated context, so an admin only ever sees campaigns within their own company’s scope. Fetching a specific campaign re-checks scope after the database read, and an out-of-scope campaign returns an HTTP 404 rather than a 403. The choice of 404 over 403 is intentional. A 403 would confirm that a campaign with that identifier exists, which is itself a small information leak. Returning 404 reveals nothing.

Taken together, the access model says something clear about what a campaign is for. It is a controlled, tenant-isolated, admin-governed instrument for driving remediation as a programme, and the platform makes sure it stays that way.

How PMAP Coordinates Remediation at Programme Level

Step back from the individual mechanics and the design intent is coherent. PMAP treats remediation as a programme to be coordinated, not a queue to be drained.

A campaign gives a batch of findings an identity, an owner, and a deadline. The enforced state machine keeps the programme’s lifecycle honest, with a reversible review checkpoint where closure claims get tested and terminal states that mean what they say. Finding membership is curated freely and safely, decoupled from the underlying findings and guarded at the tenant boundary. Bulk assignment turns staffing from per-finding data entry into a single notified action. Live closure metrics let a manager steer by closure rate and overdue count rather than by reconstruction. And the admin-only, tenant-scoped access model keeps the whole instrument in the hands of the people accountable for the outcome.

This is what it looks like to turn a backlog into a tracked programme. The findings were always there. What the campaign adds is the coordination layer that lets a team commit to a deadline and prove, with live numbers, whether they are meeting it.

For teams who want to put this into practice, the companion walkthrough on tracking a remediation campaign from draft to completion covers the hands-on procedure end to end. To understand how campaigns relate to the projects and engagements they often grow out of, see how PMAP handles a governed pentest project across multiple firms. And if you are weighing a campaign against ticket-based tracking, the comparison of remediation campaigns versus tickets draws the line between the two.

If you want to align this model with established practice, the most directly relevant external references are NIST SP 800-40 Rev. 4 on enterprise patch and remediation management, CIS Critical Security Controls v8 Control 7 on continuous vulnerability management, and the FIRST CVSS specification for the severity-driven prioritisation that decides what belongs in a campaign in the first place.

Remediation only counts when it closes. PMAP campaigns turn a pile of findings into a programme you can name, staff, deadline, and prove. Try one on your own findings and watch the closure rate move.

Frequently Asked Questions

What is a remediation campaign in PMAP?

A remediation campaign is a named, time-bounded grouping of existing findings assigned to a responsible owner. It is the mechanism PMAP uses to coordinate remediation across multiple vulnerabilities as a single programme rather than tracking each finding individually. A campaign carries a name, an owner, start and due dates, a company scope, and a status that moves through a defined lifecycle. It does not create findings. It links findings that already exist into one coordinated effort with shared accountability and a shared deadline.

What status transitions are allowed in a campaign?

Campaign status is governed by an enforced state machine. A campaign moves from draft to active or cancelled, from active to review or cancelled, and from review to completed, back to active, or to cancelled. Completed and cancelled are terminal, so no further transitions are allowed once a campaign reaches either. Illegal moves, such as jumping straight from draft to completed, are rejected by the API with an HTTP 400 invalid-transition error, and the campaign stays in its current state. The status menu in the interface only offers valid next states and greys out invalid ones with a lock icon.

Why can a campaign move back from review to active?

Review is intentionally reversible. From review a campaign can advance to completed or revert to active. The revert path exists because review is where a closure claim gets tested, and a review can raise new concerns, for example a fix that did not hold or a regression surfaced by a retest. In that case the honest move is to send the programme back to active so the remaining work gets done, rather than forcing it to completed. Closure states stay final because a closed programme should mean what it says, while review stays flexible because judgement calls happen there.

Can I assign all campaign findings to one owner at once?

Yes. Bulk assignment lets you assign a single user to every finding in a campaign in one action. If you run a bulk assign without specifying particular findings, it targets all findings currently linked to the campaign. If you pass an explicit list of finding identifiers, the assignment is restricted to that subset. Each affected finding emits a finding-assigned notification event after the assignment is committed, so the people picking up the work are actually notified. The operation only ever affects findings genuinely linked to the campaign, so out-of-scope or cross-tenant identifiers produce no effect.

How is campaign closure rate calculated?

Closure rate is computed from the linked findings at query time when you open the campaign detail. The detail returns total findings, closed findings, overdue findings, and the closure rate as the proportion of the programme that is complete. For example, a campaign with ten linked findings of which four are closed returns a closure rate of 0.4. Because the figure is derived from the actual state of the findings rather than a maintained tally, it stays current. The campaign list view uses a cached closure rate per row for speed, while the campaign detail recomputes the authoritative live value.

Does deleting a campaign delete its findings?

No. Deleting a campaign does not delete or modify any of its linked findings. Findings are independent of campaign membership, so the vulnerability records, their history, and their assignments all survive when a campaign is removed. The same independence applies to removing a finding from a campaign. It takes the finding out of the programme’s scope without touching the finding itself. This decoupling is what lets you create, complete, and retire campaigns freely without ever putting the underlying finding data at risk.

Who can create and manage remediation campaigns?

Campaign operations are restricted to the platform-admin role. Every campaign endpoint is mounted under the platform’s admin route block, so creating, editing, transitioning status, bulk-assigning, and reading closure metrics all require admin access. A user without the platform-admin role is rejected by the admin middleware before the request reaches the campaign logic. This reflects that campaigns are a programme-level coordination tool that sets deadlines and assigns work across a batch, which belongs with platform admins and security managers rather than with individual contributors working a single finding. Campaigns are also tenant-scoped, so admins only see campaigns within their own company.

author avatar
PMAP Security Team

Newsletter

Get the next writeup in your inbox

One short email when a new case writeup or detection deep dive ships. No marketing drip, no third-party tracking.