Report template tags
RedScribe reports are authored as one free-form document per Report
Profile (the Document tab on a profile’s edit
page). You write headings for structure and drop {{ tag }} placeholders
wherever you want dynamic content to appear. This page documents every tag
currently available, how each behaves, and the rules for how they combine.
There are three independent tag systems. They look the same ({{ name }})
but behave differently. See How the systems
differ before relying on edge-case behavior.
1. Placeholder tags (data substitution)
Section titled “1. Placeholder tags (data substitution)”This is simple text substitution: the tag is replaced with a plain string value from the current engagement/user. These work anywhere text can appear: directly in the Document body, and inside any custom text block’s content, any finding section, retest notes, observations, and testing-phase entries.
| Tag | Value |
|---|---|
{{ client_name }} |
Engagement.client_name |
{{ reference_number }} |
Engagement.reference_number |
{{ scope }} |
Engagement.scope (free text) |
{{ start_date }} |
Engagement.start_date, ISO format, or empty if unset |
{{ end_date }} |
Engagement.end_date, ISO format, or empty if unset |
{{ report_date }} |
Today’s date (ISO format), computed at render time |
{{ prepared_by }} |
The user generating the report, or empty if none |
If a placeholder tag’s name isn’t recognized, it’s left in the output
unchanged (e.g. a typo like {{ cilent_name }} prints literally rather than
erroring or vanishing).
2. Structural tags (built-in blocks)
Section titled “2. Structural tags (built-in blocks)”Each of these pulls in a specific chunk of real engagement/finding data. They only work as a standalone paragraph in the Document template. Put the tag alone on its own line, directly under the heading you want it to belong to. They cannot be used inside a text block, finding section, or anywhere else, only in the Document body itself.
| Tag | What it renders | Notes |
|---|---|---|
{{ breakdown_of_findings }} |
Severity/status bar chart (with a table fallback) plus a vulnerabilities summary table (ID, severity, title, status) | |
{{ finding_details }} |
The full write-up for every included finding: metadata table, affected assets, each active finding section (see Finding sections below), and (on a remediation report) retest history | This is the main body of the report, and it’s almost always required |
{{ observations }} |
Free-form dynamic entries configured per-engagement (title + rich content), each as its own subsection | Empty/omitted entirely if none are configured, with no placeholder text shown |
{{ testing_phases }} |
Same pattern as observations, free-form per-engagement phase entries | Empty/omitted if none are configured |
{{ assessment_team }} |
One subsection per engagement member with access, showing their bio and qualifications | Omitted entirely if the engagement has no members |
{{ checklist_coverage }} |
The engagement’s checklist run(s), grouped by category, showing item status and any linked findings | Shows a graceful “No checklist runs have been recorded for this engagement.” message if none exist, and never errors |
{{ scan_imports }} |
A table documenting each scanner import on this engagement (tool, filename, date, imported by, findings produced) | Metadata only: the original uploaded scan file itself is never stored, only this record of the import. Shows a graceful “No scanner imports have been recorded for this engagement.” message if none exist |
Finding sections inside {{ finding_details }}
Section titled “Finding sections inside {{ finding_details }}”{{ finding_details }} doesn’t have its own separate tag list. It
automatically includes every active ContentSectionDefinition (Finding
Structure), in their configured order. As of this writing, the active
sections are:
| Order | Slug | Label | Supports images | Visible on client portal |
|---|---|---|---|---|
| 10 | vulnerability-description |
Vulnerability description | No | Yes |
| 20 | business-impact |
Business impact | No | Yes |
| 30 | testing-summary |
Testing summary | No | Yes |
| 40 | technical-details |
Technical details | Yes | Yes |
| 50 | remediation-testing |
Remediation testing | Yes | No |
| 60 | recommendations |
Recommendations | No | Yes |
| 70 | references |
References | No | Yes |
These are managed from the Finding structure
admin screen, not the Document editor. Adding, reordering, or deactivating
one changes what {{ finding_details }} includes for every profile,
immediately.
3. Custom text-block tags (author-defined prose)
Section titled “3. Custom text-block tags (author-defined prose)”These are admin-authored rich-text blocks (ReportTextBlockDefinition),
the way you add your own prose sections (executive summary, disclaimers,
methodology, etc.) without touching code. Like structural tags, they only
work as a standalone paragraph in the Document template.
A text block always belongs to exactly one Report Profile. There’s no
shared/global text block that every profile automatically resolves. Its
metadata (slug, label) lives on the ReportTextBlockDefinition row; its
actual rich-text content lives in that profile’s own block_defaults[slug]
(or a per-report override, set from the report’s Configure page). If a tag
doesn’t match a structural tag or a text block on the current profile, it
falls back to placeholder substitution (see How the systems
differ); if that also finds nothing, the tag is
left as literal text.
New text blocks are created from a profile’s own Text blocks tab.
Whatever slug you give one becomes its tag name automatically. The “Default
Penetration Test Report” profile (seeded by seed_pentest_report_format)
ships with a worked example set:
| Tag | Label |
|---|---|
{{ executive_summary }} |
Executive Summary |
{{ risk_narrative }} |
Overall Risk Posture |
{{ root_cause_analysis }} |
Root Cause Analysis |
{{ effective_security_practices }} |
Effective Security Practices |
{{ additional_recommendations }} |
Additional Recommendations |
{{ rules_of_engagement }} |
Rules of Engagement |
{{ out_of_scope }} |
Out-of-Scope Items |
{{ emergency_contacts }} |
Emergency Contacts |
{{ testing_methodology }} |
Testing Methodology |
{{ cvss_scoring_methodology }} |
CVSS Scoring Methodology |
{{ risk_rating_matrix }} |
Risk Rating Matrix |
{{ tools_used }} |
Tools Used |
{{ tester_credentials }} |
Tester Credentials |
{{ glossary }} |
Glossary of Terms |
{{ conclusion }} |
Conclusion |
{{ confidentiality_disclaimer }} |
Confidentiality & Disclaimer |
These slugs aren’t reserved or built-in. They’re just what that one profile happens to use. A different profile is free to use different slugs entirely.
How the systems differ
Section titled “How the systems differ”| Placeholder tags | Structural tags | Custom text-block tags | |
|---|---|---|---|
| Where usable | Anywhere (Document body, text blocks, finding sections, observations, etc.) | Only as a standalone paragraph in the Document template | Only as a standalone paragraph in the Document template |
| Resolves to | A plain string | A pre-built section (table/chart/list) | Rich text (headings, lists, links, etc.) |
| Unknown tag | Printed literally, unchanged | Falls through to a custom-tag lookup, then a placeholder lookup, then printed literally | Falls through to a placeholder lookup, then printed literally |
| Recursive/nested? | No, single substitution pass, not re-scanned | No, resolved once per Document parse, never re-invoked on nested content | No, same as structural tags |
Practical example
Section titled “Practical example”A minimal but complete Document template:
# Executive Summary{{ executive_summary }}
# Scope, Rules of Engagement & Contacts## Rules of Engagement{{ rules_of_engagement }}## Out-of-Scope Items{{ out_of_scope }}## Emergency Contacts{{ emergency_contacts }}
# Testing Methodology{{ testing_methodology }}## Testing Coverage (Checklist){{ checklist_coverage }}
# Assessment Team{{ assessment_team }}
# Breakdown of Findings{{ breakdown_of_findings }}
# Detailed Findings{{ finding_details }}
# Appendix: Scanner Imports{{ scan_imports }}
# Confidentiality & Disclaimer{{ confidentiality_disclaimer }}For a fuller worked example (executive summary, root cause analysis,
effective security practices, additional recommendations, a conclusion, and
every appendix), see the profile built by
seed_pentest_report_format.
Within {{ executive_summary }}’s own authored content, you could write:
This assessment was performed for {{ client_name }} between {{ start_date }} and{{ end_date }}, under reference {{ reference_number }}.and client_name/start_date/end_date/reference_number will
substitute correctly, per engagement, every time it is rendered.
See also
Section titled “See also”- DOCX template guide: the parallel tag
system for an uploaded
.docxWord template, which differs in syntax ({{p tag }}for rich content) and adds a finding loop. - Reports & exports: the end-to-end generation workflow this page’s tags plug into.