Vulnerability Management

SLA Thresholds and Three-Level Escalation Routing

By PMAP Security Team 19 min read

An SLA on a vulnerability is a promise. It says a finding of a given severity will be resolved inside a defined window, and that the clock starts the moment the finding is discovered. Most security programmes can recite the promise. Far fewer can prove that every open finding sits under the correct deadline, that the deadline reflects the right contractual tier, and that a breach reaches a named person on a predictable schedule. The gap between the policy on paper and the deadline on the record is where audit findings live.

This article is about closing that gap at the configuration layer. It walks through how an SLA escalation policy is actually built in PMAP: where severity-to-hours thresholds are defined, how company and project overrides inherit from a global default, what happens to existing deadlines when you change a threshold, and how a three-level escalation chain routes breached findings to the right people. If you want the metric side of SLAs, breach rate and mean time to resolve, that lives in our KPI and SLA dashboards article. If you want the exact arithmetic of how a single deadline is recomputed, that is covered in our SLA deadline recalculation deep-dive. Here the focus is setup: thresholds, inheritance, escalation, and the recalculation behaviour that keeps the two in sync.

Why SLA Configuration Is Where Compliance Begins

Enterprise security programmes rarely run on a single SLA. A regulated banking client may demand critical findings closed in 24 hours. An internal low-risk project may be comfortable with months. A managed-service contract may carry penalties tied to a specific resolution window per severity tier. The commitments vary by client, by asset class, and by engagement type, and they change as contracts renew.

When those commitments are tracked in a spreadsheet and applied by hand, three failures follow predictably. First, some findings get no deadline at all, because nobody remembered to set one for a new project. Second, deadlines drift out of date, because a contract tightened but the existing open findings were never re-stamped. Third, a breach happens and nobody is notified, because the escalation path lived in someone’s memory rather than in the system.

Centralising threshold management removes all three. When severity-to-hours mappings are defined in one place, layered with scope-level overrides, and propagated automatically to every affected finding, the deadline on each record becomes auditable. An assessor can ask which policy applies to a given finding and get a deterministic answer. That determinism is the foundation that compliance frameworks expect. Frameworks such as NIST SP 800-40 Rev. 4 on enterprise patch and remediation timelines, and binding directives like CISA BOD 22-01 for known exploited vulnerabilities, all assume that a remediation deadline is defined, applied, and enforceable. SLA configuration is the control that makes that assumption true.

This is the broader theme of our pillar on vulnerability management compliance and audit, which places SLA enforcement inside the full evidence chain an auditor walks. The current article narrows to the mechanics of building that policy.

Severity-to-Hours Thresholds at Three Scopes

The unit of SLA configuration in PMAP is a severity-to-hours mapping. For each of five severity values, urgent, critical, high, medium, and low, you set the number of hours a finding may remain open before it breaches. That mapping can be defined at three distinct scopes, and the scopes form a hierarchy.

At the top sits the global default. A platform administrator sets platform-wide SLA hours per severity in the Admin System tab, along with a global escalation ladder. This is the baseline every company inherits unless it says otherwise. It exists so that a freshly created company is never without a deadline policy.

Below the global default sits the company override. A company administrator or manager opens the SLA Policy tab on a specific company and sets per-severity hours that apply to every finding in that tenant. This is where a contractual commitment for a particular client gets encoded. The company form is five numeric inputs, one per severity, and a blank field means inherit the global default for that severity.

Below the company sits the project override. A project lead can narrow deadlines further for a single engagement using the same five-field form at project scope. This is where a high-risk project tightens its critical window below what the parent company allows, without affecting any other project in the company.

The three scopes are not three separate copies of the policy. They are layers. A project override does not need to restate the company’s medium and low thresholds if it only wants to tighten critical. It sets critical and leaves the rest to inherit. That layering is what makes the model practical at scale, and it is governed by the resolution waterfall.

The Four-Level Resolution Waterfall

When PMAP needs to know how many hours a finding of a given severity gets, it does not read a single field. It runs a resolution function that walks a strict precedence order until it finds a usable value. The function takes the severity, the project, and the company, and it applies four levels in sequence.

  1. Project config. If a project-scoped SLA config exists and its threshold for this severity is set, that value wins.
  2. Company config. If the project level did not supply a value, the company-scoped config for the owning tenant is consulted next.
  3. Global admin defaults. If neither scope supplied a value, the platform-wide defaults from admin settings are used.
  4. Built-in fallback. If even the global defaults are absent, hardcoded values apply: urgent 24 hours, critical 72 hours, high 168 hours, medium 720 hours, low 2160 hours. A final safety net of 168 hours (7 days) covers any severity that still resolved to nothing.

