Skip to content

Latest commit

Β 

History

31 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

owasp-samm-toolkit

A lightweight OWASP SAMM v2 toolkit: run a maturity assessment, compute scores per practice and business function, generate a prioritised improvement roadmap, and render a Markdown report with an SVG maturity radar.

CI


What this demonstrates

Running an AppSec program the way a SAMM assessment actually works β€” not just operating scanners, but measuring maturity, setting targets, and producing an actionable roadmap. It models the full SAMM v2 structure:

  • 5 business functions β†’ 15 security practices β†’ 2 streams each β†’ 3 maturity levels
  • Answers are fractions per practice/stream/level (0 / 0.25 / 0.5 / 0.75 / 1.0)
  • Scores roll up: stream β†’ practice β†’ business function β†’ overall (all on a 0–3 scale)
  • A target profile drives gap analysis and a ranked roadmap

No heavy dependencies β€” pure Python + PyYAML. The radar chart is generated as hand-built SVG (no matplotlib), so output embeds cleanly on GitHub.

Install

Requires Python 3.9+.

pip install -e .        # exposes the `samm-tool` command
# or run without installing:
python -m samm_tool --help

Usage

# 1. Create a blank assessment (+ a target profile)
samm-tool init -o assessment.yaml --target target.yaml --target-level 2.0

# 2. Fill in assessment.yaml, then see the scores
samm-tool score assessment.yaml

# 3. Get a prioritised improvement roadmap
samm-tool roadmap assessment.yaml --target target.yaml

# 4. Generate a Markdown report + SVG radar
samm-tool report assessment.yaml --target target.yaml --outdir reports

Web interview app

For live interviews, use the browser-based interface instead of hand-editing assessment.yaml. This section is a complete manual for it.

This is an additional way to use the toolkit β€” the YAML/CLI workflow above keeps working exactly as documented, and doesn't require Flask.

Installation and startup

pip install -e ".[web]"   # installs Flask (optional dependency)
samm-tool web              # starts at http://127.0.0.1:5000

web command options:

Flag Default Description
--host 127.0.0.1 network address the server listens on
--port 5000 TCP port
--debug disabled enables Flask debug mode (auto-reload, detailed tracebacks)

1. Create an account (Sign up)

