# Severity Rubric

This rubric defines measurable, repeatable criteria for assigning severity to every
control entry on every domain page. It exists to remove ambiguity and intuition from
severity selection. Authors **MUST** apply severity by matching a candidate
misconfiguration to the criterion below — not by gut feel, vendor marketing, or
copy-paste from another framework.

The rubric is referenced by `docs/control-template.md` (mandatory field #3 —
"Severity tag"). Every control's severity tag (`<span class="sev sev-*">`) is
justified by the criterion in this document.

---

## CRITICAL

**Criterion:** Misconfiguration provides a direct, single-step path to data
exfiltration, full account takeover, or unauthenticated remote code execution
against a production-equivalent resource. No additional vulnerability, social
engineering, or pivot is required to realize the impact.

**Examples (drawn from the content matrix):**

- Root / global-admin / tenancy-administrator account without hardware MFA enabled.
- S3 bucket, Azure Blob container, GCS bucket, or OCI Object Storage bucket with
  world-readable / `AllUsers` ACL containing PII or credentials.
- EC2 instance with IMDSv1 enabled paired with an instance-profile role granting
  broad permissions (`iam:*`, `s3:*`, `sts:AssumeRole *`).
- Kubernetes API server (EKS / AKS / GKE / OKE) exposed to `0.0.0.0/0` without
  authentication required.
- KMS / Key Vault / Cloud KMS / OCI Vault key with a key policy allowing `*`
  principal to `Decrypt` or `Sign`.

**Most commonly applies to:** PREVENTIVE controls — these are configurations that
must never be in the unsafe state. CRITICAL DETECTIVE controls exist (e.g., absent
CloudTrail / Activity Log / Audit Log on a production tenant) but are rarer; see
"Control Type modifier" below.

---

## HIGH

**Criterion:** Misconfiguration creates significant attack-surface expansion or a
clear privilege-escalation path that requires one additional step (a stolen
credential, an additional vulnerability, or a pre-positioned attacker) to convert
into account takeover, data exfiltration, or RCE.

**Examples (drawn from the content matrix):**

- IAM user (AWS) / service principal (Azure) / service account (GCP) / OCI user
  with `*:*` or owner-equivalent policy attached but MFA enforced.
- CloudTrail / Azure Activity Log / Cloud Audit Logs / OCI Audit disabled in a
  single region or tenancy compartment, while still enabled elsewhere.
- Network Security Group, Security Group, VPC firewall rule, or OCI Security List
  allowing `0.0.0.0/0` on a management port (22, 3389, 5985, 5986, 1433, 3306,
  5432, 27017, 6379, 9200).
- S3 / Blob / GCS / OCI Object Storage bucket public-read enabled but content is
  static marketing material (no PII) — the surface exists, the data class
  reduces severity from CRITICAL.
- Storage account without "secure transfer required" / bucket without "uniform
  bucket-level access" / S3 without "block public access" account setting.

**Most commonly applies to:** PREVENTIVE controls (over-broad IAM policies, open
ports) and DETECTIVE controls (missing trail in a single region). Pair with
control type when emitting the tag.

---

## MEDIUM

**Criterion:** Defense-in-depth control whose absence raises attacker cost or
reduces detection fidelity but does not directly enable compromise. A skilled
attacker can still complete the kill chain without these controls present;
their value is forensic, containment-time, or marginal hardening.

**Examples (drawn from the content matrix):**

- VPC Flow Logs / NSG Flow Logs / VPC Flow Logs (GCP) / OCI VCN Flow Logs not
  enabled.
- GuardDuty / Microsoft Defender for Cloud / Security Command Center / OCI Cloud
  Guard not enabled in non-production accounts or non-default compartments.
- AWS Config / Azure Policy / GCP Organization Policy / OCI compartment policy
  optional rules missing (e.g., recommended but not mandatory CIS rules).
- S3 / Blob / GCS / OCI Object Storage versioning disabled on non-critical
  buckets.