The order is deliberate. The most specific scope that has an opinion wins, and the chain only descends when a level stays silent. This is what guarantees the property that matters most for compliance: every finding always resolves to a meaningful deadline. There is no configuration gap that can leave a finding untracked, because the built-in fallback at the bottom always answers.

The built-in numbers are worth reading as a sensible default rather than a recommendation. Urgent at 24 hours and critical at 72 hours reflect the kind of aggressive window that exploited-vulnerability guidance expects. Medium at 720 hours is 30 days and low at 2160 hours is 90 days. Most programmes will override these long before they rely on them, but they exist so the system is never silent.

Partial Overrides and Inheritance

The waterfall only works because individual severity fields can be left empty. Each threshold field on a config is nullable, and an empty field is the signal to fall through to the next level for that one severity. This is what makes partial overrides possible. A company can override only critical and high, the two tiers its contract actually constrains, and let medium and low inherit the global default. The config row exists, but it speaks only for the severities it cares about.

One detail prevents a common foot-gun. A severity value of zero is treated exactly like null, meaning inherit from the next level. A zero-hour SLA is not a valid threshold, so the system reads it as an absence rather than as an impossible deadline of right now. In waterfall terms, a level is skipped whenever its config row is missing or its specific severity field is null or zero, and the first non-zero positive value found wins. That single rule, first non-zero wins, is the whole logic of inheritance.

The practical effect is that overrides stay minimal and auditable. A reviewer reading a project config sees only the severities that project intentionally changed. Everything else is visibly inherited, which makes the delta between a project’s policy and its parent obvious at a glance.

Automatic Deadline Recalculation on Save

A threshold change that does not touch existing findings is almost worthless. If you tighten critical from 72 hours to 24 hours but the fifty critical findings already open keep their old 72-hour deadlines, your policy and your records have diverged on the day you changed them. PMAP closes this by recalculating automatically.

When a company or project SLA config is saved through its upsert endpoint, the handler does the database write and then, in the same request, recomputes the deadline for every open finding in that scope. You do not trigger a separate job, and you do not wait for a nightly batch. By the time the save response returns, the deadlines have moved.

The response also tells you how many findings changed. The number of recalculated findings comes back in an X-Recalculated-Count response header rather than in the body, which keeps the body shape identical to a plain read of the config. A security manager who saves a tightened policy can read that header and confirm the change propagated to the expected population. If you tightened a company that holds 50 open critical findings and the header says 50, the propagation is verified. That header is a small thing, but it turns a config save into an auditable event with a measurable blast radius.

The Recalculation Formula

The recomputed deadline is not just created-time plus the new hours. It accounts for time the SLA clock was paused. For each open finding in scope, the new deadline is computed as the finding’s creation timestamp, plus the resolved SLA hours from the waterfall, plus the finding’s accumulated paused hours.

That third term matters. A finding can have its SLA clock paused and resumed multiple times, for example while it waits on a third party or a change window. The paused duration accumulates on the finding, and recalculation always adds the full accumulated pause back in. Without that term, recalculating a deadline would silently shorten it by erasing every pause the finding ever had. With it, a tightened threshold applies fairly to the active time only.

One scoping note. Only open findings are recalculated. Findings in a terminal state, closed, false positive, accepted risk, or not accessible, are left alone, because there is no live deadline to move. The exact mathematics of this formula, including how the pause term interacts with multiple resume cycles, is the subject of our SLA deadline recalculation deep-dive. Here it is enough to know that the formula is deterministic and that it respects paused time.

On-Demand Bulk Recalculation

Automatic recalculation on save covers the case where you change a company or project threshold. It does not, on its own, cover one important gap: the global default. When a platform administrator edits the platform-wide SLA hours in admin settings, every company that inherits those globals is affected, but no single company config was saved to trigger their recalculation.

The on-demand recalculate endpoints exist for exactly this. A POST to the recalculate path for a company or a project recomputes the deadlines of all open findings in that scope without changing the stored config at all. It uses the same waterfall and the same formula as the automatic path. It simply runs them on demand, returning an updated_count so you can see how many findings moved.

