Skip to content

Scoring Methodology

How Salient turns your control responses into a defensible AI security posture score.

This page is the authoritative reference. If an auditor or board member asks "where does this number come from?" — the answer is here.

Design principles

  1. Risk-weighted — critical controls contribute more to the score than medium controls
  2. Domain-independent — each of the 7 domains produces its own score, then a weighted overall
  3. Partial credit is real — "Partial" is explicitly modeled at 50%, not rounded to No
  4. Not-Applicable is excluded — genuinely inapplicable controls don't drag down your score
  5. Every number is reproducible — the math is public and deterministic

Answer scoring

Each control can be answered in one of four ways:

Answer Score Used in scoring?
Yes 1.0
Partial 0.5
No 0.0
Not Applicable Excluded from domain calculation entirely

A control with no answer counts as No when the overall report runs. The Assess UI shows this warning so you can't accidentally under-answer.

Domain score formula

For each control in a domain:

earned_weight = weight × answer_score

Where weight comes from the control's risk severity (critical = 1.5, high = 1.2, medium = 0.9–1.0) and answer_score is from the table above.

Then for the domain:

domain_score = sum(earned_weight) / sum(weight_of_applicable_controls)

Result is in the [0, 1] range. Not Applicable responses contribute to neither numerator nor denominator.

Example

Suppose a domain has three controls:

  • Control A: critical, weight 1.5, answered Yes → earned = 1.5
  • Control B: critical, weight 1.5, answered No → earned = 0.0
  • Control C: medium, weight 1.0, answered Partial → earned = 0.5

Totals: earned = 2.0, total weight = 4.0 → domain score = 0.50 (50%)

If Control C were Not Applicable instead: earned = 1.5, total weight = 3.0 → domain score = 0.50 (50%) — in this case the N/A didn't change the result, but if Control C had been a "Yes" it would have pulled the score up.

Overall score formula

Each domain has its own weight (the AI stack lives under different amounts of attacker focus — MCP Security and Agent Security get heavier weights):

Domain Weight
Inventory & Governance 1.0
Data Governance 1.0
MCP Security 1.2
Prompt Security 1.1
Agent Security 1.2
Access Control 1.0
Monitoring & IR 1.0
overall_score = sum(domain_score × domain_weight) / sum(domain_weight)

Displayed as a percentage in the UI and report.

Gap identification

Any control answered No or Partial becomes a gap in the report. Gaps are sorted by severity:

  1. Critical (weight 1.5)
  2. High (weight 1.2)
  3. Medium (weight 0.9–1.0)
  4. Low (rare — most controls are medium or higher)

Partial gaps are flagged separately so remediation teams can prioritize "finish what's started" vs. "start from zero."

Recommendations

The top 8 gaps become prioritized recommendations, each with:

  • Priority level (critical / high / medium)
  • Control ID + title
  • Remediation guidance (verbatim from the control catalog)

Rank order preserves severity — critical always above high, always above medium.

What the score means

Score Interpretation
80–100% Mature AI security posture. Focus on edge cases and advanced controls.
60–79% Reasonable coverage. Key gaps remain — follow the recommendation list.
40–59% Partial coverage. Material exposure in at least one domain.
20–39% Significant exposure. Critical controls missing.
0–19% Substantial risk. Board-level escalation is appropriate.

These bands are displayed as color-coded indicators in the Results view:

  • ≥70% — green (emerald)
  • 40–69% — yellow (amber)
  • <40% — red

Why not just ask Yes/No?

"Partial" exists because reality is rarely binary. A control like "Are MCP tool calls logged?" might be true for your internal MCPs but not for a third-party one you just integrated. Forcing "Yes" overstates your posture; forcing "No" understates it. Partial credit reflects what's actually true and still flags the gap.

What the scoring cannot do

  • It cannot tell you if your answers are accurate. Garbage in, garbage out. The conducted_by field tracks who submitted the assessment for accountability.
  • It cannot replace human judgment on risk. A 90% score with a No on "MCP Authentication" is still an unacceptable posture. Read the gap list.
  • It cannot predict breach likelihood. Posture scores measure control coverage, not attacker intent.

Auditability

Every assessment stores:

  • conducted_by — user ID of the person who submitted
  • conducted_at — ISO-8601 timestamp
  • control_responses — JSON blob of every answer (for reproduction)
  • gaps / recommendations — the derived output at assessment time

This means a posture score from six months ago can be reconstructed from the stored responses even if the control catalog has evolved since. For auditors asking "what was our posture on date X?" — the answer is in the database.

Changes to the catalog

When Salient updates the control catalog (new controls, weight adjustments, renamed IDs), existing assessments are preserved with their original responses. Re-running an assessment generates a new score against the current catalog — both are kept.

See also