Target: {{ report.pipeline_name }}
Scanned: {{ report.scan_timestamp[:19].replace('T', ' ') }} UTC
Jobs: {{ report.pipeline.jobs | length }} • Stages: {{ report.pipeline.stages | length }}
{% set score = report.risk_score.overall %} {% set gc = score | score_colour %}
{% set arc_len = (score / 100 * 283) | round(1) %} {{ score }} RISK SCORE
{{ report.risk_score.grade }}
{% if report.risk_score.grade == 'A' %}Well-secured pipeline {% elif report.risk_score.grade == 'B' %}Good posture, minor issues {% elif report.risk_score.grade == 'C' %}Moderate risk — action recommended {% elif report.risk_score.grade == 'D' %}High risk — immediate action required {% else %}Critical risk — do not deploy {% endif %}
{% for sev in ['Critical', 'High', 'Medium', 'Low', 'Info'] %}
{{ severity_counts.get(sev, 0) }}
{{ sev }}
{% endfor %}
{% set cats = [ ('Pipeline Integrity', report.risk_score.pipeline_integrity), ('Identity & Access', report.risk_score.identity_access), ('Runner Security', report.risk_score.runner_security), ('Artifact Handling', report.risk_score.artifact_handling), ('Deployment Governance', report.risk_score.deployment_governance), ('Supply Chain', report.risk_score.supply_chain), ] %} {% for name, score in cats %}
{{ name }} {{ score }}/100
{% endfor %}
Pipeline Flow
{% if pipeline_stages %}
{% for stage in pipeline_stages %}
{{ stage.name }}
{% if stage.jobs %} {% for job in stage.jobs %} {% set chip_class = '' %} {% if job.max_severity == 'Critical' %}{% set chip_class = 'has-critical' %} {% elif job.max_severity == 'High' %}{% set chip_class = 'has-high' %} {% elif job.max_severity == 'Medium' %}{% set chip_class = 'has-medium' %} {% elif job.max_severity == 'Low' %}{% set chip_class = 'has-low' %} {% endif %}
{{ job.name }} {% if job.is_manual %}MANUAL{% endif %} {% if job.findings_count > 0 %}{{ job.findings_count }}⚠{% endif %}
{% endfor %} {% else %}
no jobs
{% endif %}
{% if not loop.last %}
{% endif %} {% endfor %}
{% else %}
No stage information available.
{% endif %}
{% if report.delta %}
Delta vs Baseline (baseline written {{ report.delta.baseline_timestamp }} by ciguard {{ report.delta.baseline_scanner_version }})
New
{{ report.delta.new | length }}
Resolved
{{ report.delta.resolved | length }}
Unchanged
{{ report.delta.unchanged | length }}
Score Change
{% if report.delta.score_delta > 0 %}+{% endif %}{{ report.delta.score_delta }}
{% if report.delta.new %}

New since baseline

{% for f in report.delta.new %} {% endfor %}
SeverityRuleFindingLocation
{{ f.severity.value }} {{ f.rule_id }} {{ f.name }} {{ f.location }}
{% endif %} {% if report.delta.resolved %}

Resolved since baseline

{% for f in report.delta.resolved %} {% endfor %}
SeverityRuleFindingLocation
{{ f.severity.value }} {{ f.rule_id }} {{ f.name }} {{ f.location }}
{% endif %} {% if not report.delta.new and not report.delta.resolved %}

No changes since baseline — {{ report.delta.unchanged | length }} finding{% if report.delta.unchanged | length != 1 %}s{% endif %} unchanged.

{% endif %}
{% endif %}
🔎 Findings ({{ sorted_findings | length }} total)
{% for sev in ['Critical', 'High', 'Medium', 'Low', 'Info'] %} {% set count = severity_counts.get(sev, 0) %} {% if count > 0 %} {% endif %} {% endfor %}
{% for finding in sorted_findings %} {% else %} {% endfor %}
Severity ↕ Rule ↕ Finding ↕ Category ↕ Location ↕
{{ finding.severity | severity_icon | safe }} {{ finding.severity.value }} {{ finding.rule_id }}
{{ finding.name }}
▼ Details

Description

{{ finding.description }}

Evidence

{{ finding.evidence }}

Remediation

{{ finding.remediation }}

Compliance

{% if finding.compliance.iso_27001 %}ISO 27001: {{ finding.compliance.iso_27001 | join(', ') }}  {% endif %} {% if finding.compliance.soc2 %}SOC 2: {{ finding.compliance.soc2 | join(', ') }}  {% endif %} {% if finding.compliance.nist %}NIST CSF: {{ finding.compliance.nist | join(', ') }}{% endif %}

{{ finding.category | category_icon | safe }} {{ finding.category.value }} {{ finding.location }}
✓ No findings — pipeline passed all checks.
{% if report.suppressed %}
🔒 Suppressed ({{ report.suppressed | length }} hidden by {{ report.ignore_file_path or '.ciguardignore' }})

These findings were detected but suppressed by an explicit entry in your .ciguardignore file. They are listed here for audit purposes — they do not contribute to the risk score or trigger CI failure.

{% if report.ignore_warnings %}
Expired suppressions detected
    {% for warning in report.ignore_warnings %}
  • {{ warning }}
  • {% endfor %}
{% endif %} {% for f in report.suppressed %} {% endfor %}
SeverityRuleNameLocation
{{ f.severity.value }} {{ f.rule_id }} {{ f.name }} {{ f.location }}
{% endif %}
📋 Compliance Mapping
{% if compliance_table %} {% for row in compliance_table %} {% endfor %}
Framework Control Max Severity Findings Finding Names
{% if row.framework == 'ISO 27001' %} ISO 27001 {% elif row.framework == 'SOC 2' %} SOC 2 {% else %} NIST CSF {% endif %} {{ row.control }} {{ row.max_severity }} {{ row.findings_count }} {{ row.finding_names | join(', ') }}{% if row.findings_count > 3 %}...{% endif %}
{% else %}
No compliance mappings to display.
{% endif %}
🛠 Remediation Roadmap Priority ordered by severity
{% for item in remediation_roadmap %}
{{ item.severity }} {{ item.rule_id }} {{ item.category }}

{{ item.name }}

{{ item.remediation }}
{% endfor %}