This decouples recalculation from configuration change. After editing the global defaults, an administrator can sweep the affected companies and re-stamp their findings, even though those companies own no override of their own. It is also useful as a reconciliation tool. If you ever suspect a deadline has drifted out of sync with the policy that should govern it, running the recalculate endpoint with no config change re-asserts the policy and reports what it had to fix.

A constraint to keep in mind: recalculation runs synchronously inside the request. For a tenant with many thousands of open findings, the recalculate call has elevated latency, and that is by design. The work is done as a single transactional batch write rather than an async job you have to poll, so when the call returns, the deadlines are already consistent. The trade is response time for simplicity and immediacy, which is usually the right trade for an administrative action you run deliberately.

Notification Reset on Deadline Extension

Recalculation can move a deadline in either direction. Tightening a threshold pulls deadlines earlier; loosening one, or adding back a long pause, can push them later. The second case carries a subtle risk around notifications, and PMAP handles it explicitly.

Each finding carries a flag that records whether its SLA notification has already fired. If a finding was approaching breach and its notification went out, that flag is set so the same alert does not repeat. Now suppose recalculation moves that finding’s deadline into the future, well past the point where the earlier warning made sense. The earlier notification is stale. The finding deserves a fresh warning as the new, later deadline approaches.

To allow that, recalculation resets the notification flag to false whenever the new deadline is in the future. Clearing the flag lets the notification pipeline re-fire as the extended deadline nears. The reset is conditional on purpose. If the new deadline is already in the past, meaning the finding is breached right now, the flag is not reset, because re-firing a warning for an already-breached finding would be noise rather than signal. The rule reads cleanly: a future deadline re-arms the notification, a past deadline does not.

This is a small behaviour with an outsized effect on trust in the system. It means a loosened SLA does not quietly suppress the warnings a finding should still get, and a breach does not generate a spurious second alert. The notification state always reflects the current deadline rather than a stale one.

Three Escalation Contacts With Day-After-Breach Triggers

Thresholds decide when a finding breaches. Escalation decides who hears about it and on what schedule. In PMAP, every SLA config, at company or project scope, can carry up to three escalation contacts, and each contact defines its own timing.

An escalation contact is a pair: a user, and a number of days after breach at which that user should be engaged. Level one might be the finding’s owner, engaged the day the SLA breaches. Level two might be the team lead, engaged three days after breach if the finding is still open. Level three might be a security manager or an account owner, engaged after a week. The three levels let a programme model the realistic shape of an escalation, where a missed deadline starts with the person closest to the work and climbs toward management only if it stays unresolved.

Two design choices make the chain flexible rather than rigid. First, all three levels are independent and optional. You can configure level two without level one, because the levels are not required to be sequential. A programme that wants a single management-level escalation at day five and nothing before it can set only one contact at whatever level it likes. Second, the chain inherits the same way thresholds do. When a company or project defines no escalation contacts of its own, the global escalation ladder configured by the platform administrator in admin settings applies. So escalation, like the threshold itself, always has a defined fallback rather than failing silent.

The contacts are part of the config, which means they are saved through the same upsert and reverted through the same delete as the thresholds. They are not a separate subsystem to maintain. When you set a company’s SLA policy, you set its escalation chain in the same form, and both live or die together.

It is worth being precise about the boundary here. This feature owns the configuration of the escalation chain, who is on it and when each level triggers. The act of walking that chain on a live breached finding, logging each escalation and acknowledging it, belongs to the finding lifecycle rather than to SLA configuration. The policy lives here. The execution against a specific finding lives with the finding.

Reverting to Inherited Defaults

Setting an override is half of a useful configuration model. The other half is removing one cleanly. A contract ends, a project closes out, a company that needed a special policy goes back to standard terms. When that happens you want the override gone and the finding population back under the level above it, without manually re-entering the parent’s numbers.

PMAP handles this with deletion. Removing a company or project SLA config drops the scope-level override entirely. On the next resolution cycle, findings in that scope fall through to the next level, the company config for a deleted project override, or the global defaults for a deleted company override. The delete returns HTTP 204, a clean no-content confirmation that the override is gone.

Because the waterfall is evaluated fresh each time hours are resolved, you do not have to copy the parent’s thresholds down into the child before deleting. The child simply stops answering, and the parent’s policy takes over automatically. This is the inverse of the partial-override behaviour. Where a partial override lets a scope speak for only some severities, deletion makes a scope speak for none, handing the entire policy back to the level above. The two together give you a configuration surface that scales up to a precise per-engagement policy and collapses back down to a shared default with a single action.

