Vulnerability Management

SLA Deadline Recalculation Explained

By PMAP Security Team 20 min read

A service-level agreement deadline looks like a single date on a finding. In reality it is a computed value that has to survive every change a vulnerability goes through. The severity can be revised after a retest. A finding can be paused while a vendor patch is pending, then resumed weeks later. A company can sign a stricter contractual window that has to apply retroactively to everything already open. If the deadline were a static timestamp written once at creation, none of those events would be reflected, and your SLA breach reporting would slowly drift away from the truth.

This article walks through the math behind that deadline. It is about recalculation specifically, meaning how the deadline is recomputed when something material changes, why pause time is added back into the window, and which configuration level wins when several scopes disagree. It is not a guide to setting up thresholds or escalation routing. Threshold setup and escalation contacts are configured separately, and the definition of vulnerability management SLAs as a concept is covered on its own. Here the focus is the formula, the precedence chain, and the recompute triggers, grounded in how PMAP actually resolves these values.

If you own remediation timelines, design SLA policy for a compliance program, or coordinate fix work across teams, understanding this math is what lets you trust the deadline you report to an auditor.

What an SLA Deadline Represents

An SLA deadline answers a narrow question. Given a finding of a known severity, how much time may pass before that finding has breached its service-level agreement? The deadline is the moment that window closes.

The underlying mechanism is a severity to hours mapping. Every severity level carries an allowed number of hours that a finding of that severity may remain open. An urgent finding gets a short window. A low finding gets a long one. The deadline is simply the finding’s start point plus the hours its severity allows, with one adjustment for paused time that we will get to shortly.

In PMAP, the component that owns this mapping is the SLA Config domain. It manages per-scope SLA threshold overrides, where a config is a severity to hours mapping that governs how long a finding of a given severity may remain open before it breaches. That domain has no dependency on finding business logic. The relationship is deliberately one-directional. The finding service asks the SLA config service for the right number of hours, and the SLA config service answers without knowing or caring what the finding does next. That separation matters for the recalculation story, because it means the same resolution logic produces the same answer whether a finding is being created, updated, or recomputed in bulk.

So when you see a deadline on a finding, read it as a derived fact. It is the output of a function, not a field someone typed in. Recalculation is what happens when one of the inputs to that function changes.

The Severity-to-Hours Mapping

The first input to the deadline is the number of hours the finding’s severity allows. PMAP recognizes five severity values: urgent, critical, high, medium, and low. These are string-typed and match the finding domain’s severity column exactly, so there is never a translation step between how a finding labels its severity and how the SLA config looks it up.

Each severity maps to an hour limit. The limits are configurable per scope, which is what makes the precedence chain in the next section necessary. But underneath the configurable layers sits a fixed set of defaults that always produces an answer.

The Hardcoded Fallback Values

If no config exists at any level, the resolution logic falls back to built-in defaults. These hardcoded values are:

  • Urgent: 24 hours, meaning one day.
  • Critical: 72 hours, meaning three days.
  • High: 168 hours, meaning seven days.
  • Medium: 720 hours, meaning thirty days.
  • Low: 2160 hours, meaning ninety days.

These numbers are worth committing to memory because they are the floor of the whole system. Whatever else is configured or left blank, an open finding of a given severity will always resolve to a concrete window. There is no state in which a finding has no deadline because nobody configured one.

There is also a final fallback below even these per-severity defaults. If resolution somehow reaches the end of the chain without a usable value, it returns 168 hours, which is the seven-day window. Think of it as a last-resort guarantee that the math never returns zero or null. A finding without a meaningful window would be invisible to SLA breach tracking, and the design refuses to allow that.

Notice that the defaults scale roughly with how much exposure each severity represents. The gap between urgent at 24 hours and low at 2160 hours is two orders of magnitude. That spread is what gives risk-based remediation its teeth. Recalculation matters precisely because a finding can move between these bands, and when it does, the deadline has to move with it.

The Five-Level Precedence Chain

Real organizations do not run on a single set of SLA numbers. A holding company may set one baseline, a subsidiary may tighten it, and a specific engagement may have contractual terms stricter than both. To support that, the deadline resolution applies a waterfall. It looks for an answer at the most specific scope first and falls back level by level until it finds a usable value.

