keycloak / keycloak/keycloak-github-bot

Automatic severity assignment based on CVSS score

Open
#67 0 comments 0 reactions 0 assignees View on GitHub
kind/feature status/triage
Dominant language
Java
Stars
9
Forks
11
Avg merge
2d 16h
Merged PRs (30d)
2

Description

## Summary

When a maintainer requests a CVE via @security secalert and includes a CVSS score in the issue body, the keycloak-github-bot should automatically parse the score, map it to the correct severity label using CVSS 3.1 ranges, and apply the label to the issue. This also replaces the current Red Hat-specific severity labels with industry-standard CVSS 3.1 nomenclature.

## Problem statement

Today, severity labels on secalert submissions are assigned manually. This creates two problems:

1. Manual label assignment is error-prone and slow. Maintainers already provide the CVSS score in the issue body, but then someone still has to manually pick the right severity label. That's redundant work and a source of inconsistency.

2. The current label naming doesn't match industry standards. The existing labels (severity/important, severity/moderate, severity/low, severity/critical) follow Red Hat's internal lingo. The rest of the security world — NVD, FIRST, Jira security plugins, GitHub advisories — uses CVSS 3.1 nomenclature: None, Low, Medium, High, Critical. This mismatch causes confusion when cross-referencing with external advisories and when onboarding people who aren't familiar with Red Hat conventions.

## Proposed solution

### Label migration

Replace the current severity labels with CVSS 3.1-aligned labels:

|Current label|New label|CVSS 3.1 score range|
|---|---|---|
|_(no equivalent)_|severity/none|0.0|
|severity/low|severity/low|0.1 – 3.9|
|severity/moderate|severity/medium|4.0 – 6.9|
|severity/important|severity/high|7.0 – 8.9|
|severity/critical|severity/critical|9.0 – 10.0|

### Automatic assignment flow

When the bot processes a @security secalert command:

1. Parse the issue body for a CVSS score (e.g., CVSS: 7.5, CVSS Score: 7.5, or a CVSS vector string from which the base score can be extracted). Or more simple, use the string in the CVSS score to apply the label: CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:N (6.5 Medium)
2. Map the score to the corresponding severity label using the CVSS 3.1 ranges above.
3. Apply the label to the issue automatically.
4. If no CVSS score is found in the body, skip auto-assignment and leave the label unset (don't guess).

```mermaid
flowchart TD
A["Maintainer runs @security secalert"] --> B{"CVSS score present in body?"}
B -- No --> C["Skip severity label assignment"]
B -- Yes --> D["Parse CVSS score"]
D --> E{"Score range?"}
E -- "0.0" --> F["Apply severity/none"]
E -- "0.1 - 3.9" --> G["Apply severity/low"]
E -- "4.0 - 6.9" --> H["Apply severity/medium"]
E -- "7.0 - 8.9" --> I["Apply severity/high"]
E -- "9.0 - 10.0" --> J["Apply severity/critical"]
F & G & H & I & J --> K["Continue with CVE request"]
C --> K
```

## Value & benefits

|Benefit|Who gains it|Impact|
|---|---|---|
|Eliminates manual severity labeling|Security team, maintainers|Removes a repetitive step from every CVE request — less friction, fewer mistakes|
|Consistent severity classification|Everyone triaging or reviewing issues|No more subjective label picks; the score determines the label deterministically|
|Industry-standard nomenclature|Contributors, external reporters, anyone cross-referencing advisories|Labels match what NVD, FIRST, GitHub advisories, and Jira use — no translation needed|
|Faster triage|Security team|Issues arrive pre-labeled, so the team can prioritize and filter immediately|

## User stories / scenarios

> "As a security team member reviewing open secalert issues, I want severity labels to use standard CVSS 3.1 names (severity/high instead of severity/important), so that I can immediately understand the severity without mentally translating Red Hat-specific terms."

> A maintainer opens an issue with @security secalert and includes CVSS: 5.4 in the body. The bot parses 5.4, determines it falls in the 4.0–6.9 range, and applies severity/medium. No manual intervention needed.

## Acceptance criteria

- When a @security secalert command is processed and the issue body contains a valid CVSS score, the bot applies the correct severity label based on the CVSS 3.1 ranges.
- The bot recognizes CVSS scores in common formats: bare decimal (e.g., 7.5), labeled (e.g., CVSS: 7.5, CVSS Score: 7.5), and optionally extracted from a CVSS 3.1 vector string.
- If no CVSS score is found, the bot does not assign any severity label and proceeds normally.
- If an invalid or out-of-range score is provided (e.g., 11.0, -1, abc), the bot does not assign a label and optionally logs a warning.
- Migration of existing issues with old labels are migrated to the new label names.

## Out of scope

- Automatic CVSS score calculation from vulnerability details — the maintainer still provides the score.
- Re-scoring or overriding an already-assigned severity label (that stays a manual action).
- Parsing CVSS scores from linked external pages or attachments — only the issue body is scanned.
- Supporting CVSS 4.0 ranges (can be addressed in a follow-up if FIRST finalizes adoption).

### Discussion

_No response_

### Motivation

_No response_

### Details

_No response_

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by locating the @security secalert command-processing entry point and the code that applies severity labels. Trace how issue bodies are currently handled, then use the acceptance criteria to define completion: valid CVSS 3.1 scores map to the new labels, invalid or absent scores leave severity unset, and existing labels are migrated.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
security, tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.