A note on identity and access. Every SLA config endpoint, whether you are reading, saving, deleting, or recalculating, lives inside the authenticated, RBAC-scoped API. Who can change a company’s SLA policy is governed by the caller’s role and scope, the same access model that governs the rest of the platform. There is no separate, weaker door into SLA configuration. The access control that protects your tenant data also protects the deadlines applied to it.

How PMAP Keeps Every Finding on a Meaningful Deadline

Step back from the individual mechanics and the design reads as a single guarantee: no finding is ever without a deadline, and every deadline reflects the most specific policy that has an opinion about it. That guarantee is assembled from a few deliberate behaviours working together.

The four-level waterfall ensures resolution always terminates in a real number, even when every override is absent. Nullable fields and the first-non-zero-wins rule let overrides be partial, so policy stays minimal and the inheritance is visible. Automatic recalculation on save, reported through the X-Recalculated-Count header, keeps the existing finding population aligned with the policy the moment it changes. On-demand recalculation extends that alignment to global-default edits and serves as a reconciliation tool. The notification reset keeps alerting honest as deadlines move. The three-level escalation chain, with its own inheritance and day-after-breach timing, routes the consequence of a breach to the right people on a predictable schedule. And deletion makes reverting an override as clean as setting one.

None of these behaviours is exotic. Their value is that together they remove the manual reconciliation that usually sits between a policy and the records it governs. The deadline on each finding is not something a person remembered to set. It is something the system resolved, recalculated, and can re-resolve on demand. That is what makes an SLA escalation policy in PMAP defensible to an auditor rather than merely declared.

If you want to put this into practice, our step-by-step guide to configuring SLA thresholds and escalation walks the exact screens, from setting global defaults to saving a company override and reading the recalculation count. For the broader compliance context this sits inside, see the vulnerability management compliance and audit pillar. And for the question SLA configuration ultimately serves, what does SLA mean in vulnerability management, see our explainer on vulnerability management SLAs.

Frequently Asked Questions

What happens to a finding if I never set any SLA threshold?

It still gets a deadline. The resolution waterfall always terminates in a value. If no project, company, or global configuration supplies hours for a finding’s severity, the built-in fallback applies: urgent 24 hours, critical 72 hours, high 168 hours, medium 720 hours, low 2160 hours, with a final safety net of 168 hours. There is no configuration gap that can leave a finding untracked.

If I change a company’s SLA threshold, do existing open findings update?

Yes, automatically. Saving a company or project SLA config recomputes the deadline for every open finding in that scope in the same request, before the response returns. The number of findings updated comes back in the X-Recalculated-Count header so you can confirm the change reached the population you expected. Closed, false-positive, accepted-risk, and not-accessible findings are not touched.

How do project, company, and global SLA settings interact?

They form a four-level waterfall resolved per severity. A project threshold wins if set, otherwise the company threshold, otherwise the global admin default, otherwise the built-in fallback. Each severity is resolved independently, so a project can override only critical and let the other severities inherit. A field left empty, or set to zero, is treated as inherit from the next level, and the first non-zero value found wins.

What is the formula for a recalculated SLA deadline?

For each open finding, the new deadline equals the finding’s creation time, plus the resolved SLA hours from the waterfall, plus the finding’s accumulated paused hours. The paused term ensures that recalculating a deadline never silently shortens it by erasing time the SLA clock was legitimately stopped. The precise interaction of the pause term across multiple resume cycles is covered in our SLA deadline recalculation deep-dive.

How does escalation routing work after a breach?

Each SLA config can define up to three escalation contacts, each a pairing of a user with a number of days after breach at which that user is engaged. The levels are independent and optional, so they do not have to be set in sequence. If a company or project defines no contacts, the global escalation ladder set by the platform administrator applies. This feature configures the chain; walking it on a live breached finding belongs to the finding lifecycle.

Can I recalculate deadlines without changing any configuration?

Yes. A dedicated recalculate endpoint recomputes all open-finding deadlines in a company or project scope without touching the stored config, returning an updated_count. It is the right tool after editing global defaults, since that change affects inheriting companies without any company config being saved, and it doubles as a reconciliation action when you want to re-assert the current policy across a scope.

Why does my recalculation request take a while on a large tenant?

Recalculation runs synchronously as a single transactional batch write rather than as an async background job. For a tenant with many thousands of open findings, the request has elevated latency by design. The benefit is immediacy and consistency: when the call returns, every deadline in scope is already aligned with the current policy, with no separate job to poll or partial state to reconcile.

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.