For a given combination of severity, project, and company, the resolution order is:

  1. Project config. The hours for that severity from the project-level SLA config. This is the most specific scope and wins if present.
  2. Company config. The hours for that severity from the company-level config. Used when the project has nothing set for that severity.
  3. Global defaults. The platform-wide defaults supplied by admin settings. Used when neither project nor company specifies the severity.
  4. Hardcoded values. The built-in urgent 24, critical 72, high 168, medium 720, low 2160 mapping described above.
  5. Final fallback. 168 hours, the seven-day guarantee, if nothing else produced a value.

A level is skipped if its config row is absent or if the specific severity field is null or zero. The first non-zero positive value wins. That last detail is what makes the chain robust. It does not stop at the first config row it finds. It stops at the first config row that actually has a value for the severity in question.

Partial Overrides and Inheritance

This is where the precedence chain becomes genuinely useful instead of just hierarchical. Every severity field in a config is nullable. Any severity can be omitted, and omitting it signals inherit from the next level up. An administrator can override only one or two severities at a scope and let the rest cascade.

Consider a project that only cares about tightening its urgent window. The team sets the project-level urgent hours to a stricter value and leaves critical, high, medium, and low null. When the resolution runs for an urgent finding in that project, it finds the project value and stops. When it runs for a high finding in the same project, it skips the null project field and falls through to the company level, then global, then hardcoded, until it finds a non-zero value. The result is a config that says exactly one thing and inherits everything else, with no duplication of the values the team did not want to change.

This inheritance is also why recalculation is not optional. The moment a parent scope changes, every child finding that was inheriting from that scope has a stale deadline until something recomputes it. The bulk recalculation tools exist to close that gap on demand.

The Recalculation Formula

Here is the core math. For a finding, the deadline is computed as the finding’s creation time, plus the hours its severity resolves to, plus the hours it has spent paused:

new_deadline = finding.created_at
             + ResolveHours(severity, project, company) hours
             + finding.sla_paused_hours hours

Three inputs, one output. The creation time anchors the window to when the finding first appeared. The resolved hours come from the precedence chain we just walked. The paused hours restore any time the clock was legitimately stopped. Every recalculation, whether for a single finding or thousands at once, runs this same expression. There is no separate code path that computes deadlines differently in different situations, which is exactly why the number stays trustworthy.

The bulk recomputation applies this formula to every open finding in scope. Open means the status is not one of closed, false positive, accepted risk, or not accessible, and the finding has a non-null deadline to begin with. Findings that are already resolved or out of scope are left untouched, because their SLA window is no longer a live concern.

Why Pause Hours Are Added Back

The pause term is the part that most people miss, and it is the part that keeps the agreement honest. When a finding is legitimately paused, real time keeps passing, but that time should not count against the SLA window. A common case is a finding that depends on a vendor patch that has not shipped yet. The team cannot remediate, so holding them to the original clock would be unfair and would manufacture an SLA breach that nobody could have prevented.

PMAP tracks accumulated pause time in a per-finding field. When the deadline is recalculated, those paused hours are added back into the window. The effect is to push the deadline forward by exactly the amount of time the clock was stopped. The agreed amount of active time stays constant. If the contract says a high finding gets 168 active hours, then 168 active hours is what the team gets, regardless of how many calendar days passed while the finding was paused waiting on someone else.

This is why pausing and resuming are first-class events in the recalculation story rather than afterthoughts. The SLA resume path explicitly recomputes the deadline after accounting for accumulated pause hours. Without the add-back, a finding that was paused for a month would still breach on its original date, and the metric would punish teams for delays outside their control.

When Recalculation Fires

A formula is only as reliable as the moments it runs. The finding service holds a reference to the SLA config service and asks it to resolve hours in four distinct situations:

  • On finding creation. When a finding is first written, the service sets its initial deadline from the resolved hours. This is the baseline, and at creation there are no paused hours yet.
  • On finding update when severity changes. If a retest or analyst review changes the severity, the deadline is recalculated so the window matches the new risk band. This is the trigger most people think of first, and it gets its own section below.
  • On SLA resume. When a paused finding resumes, the deadline is recomputed after subtracting the accumulated pause hours from the clock, which in formula terms means adding those hours into the window so the remaining active time is preserved.
  • On bulk status change. When findings move through a bulk status operation, affected deadlines are recalculated so the values stay consistent with the new states.

Beyond these per-finding triggers, there is the config-driven path. When a company or project SLA config is saved, the save handler immediately triggers a recalculation for all open findings in that scope. Changing the policy and recomputing the deadlines happen together, so you never end up with a new threshold that applies only to findings created after the change. The save returns the count of recalculated findings in a response header, so the caller can confirm how many records the policy change touched without making a separate query.

Resetting the Notification Flag

Recalculation does one more thing that is easy to overlook. During bulk recalculation, if the newly computed deadline is in the future, the finding’s SLA notification flag is reset so the notification pipeline can fire again as the extended deadline approaches.

The reasoning is practical. Suppose a finding had already passed its old deadline and its breach notification had fired. Then an administrator widens the company SLA window, and recomputation pushes that finding’s deadline back into the future. The finding is no longer in breach. Leaving the notified flag set would mean the system never alerts anyone again, even though there is now a fresh future deadline worth warning about. Resetting the flag re-arms the notification so the warning re-triggers at the right time relative to the new deadline. The deadline math and the notification state stay in agreement.

On-Demand Bulk Recalculation

Most recalculation happens automatically as a side effect of saving a config or changing a finding. There is also an explicit path for recomputing deadlines without changing anything.

Each scope exposes a recalculate action that re-runs the deadline computation for all open findings in that company or project without touching the stored config. The most common reason to use it is a change to the platform global defaults. Because global defaults sit at level three of the precedence chain, editing them in admin settings changes what many findings should resolve to, but it does not by itself rewrite any finding’s deadline. The on-demand recalculation is how you propagate that change to every affected finding deliberately, when you are ready, rather than as an automatic cascade.

It is worth being honest about the cost. All of this work runs synchronously inside the request. There is no background queue. For a large company with many thousands of open findings, the bulk recalculation can take a noticeable amount of time, because it walks every open finding, computes the new deadline, and writes the results in a single transactional batch. The trade-off is intentional. A synchronous, transactional recompute means that when the call returns, the deadlines are authoritative. There is no eventual-consistency window during which some findings carry old deadlines and some carry new ones. For SLA breach reporting that feeds compliance evidence, that consistency is worth more than raw speed.

How a Severity Change Reshapes the Deadline

Of all the triggers, a severity change is the one most likely to surprise people, so it deserves a worked example.

Imagine a finding created as medium severity. With the default mapping, medium resolves to 720 hours, which is thirty days. The deadline is set to thirty days after creation. Now a retest reveals the finding is actually exploitable in a way that justifies critical severity. An analyst updates the severity to critical.

On that update, the deadline is recalculated. The formula re-runs with the new severity. Critical resolves to 72 hours, three days, instead of 720. The new deadline is the original creation time plus 72 hours plus any paused hours. Crucially, the anchor is still the creation time, not the moment of the severity change. The window is measured from when the finding first appeared, not from when somebody noticed it deserved a tighter clock.

That has a sharp consequence. If the finding was created more than three days ago, the recomputed critical deadline is already in the past. The finding is immediately in SLA breach the instant its severity is corrected. This is the correct behavior. The exposure existed at critical severity from the moment the finding was created. The earlier medium label was simply wrong, and the corrected deadline reflects the real risk timeline rather than rewarding the period during which the severity was understated.

The reverse case is just as clean. Downgrade a finding from critical to low, and the deadline recomputes from 72 hours to 2160 hours, ninety days. A finding that looked overdue under the critical clock can return to a comfortable position under the low clock, and if its new deadline lands in the future, the notification flag resets so a future warning can still fire. The math does not care which direction the severity moves. It always rebuilds the deadline from the same three inputs.

This anchoring to creation time is the single most important thing to internalize about recalculation. The deadline is not a countdown that restarts on every edit. It is a recomputed fact about the total window a finding is allowed, measured from its origin, adjusted for legitimately paused time. That property is what makes SLA breach reporting defensible. Treating SLA deadlines as a derived compliance control rather than a manual field is also what makes them audit-ready, because every deadline can be reconstructed from inputs that are themselves recorded.

Why This Math Matters for Compliance

It is tempting to treat SLA deadlines as an internal operations nicety. In a regulated program, they are evidence. When an auditor asks how long a critical vulnerability stayed open before remediation, the honest answer depends on a deadline that was computed correctly at every step. Several external frameworks give these timelines weight. NIST SP 800-40 Rev. 4 addresses remediation timelines as part of patch and vulnerability management, CISA BOD 22-01 sets concrete remediation due dates for known exploited vulnerabilities, and ISO/IEC 27001:2022 frames timely remediation within operations security. A deadline that quietly drifts because it failed to recompute after a severity change or a pause undermines the very evidence these frameworks expect you to produce.