Go to http://127.0.0.1:5000 (redirects to /login if you're not logged in) and click Sign up. Fill in:

  • Name β€” your name
  • Role β€” your role (e.g., AppSec Analyst)
  • Organization β€” the company/team you belong to (not the organization being assessed β€” that's asked later, per assessment)
  • Email β€” used as the login; must be unique
  • Password β€” at least 8 characters, no other complexity rules

On signup, you're logged in automatically and taken straight to the dashboard (My assessments). An already-registered email produces an error message and the form is re-shown without creating the account.

2. Log in / Log out

  • Log in (/login): email and password.
  • Log out: the Log out button in the top-right corner, available on any page while you're logged in.

The session uses a Flask-signed cookie (key generated once and persisted to instance/secret_key); it doesn't expire automatically beyond the browser's default behavior.

3. Dashboard ("My assessments")

The home screen (/) shows:

  • An Assessment in progress card, with a Continue button, if you have an assessment that isn't finished yet.
  • The New assessment button, to start a new interview.
  • The list of Completed assessments, each linking to its result page.

Note: the dashboard only shows the most recent in-progress assessment. If you click "New assessment" while one is already in progress, the earlier one stays saved in the database but stops appearing on the dashboard β€” finish an interview before starting another to avoid losing access to it through the interface.

4. Start a new assessment

On New assessment (/assessments/new), fill in the interview details:

  • Organization β€” the organization/company being assessed
  • Project β€” the project or product in scope
  • Interviewee β€” the name of the person being interviewed
  • Date β€” the interview date

On confirming (Start interview), the assessment is created with "in progress" status and you're taken straight to the first question of the questionnaire.

5. Answer the questionnaire

The questionnaire covers the 15 SAMM practices, each with 2 streams (A and B) β€” 30 screens in total, always in the same order (practice Γ— stream, never shuffled). Each screen shows:

  • The practice's code and name (e.g., SM Β· Strategy & Metrics) and the current stream, with the question number at the top ("Question X of 30")
  • The practice/stream's 3 maturity levels, each with its objective described
  • For each level, a choice among 5 answers:
Answer Numeric value
No 0.0
Slightly 0.25
Partially 0.5
Mostly 0.75
Yes 1.0

Navigation:

  • Next saves the current screen's 3 answers and advances to the next one. All 3 answers are required β€” the screen won't advance without them.
  • Back (available from the 2nd question onward) returns to the previous screen without losing what's already been answered; answers already saved appear pre-selected when revisiting a screen.

Each answer is written to the database as soon as you click Next β€” there's no separate "save" button, and no risk of losing answers already given. If you close the browser mid-interview, you can come back later, log in again, and click Continue on the dashboard: you resume exactly at the next unanswered question.

After answering the last of the 30 screens, the assessment is automatically marked as completed and you're redirected to the result page.

6. Result page

Once completed, the assessment always shows (/assessments/<id>/result):

  • Overall maturity β€” average of the 15 practices, on a 0–3 scale
  • The maturity radar (SVG), with the current score overlaid on the default target (level 2.0 across all practices β€” the same default used by samm-tool roadmap/report without --target)
  • A score by business function table (Governance, Design, Implementation, Verification, Operations)
  • A score by practice table (the 15 practices, each 0–3)
  • Improvement roadmap β€” a list prioritized by the largest gap to the target, with concrete actions (the level to reach in each stream) to close each gap; if all practices already meet the target, that's stated explicitly instead of showing an empty list
  • Links to download report.md and radar.svg, generated by the same modules used by the CLI's samm-tool report flow

Completed assessments are read-only β€” there's no way to edit answers through the interface once they're completed.

Where the data lives

Everything lives under instance/, created in the folder you ran samm-tool web from (git-ignored β€” never versioned):

  • instance/samm.db β€” SQLite database with users, assessments, and answers
  • instance/secret_key β€” key used to sign session cookies (generated once, with permissions restricted to the file's owner)
  • instance/reports/<id>/report.md and radar.svg β€” generated the first time each assessment's result page is opened, and reused by the download links

Security

  • Passwords hashed with PBKDF2 (werkzeug.security), never stored in plain text
  • CSRF protection on every form that changes data (signup, login, logout, new assessment, questionnaire)
  • Each assessment is only accessible to the user who created it β€” any attempt to access another user's assessment returns 404
  • Free-text user input (name, role, organization, project, interviewee) is never rendered as raw HTML β€” always auto-escaped by Jinja2, preventing XSS

Example

A worked, fictional assessment lives in examples/; the generated output is committed in reports/:

Regenerate it with:

samm-tool report examples/example-assessment.yaml \
  --target examples/target-profile.yaml --outdir reports

Assessment format

meta:
  organization: Acme FinTech
  assessor: Jane Doe
  date: 2026-07-20
answers:
  SM: {A: {1: 1.0, 2: 0.25, 3: 0.0}, B: {1: 0.5, 2: 0.25, 3: 0.0}}
  # ... all 15 practice codes (SM PC EG TA SR SA SB SD DM AA RT ST IM EM OM)

Target profile format

The roadmap and report commands take an optional --target profile: a per-practice maturity goal on the 0–3 scale. Generate one with init --target, or hand-write it β€” any practice you omit falls back to --target-level (default 2.0).

targets:
  SM: 2.0
  SB: 3.0   # aim higher where the team is strong
  EG: 1.5   # pragmatic floor for lower-priority practices
  # ... any of the 15 practice codes; omitted ones use --target-level

Scoring model

Level Formula Range
Stream sum of its 3 level fractions 0.0–3.0
Practice mean of streams A and B 0.0–3.0
Business function mean of its 3 practices 0.0–3.0
Overall mean of all 15 practices 0.0–3.0

Development

pip install -e ".[dev]"
pytest -q
ruff check .

Attribution

The SAMM model text is summarised from the OWASP SAMM v2 project (CC BY-SA 4.0). See NOTICE. This toolkit's code is MIT-licensed (see LICENSE) and is an independent, unofficial helper β€” not an official OWASP release.

About

OWASP SAMM v2 assessment toolkit: score, roadmap, and report with SVG maturity radar

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages