Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
da6466d
Move pyproject.toml to root level dir
sei-renae Sep 19, 2025
2849dd0
Fix python build
sei-renae Sep 19, 2025
e8cdc47
Adjust Dockerfile for relocated pyproject.toml and uv.lock. I am not …
sei-renae Sep 19, 2025
9ee2f28
Merge branch 'main' into 974
ahouseholder Sep 29, 2025
420f143
Extend methods to generate Selection Schema for CVE and other projects
sei-vsarvepalli Oct 7, 2025
7131c0d
Added mode="json" for reliable super model
sei-vsarvepalli Oct 7, 2025
4ca0064
Merge branch 'main' into Issue_996
sei-vsarvepalli Oct 7, 2025
205c508
Revert mode=json and add timezone checks
sei-vsarvepalli Oct 7, 2025
7a9bf3b
Updated README.md for pypi project
sei-vsarvepalli Oct 7, 2025
c05fa15
Updated to add tests and simplified model_dumpers
sei-vsarvepalli Oct 9, 2025
fc7b9d2
add examples to api
ahouseholder Oct 9, 2025
87224c2
add EXAMPLE_MINIMAL_DECISION_POINT_VALUE to examples
ahouseholder Oct 9, 2025
7ecedd3
add test for examples in app
ahouseholder Oct 9, 2025
c20e4a2
add endpoint to retrieve sample references and corresponding tests
ahouseholder Oct 9, 2025
8e59824
mark test_get_selection_lists as expected failure and add TODO for PO…
ahouseholder Oct 9, 2025
17b6845
add POST endpoint to validate Reference and corresponding tests
ahouseholder Oct 10, 2025
bf89719
Extend methods to generate Selection Schema for CVE and other project…
ahouseholder Oct 10, 2025
3ea12b4
Merge branch 'main' of https://github.com/CERTCC/SSVC into api-examples
ahouseholder Oct 10, 2025
bb41416
remove debug print statement from data cleanup function
ahouseholder Oct 10, 2025
0299753
Removed debug print statement
sei-vsarvepalli Oct 10, 2025
650e391
add tests for SelectionList to validate empty lists and model dumping…
ahouseholder Oct 10, 2025
054261f
refactor examples and tests for clarity and structure
ahouseholder Oct 10, 2025
e2a67bc
add model validators to handle default summary and remove falsy fields
ahouseholder Oct 10, 2025
4b06105
Removed debug print statement (#1008)
ahouseholder Oct 10, 2025
1c36e52
Merge branch 'main' into api-examples
ahouseholder Oct 10, 2025
20405dc
add prefix and tags to API router and enhance root redirect description
ahouseholder Oct 10, 2025
87041a6
remove prefix and tags from v1 API router configuration
ahouseholder Oct 10, 2025
2a88e43
add README.md for SSVC API setup and usage instructions
ahouseholder Oct 10, 2025
87fb9e0
Merge remote-tracking branch 'gh_pub/api-examples' into api-examples
ahouseholder Oct 10, 2025
f44a2f3
Update src/test/api/routers/test_examples.py
ahouseholder Oct 10, 2025
83161ad
black formatter
ahouseholder Oct 10, 2025
66ed04a
Merge remote-tracking branch 'gh_pub/api-examples' into api-examples
ahouseholder Oct 10, 2025
96b7b53
Update src/ssvc/selection.py
ahouseholder Oct 10, 2025
d29d624
Update src/test/test_selections.py
ahouseholder Oct 10, 2025
695779b
Update src/test/test_selections.py
ahouseholder Oct 10, 2025
4d5b597
Add API examples endpoints (#1006)
ahouseholder Oct 10, 2025
55fab92
Initial plan
Copilot Oct 10, 2025
4f6bc3d
Initial plan
Copilot Oct 10, 2025
85c34d6
Add GitHub Copilot instructions for SSVC repository
Copilot Oct 10, 2025
cd1fa69
Refactor Default Automatable Values into includable file
Copilot Oct 10, 2025
3e32f22
fix clipping
sei-renae Oct 10, 2025
ef61937
merge main
sei-renae Oct 10, 2025
243b44a
Update docs/_includes/default_automatable_values.md
ahouseholder Oct 10, 2025
c5724f7
Initial plan
Copilot Oct 10, 2025
cbebd9e
Initial plan
Copilot Oct 10, 2025
26c5696
Refactor default exploitation values to includable file
Copilot Oct 10, 2025
eab18e4
Initial plan
Copilot Oct 10, 2025
6ea2726
Initial plan
Copilot Oct 10, 2025
c814165
Refactor Default System Exposure Values into an includable
Copilot Oct 10, 2025
0234fef
Refactor default mission impact values into reusable include file
Copilot Oct 10, 2025
f931433
Refactor default safety values tip into includable file
Copilot Oct 10, 2025
01ab1b4
update dependabot
sei-renae Oct 13, 2025
96eef7d
lint
sei-renae Oct 13, 2025
21433f0
Update pyproject.toml
ahouseholder Oct 14, 2025
e07a701
Merge branch 'main' into 974
ahouseholder Oct 14, 2025
aaf288a
Remove virtual environment setup from Dockerfile since uv will handle…
ahouseholder Oct 14, 2025
4c8d970
Refactor Makefile to remove PROJECT_DIR variable and simplify uv comm…
ahouseholder Oct 14, 2025
51d06f4
Add example environment file to avoid Docker naming collisions (+1 sq…
ahouseholder Oct 14, 2025
94c4ba2
remove requirements.txt because we use pyproject.toml now
ahouseholder Oct 14, 2025
271cf19
Merge branch '974' of https://github.com/sei-renae/SSVC into 974
ahouseholder Oct 14, 2025
3ac96e6
add black to uv dev dependencies
ahouseholder Oct 14, 2025
14cb0a4
Move pyproject.toml to root level dir (#980)
ahouseholder Oct 14, 2025
223fa09
Use absolute paths from doc root in include file
Copilot Oct 14, 2025
2821fd5
Revert to relative paths in include file
Copilot Oct 14, 2025
67f21b9
Apply suggestion from @Copilot
ahouseholder Oct 14, 2025
94e55c4
Apply suggestion from @Copilot
ahouseholder Oct 14, 2025
bc0ce12
Refactor Default Automatable Values into reusable include file (#1010)
ahouseholder Oct 14, 2025
0a25ccd
Fix link paths to use absolute URLs in include file
Copilot Oct 14, 2025
73f1938
Refactor Default System Exposure Values into an includable (#1014)
ahouseholder Oct 14, 2025
96fd1af
Refactor default safety values tip into an includable file (#1015)
ahouseholder Oct 14, 2025
c5a78d9
Refactor Default Mission Impact Values into reusable include file (#1…
ahouseholder Oct 14, 2025
2f45d9c
Update docs/_includes/default_safety_values.md
ahouseholder Oct 14, 2025
b0510e6
Update safety impact documentation
ahouseholder Oct 14, 2025
92c06e2
Enable rewriting of relative links in MkDocs configuration
ahouseholder Oct 14, 2025
0980471
Merge remote-tracking branch 'gh_pub/copilot/refactor-default-exploit…
ahouseholder Oct 14, 2025
dbe452a
Refactor default decision point values from collect.md to includable …
ahouseholder Oct 14, 2025
ab834d0
Address review feedback on Copilot instructions
Copilot Oct 15, 2025
9ade107
Restore aspirational guidance based on feedback
Copilot Oct 15, 2025
219b06a
Bump actions/upload-artifact from 4 to 5
dependabot[bot] Oct 27, 2025
355379c
Clean up
sei-renae Oct 27, 2025
3e910cd
Bump actions/upload-artifact from 4 to 5 (#1021)
ahouseholder Oct 28, 2025
55ff831
test markdown lint to exclude .github
sei-renae Oct 28, 2025
fc0a85a
Setup copilot instructions (#1024)
sei-renae Oct 28, 2025
4e38b31
Fix graph view cutoff in Explorer with fixed bottom buffer (#1004)
sei-vsarvepalli Oct 28, 2025
a95fa22
Initial plan
Copilot Oct 28, 2025
c032b5d
Fix zoom control: Initialize SVG viewBox on creation
Copilot Oct 28, 2025
da6b958
Change syntax of markdownlint ignores
sei-renae Oct 29, 2025
c779480
Change syntax of markdownlint ignores (#1029)
sei-renae Oct 29, 2025
107cd68
Remove mention of kebab case
sei-renae Oct 29, 2025
654938c
Remove mention of kebab case (#1030)
sei-renae Oct 29, 2025
4049910
Update .github/copilot-instructions.md
ahouseholder Oct 29, 2025
92546b6
Update .github/copilot-instructions.md
ahouseholder Oct 29, 2025
c06cdc2
Update .github/copilot-instructions.md
ahouseholder Oct 29, 2025
84a9767
Update .github/copilot-instructions.md
ahouseholder Oct 29, 2025
f26e116
✨ Set up GitHub Copilot instructions for SSVC repository (#1012)
sei-renae Oct 29, 2025
b8b76b4
updates also to truncate long fields
sei-vsarvepalli Oct 28, 2025
69d0b8c
Update docs/ssvc-explorer/simple.js
sei-vsarvepalli Oct 28, 2025
df4ad63
Update docs/ssvc-explorer/simple.js
sei-vsarvepalli Oct 28, 2025
58153d0
Update docs/ssvc-explorer/simple.js
sei-vsarvepalli Oct 28, 2025
221822f
Updates to handle words that may end with spaces and ellipsis is invi…
sei-vsarvepalli Oct 29, 2025
f225d89
Suggestion to color distinguish values from names of Decision Points
sei-vsarvepalli Oct 29, 2025
62fad9f
Added more conditions to regex match
sei-vsarvepalli Oct 29, 2025
86c18b5
Reduce string length to truncate
sei-renae Oct 29, 2025
b13acfa
Uncomment a slicer
sei-renae Oct 29, 2025
2be8f34
Add test for first character not to be space
sei-vsarvepalli Oct 29, 2025
4805f9f
Fix syntax
sei-renae Oct 29, 2025
073f634
Truncate long labels in decision table visualization (#1028)
ahouseholder Oct 30, 2025
5682f6e
Merge branch 'publish' into main
ahouseholder Nov 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 168 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
# GitHub Copilot Instructions for SSVC

This repository contains the **Stakeholder-Specific Vulnerability Categorization (SSVC)** project, which provides a system for prioritizing actions during vulnerability management.

## Project Overview

SSVC is a modular decision-making framework for vulnerability management that includes:
- Python modules for decision points, decision tables, and outcomes
- MkDocs-based documentation website
- Interactive calculators and policy explorers
- JSON/CSV data files for decision tables
- Docker and Make-based development and deployment

## Technology Stack

- **Primary Language**: Python 3.x
- **Package Management**: uv (package and project manager)
- **Build Tool**: Make
- **Documentation**: MkDocs with Material theme
- **Testing**: pytest
- **Data Models**: Pydantic for JSON schema validation
- **Scientific Computing**: NumPy, SciPy, scikit-learn
- **Web Framework**: FastAPI (for API endpoints)
- **Containerization**: Docker and Docker Compose

## Project Structure

- `/src/ssvc/` - Core Python modules for SSVC functionality
- `decision_points/` - Decision point definitions
- `decision_tables/` - Decision table implementations
- `api/` - FastAPI application
- `outcomes/` - Outcome definitions
- `dp_groups/` - Decision point groups
- `registry/` - Registry functionality
- `/docs/` - Markdown documentation source files
- `/data/` - JSON and CSV data files for decision tables
- `/src/test/` - Unit tests
- `/docker/` - Docker configurations
- `/obsolete/` - Deprecated code (do not modify)

## Make Commands

Use `make help` to see all available commands. Common targets include:

- `make dev` - Set up development environment
- `make test` - Run tests locally
- `make docker_test` - Run tests in Docker
- `make docs_local` - Serve documentation locally (http://localhost:8000/SSVC/)
- `make docs` - Build and run documentation in Docker
- `make api_dev` - Run API locally with auto-reload
- `make api` - Build and run API in Docker
- `make mdlint_fix` - Run markdown linting with auto-fix
- `make regenerate_json` - Regenerate JSON files from Python modules

## Development Workflow

## Coding Conventions

### Python Code

- Follow PEP 8 style guidelines
- Use type hints for function signatures and return types
- Use Pydantic models for data validation
- Document classes and functions with docstrings
- Prefer explicit imports over wildcard imports
- Module structure uses absolute imports from `ssvc` package

### Naming Conventions

- Python files: `snake_case.py`
- Classes: `PascalCase`
- Functions/variables: `snake_case`
- Constants: `UPPER_SNAKE_CASE`

## Testing Requirements

### Test Structure

- Unit tests use pytest framework
- Tests are located in `/src/test/`
- Test files follow pattern: `test_*.py`
- Run tests with: `make test` or `uv run pytest -v`

### Test Coverage

- Write tests for new Python modules
- Ensure decision points and tables have corresponding tests
- Test JSON schema validation
- Validate data model serialization/deserialization

### Before Committing

1. Run all tests: `make test`
2. Ensure no test failures
3. Fix any linting issues: `make mdlint_fix`
4. Verify documentation builds: `make docs_local`

## Documentation

### Writing Documentation

- Documentation uses MkDocs with Material theme
- Files are in Markdown format in `/docs/`
- Use Python exec blocks for dynamic content generation
- Include examples and code snippets
- Follow existing documentation structure

### Documentation Features

- Automatic API documentation via mkdocstrings
- Python module imports for dynamic content generation
- BibTeX citations via mkdocs-bibtex
- Add markdown files to site navigation by specifying them in `mkdocs.yml`
- Include markdown files in other markdown files with `mkdocs-include-markdown-plugin`
- Dynamically generate content from python code blocks using the `markdown-exec` plugin

## Data Files

### JSON Files

- Located in `/data/json/`
- Generated from Python Pydantic models
- Use JSON schema validation

### CSV Files

- Located in `/data/csv/`
- Define decision table outcomes
- Generated from python modules (The python data objects are authoritative)
- Allows users to explore customizing SSVC for specific environments

## Common Pitfalls

1. **Import Paths**: Use absolute imports like `from ssvc.module import Class`, not relative imports
2. **PYTHONPATH**: When running scripts directly, set `export PYTHONPATH=$PYTHONPATH:$(pwd)/src`
3. **JSON Regeneration**: After modifying decision points/tables, regenerate JSON with `make regenerate_json`
4. **Docker Context**: Some make targets use Docker, others run locally - check the Makefile
5. **Package Management**: Use `make` commands or `uv` directly, not pip
6. **Obsolete Code and Documentation**: Never modify files in `/obsolete/`, `/doc/`, or `/pdfs/` directories

## API Development

- FastAPI application is in `/src/ssvc/api/`
- Run locally with auto-reload: `make api_dev` (serves on http://127.0.0.1:8000/docs)
- Run in Docker: `make api` (serves on http://127.0.0.1:8001/SSVC/)

## Git Workflow

- Create feature branches for new work
- Write descriptive commit messages
- Reference issue numbers in commits when applicable
- Keep commits focused and atomic
- Run tests before pushing

## Additional Resources

- Main documentation: https://certcc.github.io/SSVC/
- Source repository: https://github.com/CERTCC/SSVC
- SSVC Calculator: https://certcc.github.io/SSVC/ssvc-calc/
- Contributing guide: See CONTRIBUTING.md
- Project wiki: https://github.com/CERTCC/SSVC/wiki

## Special Notes

- This project uses a MIT (SEI)-style license with Carnegie Mellon University copyright (see LICENSE file)
- Decision points and tables follow SSVC specification
- Backward compatibility is important for existing data files
- Documentation changes should be reflected in both `/docs/` and `/src/README.md` when applicable
1 change: 0 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ updates:
- package-ecosystem: "uv" # See documentation for possible values
directories:
- "/"
- "/src" # Location of package manifests
schedule:
interval: "weekly"
groups:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/deploy_site.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ jobs:
run: |
python -m pip install --upgrade pip
python -m pip install uv
uv sync --project=src --no-dev
uv sync --no-dev

- name: Setup Pages
uses: actions/configure-pages@v5

- name: Build Site
run: |
export PYTHONPATH=src:$PYTHONPATH
uv run --project=src mkdocs build --clean --config-file mkdocs.yml
uv run mkdocs build --clean --config-file mkdocs.yml

- name: Upload artifact
uses: actions/upload-pages-artifact@v4
Expand Down
9 changes: 4 additions & 5 deletions .github/workflows/link_checker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ on:
# run on any PR that changes this workflow
- .github/workflows/linkchecker.yml
# run on any PR that changes the pip requirements
- requirements.txt
- src/pyproject.toml
- pyproject.toml
# let us trigger it manually
workflow_dispatch:

Expand All @@ -31,13 +30,13 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip uv
uv sync --dev --project=src
uv sync --dev

- name: Build Site
run: |
uv run --project=src mkdocs build --verbose --clean --config-file mkdocs.yml
uv run mkdocs build --verbose --clean --config-file mkdocs.yml

- name: Check links
run: |
uv run --project=src linkchecker site/index.html
uv run linkchecker site/index.html

8 changes: 4 additions & 4 deletions .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip uv
uv sync --project=src --dev --frozen
uv sync --dev --frozen
# - uses: psf/black@stable
- name: Test with pytest
run: |
uv run --project=src pytest
uv run pytest
- name: Build
run: |
uv build --project=src
uv build
- name: Upload Artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: ssvc
path: src/dist/ssvc-*.tar.gz
Expand Down
2 changes: 2 additions & 0 deletions .markdownlint.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
ignores:
- .github/**
default: true
# disable noisy rules
# 0004 Unordered List style
Expand Down
9 changes: 4 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# Project-specific vars
MKDOCS_PORT=8765
DOCKER_DIR=docker
PROJECT_DIR = ./src
DOCKER_COMPOSE=docker-compose --project-directory $(DOCKER_DIR)
UV_RUN=uv run --project $(PROJECT_DIR)
UV_RUN=uv run

# Targets
.PHONY: all test docs api docker_test clean help mdlint_fix up down regenerate_json
Expand All @@ -13,15 +12,15 @@ all: help

dev:
@echo "Set up dev environment..."
uv sync --dev --project $(PROJECT_DIR)
uv sync --dev

mdlint_fix:
@echo "Running markdownlint..."
markdownlint --config .markdownlint.yml --fix .

test:
@echo "Running tests locally..."
uv run --project $(PROJECT_DIR) pytest -v
$(UV_RUN) pytest -v

docker_test:
@echo "Building the latest test image..."
Expand Down Expand Up @@ -60,7 +59,7 @@ regenerate_json:
clean:
@echo "Cleaning up Docker resources..."
$(DOCKER_COMPOSE) down --rmi local || true
rm -rf $(PROJECT_DIR)/.venv $(PROJECT_DIR)/uv.lock

help:
@echo "Usage: make [target]"
@echo ""
Expand Down
23 changes: 7 additions & 16 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,26 @@ RUN apt-get update && apt-get install -y --no-install-recommends git && rm -rf /
RUN pip install --upgrade pip uv
WORKDIR /app

ENV VIRTUAL_ENV=/app/.venv
ENV PATH="${VIRTUAL_ENV}/bin:${PATH}"

RUN python -m venv "${VIRTUAL_ENV}"
FROM base AS dependencies

ARG BASE_DIR=..
ARG SRC_DIR=${BASE_DIR}/src

# Copy the files we need
COPY ${BASE_DIR}/ /app
COPY . /app
# Set the environment variable
ENV PYTHONPATH=/app/src
COPY ${SRC_DIR}/pyproject.toml /app/src/pyproject.toml
COPY ${SRC_DIR}/uv.lock /app/src/uv.lock

# install requirements
RUN uv sync --project=/app/src --frozen

RUN uv sync --frozen

FROM dependencies AS test

ENV PYTHONPATH=/app/src
# Install pytest and dev dependencies
RUN uv sync --project=/app/src --frozen --dev
RUN uv sync --frozen --dev
# Run the unit tests
CMD ["uv", "run", "--project=/app/src", "pytest"]
CMD ["uv", "run", "pytest"]

FROM dependencies AS docs
CMD ["uv", "run", "--project=/app/src", "mkdocs", "serve", "--dev-addr", "0.0.0.0:8000"]
CMD ["uv", "run", "mkdocs", "serve", "--dev-addr", "0.0.0.0:8000"]

FROM dependencies AS registry_api
CMD ["uv", "run", "--project=/app/src", "uvicorn", "ssvc.api.main:app", "--host", "0.0.0.0", "--port", "8000"]
CMD ["uv", "run", "uvicorn", "ssvc.api.main:app", "--host", "0.0.0.0", "--port", "8000"]
3 changes: 3 additions & 0 deletions docker/env_example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# copy or link this file to .env in this directory
# this helps avoid docker image/container naming collisions
COMPOSE_PROJECT_NAME=ssvc
5 changes: 5 additions & 0 deletions docs/_includes/default_automatable_values.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
!!! tip "Default Automatable Values"

If nothing is known about [*Automatable*](/reference/decision_points/automatable.md), the safer answer to assume is [*yes*](/reference/decision_points/automatable.md).
[*Value Density*](/reference/decision_points/value_density.md) should always be answerable; if the product is uncommon, it is probably
[*diffuse*](/reference/decision_points/value_density.md).
4 changes: 4 additions & 0 deletions docs/_includes/default_exploitation_values.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
!!! tip "Default Exploitation Values"

[*Exploitation*](../reference/decision_points/exploitation.md) needs no special default; if adequate searches are made for exploit code and none is
found, the answer is [*none*](../reference/decision_points/exploitation.md).
5 changes: 5 additions & 0 deletions docs/_includes/default_mission_impact_values.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
!!! tip "Default Mission Impact Values"

Similarly, with [*Mission Impact*](/reference/decision_points/mission_impact.md), the deployer should assume that the software is in use at the
organization for a reason, and that it supports essential functions unless they have evidence otherwise.
With a total lack of information, assume [*support crippled*](/reference/decision_points/mission_impact.md) as a default.
6 changes: 6 additions & 0 deletions docs/_includes/default_safety_values.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
!!! tip "Default Safety Values"

If the decision maker knows nothing about the environment in which the device is used, we suggest assuming a
[*marginal*](../reference/decision_points/safety_impact.md) [*Safety Impact*](../reference/decision_points/safety_impact.md).
This position is conservative, but software is thoroughly embedded in daily life now, so we suggest that the decision
maker provide evidence that no one's well-being will suffer.
5 changes: 5 additions & 0 deletions docs/_includes/default_system_exposure_values.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
!!! tip "Default System Exposure Values"

If the deployer does not know their exposure,<!--lowercase exposure on purpose, this is the general concept--> that
means they do not know where the devices are or how they are controlled, so they should assume
[*System Exposure*](../reference/decision_points/system_exposure.md) is [*open*](../reference/decision_points/system_exposure.md).
Loading
Loading