Report template tags
Every tag available in a Report Profile's Document template, and the rules for how the three tag systems combine.
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 |
|---|---|---|
{{ cover_page }} |
The report’s own cover page, built from the Report Profile’s Appearance settings and the engagement’s own fields (cover title, client, reference number, dates, classification label) | Not automatic: a template with no {{ cover_page }} tag gets no cover page at all, the same as any other structural tag |
{{ table_of_contents }} |
A table of contents, using the section numbers computed from your template’s own heading structure | Placement matters: sections above this tag in the template won’t be numbered relative to it, since numbering is computed by walking the template top to bottom |
{{ document_control }} |
A table of the engagement’s status history (stage / date / changed by) | Same content as {{p document_control }} in a DOCX template |
{{ breakdown_of_findings }} |
Severity/status bar chart (with a table fallback) plus a findings summary table (ID, severity, title, status) | |
{{ finding_details }} |
The full write-up for every included finding: metadata table, then each active finding section in its configured order (see Finding sections below, which includes Affected Assets), 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 user actually assigned to the engagement, showing their bio and qualifications | Omitted entirely if no one is assigned. Superadmins and anyone else with blanket instance-wide access are excluded unless they’re specifically assigned to this engagement |
{{ checklist_coverage }} |
The engagement’s checklist run(s), grouped by category, showing item status and any linked findings. A Blocked check’s status includes its reason (“Blocked: …”), so testing limitations appear in the report | 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. A fresh instance starts with zero
content sections; the table below is what
seed_pentest_report_format
creates as a starting point, and it’s fully editable afterward from
Finding structure:
| Order | Slug | Label | Supports images | Visible on client portal |
|---|---|---|---|---|
| 5 | risk_assessment |
Risk Assessment | No | Yes |
| 10 | description |
Description | No | Yes |
| 20 | impact |
Impact | No | Yes |
| 30 | steps_to_reproduce |
Steps to Reproduce | Yes | Yes |
| 40 | proof_of_concept |
Proof of Concept | Yes | Yes |
| 50 | affected_assets |
Affected URLs / Assets | No | Yes |
| 60 | recommendation |
Recommendation | 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.
Every deployment also always has an Affected Assets entry in this same
ordered list (slug affects), wherever it’s currently positioned. See
Affected Assets is a built-in, protected
section.
Unlike the sections above, it isn’t rich text and isn’t backed by
FindingSection content: it renders the finding’s own Affects field as
a plain list, and it can be repositioned/renamed but never deleted.
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”A side-by-side summary of the three systems described above, for when you just need a quick comparison rather than the full explanation of each:
| 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:
{{ cover_page }}
{{ table_of_contents }}
# Document Control{{ document_control }}
# 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.