- IAM Access Analyzer / Azure Entra Permissions Management / IAM Recommender not
  scheduled.

**Most commonly applies to:** DETECTIVE and RESPONSIVE controls — logging,
monitoring, anomaly detection. These rarely qualify as PREVENTIVE; their absence
does not block an attack, only its observation or aftermath.

---

## LOW

**Criterion:** Configuration hygiene with minimal direct risk; absence affects
observability completeness, compliance posture, or operational tidiness rather
than the attacker's ability to compromise the environment.

**Examples (drawn from the content matrix):**

- IAM access key older than 90 days but rotated and scoped to a specific
  workload.
- Missing optional AWS Config rule (e.g., `acm-certificate-rsa-check`) when an
  equivalent SCP or organization-wide control is enforcing the requirement.
- Tag-policy or naming-convention drift on non-production resources.
- Information-disclosure header gaps (`X-Frame-Options` missing on internal
  consoles) where the surface is already authenticated.
- Documentation / runbook gaps for non-critical playbooks.

**Most commonly applies to:** RESPONSIVE controls and compliance-posture controls.
A LOW PREVENTIVE control is uncommon — if it is PREVENTIVE and absent has minimal
impact, the control is usually optional rather than tracked.

---

## Control Type modifier

Per PITFALLS.md B-14, severity alone is insufficient. A CRITICAL DETECTIVE control
(e.g., "no audit log in any region") is operationally different from a CRITICAL
PREVENTIVE control (e.g., "root account without MFA"). The DETECTIVE failure
delays discovery; the PREVENTIVE failure enables the breach.

**Always pair severity with control type:**

- **PREVENTIVE:** Stops the unsafe state from existing. Examples: deny-by-default
  bucket policy, hardware MFA enforcement, KMS key policy without wildcard
  principals.
- **DETECTIVE:** Surfaces the unsafe state after it exists. Examples: CloudTrail,
  GuardDuty findings, Defender for Cloud alerts, AWS Config non-compliant
  resource notification.
- **RESPONSIVE:** Acts on the unsafe state once detected. Examples: EventBridge
  rule that auto-remediates public S3 buckets, Azure Logic App that disables a
  user on impossible-travel sign-in, SOAR playbook for IAM credential rotation.

**Pairing rule:** Render severity and control type as two adjacent spans in the
control header:

```html
<span class="sev sev-critical">
  <span class="sev-icon" aria-hidden="true">&#x26d4;</span>
  <span class="sev-label">CRITICAL</span>
</span>
<span class="control-type">PREVENTIVE</span>
```

Reviewers reading the rubric next to a candidate control must reach the same
severity AND control type independently. If two reviewers disagree, the criterion
above is the tiebreaker — not opinion, not vendor severity rating, not CVE score.

---

## Applying severity consistently

Per PITFALLS.md B-10, severity drift is the most common failure mode of multi-
author hardening references. The rubric exists to prevent two patterns:

1. **Inflation:** Tagging everything CRITICAL to signal importance. This destroys
   triage value — readers cannot tell which controls warrant pager-grade response
   versus next-sprint backlog.
2. **Deflation by familiarity:** Tagging known-bad configurations MEDIUM because
   "every cloud has this issue." Familiarity is not severity; the criterion is.

**Enforcement:**

- Severity is applied **from this rubric**, not by intuition or vendor labels.
- Every control's severity tag in the rendered HTML must match the criterion
  above when traced back. The validation script `build/check-severity-markup.sh`
  (see Phase 3) greps for three-channel severity markup; reviewers verify the
  criterion match during content review.
- Disagreements are resolved by re-reading the relevant criterion section, not
  by majority vote.
- If a candidate misconfiguration does not cleanly match exactly one criterion,
  the author **must** record the ambiguity in the control's threat-model
  "Attack vector" sub-field and choose the higher severity. Never round down on
  ambiguity.

See `docs/control-template.md` for the full markup specification that consumes
this rubric.