This is why the recalculation behavior is conservative by design. It anchors to creation time so the window reflects real exposure. It adds pause hours back so teams are measured on active time, not calendar time they could not control. It recomputes on every material change and on demand after a policy shift, so the stored deadline never lags the policy. And it runs the same formula everywhere, so two findings with the same severity, creation time, and pause history will always carry the same deadline. Predictability is the whole point. An SLA control that produces different answers in different code paths is not a control at all.

For the broader picture of how SLA timelines, approvals, and audit trails fit into a defensible compliance program, see our pillar guide on vulnerability management compliance and audit. For setting up the thresholds and escalation routing that feed this math, see the companion piece on SLA thresholds and escalation routing (P2-26). For a plain-language definition of what a vulnerability management SLA is in the first place, see the SLA primer (P7-06).

Putting It Together

The deadline you see on a finding is the output of a small, stable formula. Take the finding’s creation time, add the hours its severity resolves to through the five-level precedence chain, and add back any hours the finding spent paused. The severity hours come from the most specific scope that has a value, with project beating company beating global beating the hardcoded defaults of urgent 24, critical 72, high 168, medium 720, and low 2160. Partial overrides let each scope change only what it cares about and inherit the rest.

Recalculation is what keeps that output honest as the inputs change. It fires when a finding is created, when its severity changes, when it resumes from pause, and when bulk status changes ripple through. It fires automatically when a config is saved and on demand when you need to propagate a global-defaults change. It resets the notification flag when a deadline moves into the future so warnings re-arm correctly. And it always anchors to creation time, so the window measures real exposure rather than restarting on every edit.

Understand those three inputs and the moments they get recomputed, and you understand why your SLA breach numbers can be trusted. The deadline is not a date someone typed. It is a fact the system can rebuild, the same way, every time.

To see how SLA deadlines function as a recorded compliance control alongside the rest of your audit evidence, read the audit and compliance datasheet and see how PMAP keeps SLA deadlines honest as severity changes.

Frequently Asked Questions

How is an SLA deadline calculated?

An SLA deadline is the finding’s creation time plus the number of hours its severity resolves to, plus any hours the finding has spent paused. The severity hours are resolved through a precedence chain that checks the project config first, then the company config, then global defaults, then hardcoded per-severity values. The paused hours are added back so the agreed amount of active time stays constant regardless of how long the clock was stopped.

What are the default SLA hours per severity?

The hardcoded fallback values are urgent 24 hours, critical 72 hours, high 168 hours, medium 720 hours, and low 2160 hours. These apply when no project, company, or global config sets a value for that severity. There is also a final fallback of 168 hours that guarantees resolution never returns an empty or zero window.

What happens to the deadline when a finding is paused?

While a finding is paused, calendar time keeps passing but is not supposed to count against the SLA window. PMAP tracks the accumulated pause hours and adds them back into the deadline on recalculation. The deadline moves forward by exactly the time the clock was stopped, so the team still gets the full agreed window of active time. When the finding resumes, the deadline is recomputed with those pause hours included.

Which level wins when a company and a project both set thresholds?

The project-level threshold wins. The resolution order is project, then company, then global defaults, then hardcoded values, then the final 168-hour fallback. A level is skipped if its config is missing or if the specific severity field is null or zero, and the first non-zero positive value is used. This lets a project override only the severities it cares about and inherit the rest from the company or global level.

Does changing a finding’s severity immediately move its deadline?

Yes. When severity changes, the deadline is recalculated using the new severity hours, but the window is still anchored to the finding’s original creation time, not the moment of the change. If a finding is upgraded to a higher severity and it was created longer ago than the new shorter window allows, it can be in SLA breach immediately. If it is downgraded, its deadline can move into the future, and the notification flag resets so warnings can re-fire.

What is bulk SLA recalculation and when should I run it?

Bulk recalculation re-runs the deadline formula for every open finding in a company or project. It happens automatically when you save an SLA config so the new policy applies to existing findings. There is also an on-demand action that recomputes deadlines without changing the config, which is the right tool after you edit the platform global defaults in admin settings, since that change does not rewrite finding deadlines on its own. The operation runs synchronously in a single transaction, so when it returns, every deadline in scope is authoritative.

Why does the deadline anchor to creation time instead of the last edit?

Anchoring to creation time means the deadline reflects the total window a finding is allowed from the moment the exposure first appeared, not a countdown that restarts on every edit. This keeps SLA breach reporting defensible. If the window restarted whenever someone corrected a severity, a long-standing vulnerability could appear compliant simply because it was recently touched. Anchoring to creation time, adjusted only for legitimately paused hours, ensures the deadline measures real exposure time.

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.