Welcome to the Search Guard Documentation System.
The latest online version can be found here: Search Guard Documentation
- Technologies
- Quick Start
- Available Commands
- Project Structure
- Navigation System
- Adding Content
- Adding Changelogs
- Conventions
- Jekyll Plugins
- CI/CD Pipeline
- Troubleshooting
The documentation is based on:
- Ruby 3.0 - Programming language
- Jekyll 4.2.0 - Static site generator
- Kramdown - Markdown parser with GitHub Flavored Markdown (GFM) support
- Sass - CSS preprocessor
- Algolia - Full-text search engine
- HTMLProofer - Link validation tool
- VSDocs Documentation Templates - Base template
- Clone the repository:
git clone <repository-url>
cd search-guard-docs- Install Ruby dependencies:
bundle install- Start the development server:
bundle exec jekyll serve --watchThe site will be available at http://localhost:4000. The --watch flag tells Jekyll to automatically regenerate the site when files change.
Start development server:
bundle exec jekyll serve --watchBuild the site (production):
bundle exec jekyll buildBuild with version configuration:
bundle exec jekyll build --config _config.yml,_versions.ymlCheck for broken links:
# Build the site first
bundle exec jekyll build
# Run HTMLProofer
bundle exec htmlproofer ./_site --assume-extension .html --disable-external \
--url-ignore "/^\/(latest|[67]\.x-\d{2}|v[25])(\/|$)/" \
--alt-ignore '/.*/' --allow_hash_href trueRebuild Algolia search index:
bundle exec jekyll algolia push --config _config.yml,_versions.ymlNote: To skip search indexing during deployment, include "noindex" in your commit message.
Add section fields to all pages (bulk update):
./add_section_fields.shsearch-guard-docs/
├── _content/ # All documentation markdown files
│ ├── _changelogs/ # Changelog entries
│ ├── _docs_introduction/ # Introduction documentation
│ ├── _docs_installation/ # Installation guides
│ ├── _docs_tls/ # TLS/encryption configuration
│ ├── _docs_auth_auth/ # Authentication and authorization
│ ├── _docs_roles_permissions/ # RBAC documentation
│ ├── _docs_kibana/ # Kibana integration
│ ├── _docs_signals/ # Alerting (Signals feature)
│ ├── _docs_aim/ # Automated Index Management
│ ├── _docs_dls_fls/ # Document and Field-Level Security
│ ├── _docs_audit_logging/ # Audit logging
│ ├── _docs_encryption_at_rest/ # Encryption at rest
│ ├── _docs_ad/ # Anomaly Detection
│ ├── _docs_category_pages/ # Auto-generated category pages
│ └── ... # Other collections
├── _data/ # YAML/JSON data files
│ ├── main_navigation_sections.yml # Main nav section definitions
│ ├── side_navigation_main_structure.yml # Side nav orchestrator
│ ├── side_navigation_security.yml # Security section navigation
│ ├── side_navigation_alerting.yml # Alerting section navigation
│ ├── side_navigation_index_management.yml
│ ├── side_navigation_encryption_at_rest.yml
│ ├── side_navigation_anomaly_detection.yml
│ ├── sgversions_docroots.yml # Version dropdown data
│ └── breadcrumbs.yml # Auto-generated (git-ignored)
├── _diagrams/ # Diagrams (PNG + draw.io sources)
├── _includes/ # Reusable template fragments
│ ├── main_navigation.html # Top navigation bar
│ ├── left_navigation.html # Side navigation
│ ├── left_navigation_item.html # Recursive nav item renderer
│ ├── breadcrumbs.html # Breadcrumb navigation
│ └── ... # Other includes
├── _layouts/ # Page layout templates
│ ├── docs.html # Main documentation layout
│ ├── search.html # Search results layout
│ └── versionmatrix.html # Version compatibility layout
├── _plugins/ # Custom Jekyll plugins
│ ├── category_pages_generator.rb # Auto-generate category pages
│ ├── breadcrumbs_generator.rb # Generate breadcrumb data
│ ├── search.rb # Algolia search integration
│ ├── custom_kramdown.rb # Custom code block rendering
│ └── file_normalizer.rb # File name normalization
├── sass/ # Sass/SCSS source files
│ ├── _sg_navigation.scss # Navigation styles
│ ├── _sg_code.scss # Code block styles
│ └── ... # 60+ other style modules
├── css/ # Compiled CSS output
├── js/ # JavaScript files
├── fonts/ # Font files
├── img/ # Images and graphics
├── _site/ # Generated static site (git-ignored)
├── _config.yml # Main Jekyll configuration
├── _versions.yml # Version-specific configuration
├── Gemfile # Ruby dependencies
└── index.md # Homepage
_content/ - All documentation markdown files organized by Jekyll collections. Each subdirectory represents a logical grouping of related documentation.
_data/ - YAML files containing structured data, primarily navigation structures and metadata.
_includes/ - Reusable template components that can be included in layouts and pages.
_layouts/ - Page templates that wrap content with HTML structure.
_plugins/ - Custom Ruby plugins that extend Jekyll's functionality.
sass/ - Sass source files that compile to CSS.
_site/ - Generated static HTML (not tracked in git).
The documentation uses a section-based navigation system with two levels:
Displays 5 clickable section tabs plus Versions and Contact:
Security | Alerting | Index Management | Encryption at Rest | Anomaly Detection | Versions | Contact
Configuration: _data/main_navigation_sections.yml
sections:
- title: Security
slug: security # Landing page permalink
key: security # Used in page frontmatter
nav_file: side_navigation_security # Side nav file to load
- title: Alerting
slug: elasticsearch-alerting
key: alerting
nav_file: side_navigation_alerting
# ... additional sectionsShows a hierarchical tree of pages within the active section. The displayed navigation is determined by the page's section field.
Behavior:
- Pages with
sectionfield: Shows only that section's navigation tree - Homepage (
isroot: true): Shows a flat list of the 5 main sections - Pages without section: Fallback to showing all sections
Configuration: Each section has its own navigation YAML file in _data/:
side_navigation_security.ymlside_navigation_alerting.ymlside_navigation_index_management.ymlside_navigation_encryption_at_rest.ymlside_navigation_anomaly_detection.yml
Navigation Structure:
- title: Security
slug: security
children:
- title: Introduction to Search Guard
slug: search-guard-introduction
children:
- title: Overview
slug: security-for-elasticsearch
- title: Main Concepts
slug: main-concepts
- title: TLS Setup
slug: search-guard-security-tls-setup
children:
- title: Configuring TLS
slug: configuring-tlsImportant: The slug in navigation files MUST match the permalink in page frontmatter exactly (1:1 match).
Breadcrumbs are auto-generated from the navigation structure by the breadcrumbs_generator.rb plugin. The plugin inverts the navigation tree to create a lookup table mapping each page to its ancestor path.
-
Create a markdown file in the appropriate collection directory:
- Security pages →
_content/_docs_*(auth_auth, tls, roles_permissions, etc.) - Alerting pages →
_content/_docs_signals/ - Index Management →
_content/_docs_aim/ - Encryption at Rest →
_content/_docs_encryption_at_rest/ - Anomaly Detection →
_content/_docs_ad/
- Security pages →
-
Add frontmatter to the markdown file:
---
title: Configuring TLS
html_title: TLS Configuration Guide # Optional
permalink: configuring-tls # Required, lowercase with dashes
layout: docs # Required
section: security # Required (security, alerting, index_management, encryption_at_rest, anomaly_detection)
description: How to configure TLS for Search Guard # Optional but recommended
edition: enterprise # Optional (community or enterprise)
---- Add the page to navigation in the appropriate
_data/side_navigation_*.ymlfile:
- title: TLS Setup
slug: search-guard-security-tls-setup
children:
- title: Configuring TLS
slug: configuring-tls # Must match permalink exactly!- Write your content using Markdown with GitHub Flavored Markdown (GFM) syntax.
To add a new main section (e.g., "Machine Learning"):
- Create a collection directory:
mkdir _content/_docs_ml- Declare the collection in
_config.yml:
collections:
docs_ml:
output: true
permalink: :name
algolia_hierarchy: "Machine Learning"- Add section to main navigation in
_data/main_navigation_sections.yml:
sections:
# ... existing sections ...
- title: Machine Learning
slug: machine-learning
key: machine_learning
nav_file: side_navigation_machine_learning- Create side navigation file
_data/side_navigation_machine_learning.yml:
- title: Machine Learning
slug: machine-learning
children:
- title: Getting Started
slug: ml-getting-started
- title: Configuration
slug: ml-configuration- Add to side navigation orchestrator in
_data/side_navigation_main_structure.yml:
files:
- side_navigation_security
- side_navigation_alerting
- side_navigation_index_management
- side_navigation_encryption_at_rest
- side_navigation_anomaly_detection
- side_navigation_machine_learning # Add here- Create the landing page at
_content/_docs_category_pages/machine_learning.md:
---
title: Machine Learning
html_title: Machine Learning
permalink: machine-learning
layout: docs
section: machine_learning
index: false
description: All pages in the category Machine Learning
---
# Machine Learning
Browse all documentation pages in the Machine Learning category:
* [Getting Started](ml-getting-started)
* [Configuration](ml-configuration)- Create your documentation pages in
_content/_docs_ml/withsection: machine_learningin their frontmatter.
Changelogs are integrated into the Security section's navigation.
- Create a markdown file in
_content/_changelogs/:
_content/_changelogs/changelog_searchguard_flx_4_0_0.md- Add frontmatter:
---
title: Search Guard FLX 4.0.0
permalink: changelog-searchguard-flx-4_0_0
layout: docs
section: security
description: Changelog for Search Guard FLX 4.0.0
index: false
sitemap: false
----
Write changelog content using markdown.
-
Add to changelog navigation in the appropriate changelog main page (e.g.,
_content/_changelogs/changelogs_searchguard_main.md).
Changelogs are accessible via:
- Main Navigation: Security → Changelogs (in side nav)
- Side Navigation Structure: Defined in
_data/side_navigation_security.yml:
- title: Changelogs
slug: changelogs-section
children:
- title: Search Guard Security
slug: changelogs-searchguard
- title: Kibana
slug: changelogs-kibana
- title: TLS Tool
slug: changelogs-tlstool
- title: Encryption at Rest
slug: changelogs-earPermalinks:
- Lowercase only
- Use dashes (
-) as word delimiters - Example:
configuring-tls - NEVER change a permalink without coordinating a 301 redirect!
Filenames:
- Lowercase only
- Use underscores (
_) as word delimiters - Example:
configuring_tls.md
SEO Importance: Permalinks are critical for SEO. Do not change them unless absolutely necessary and only after coordinating with DevOps for 301 redirect setup.
Use these exact values for the section field in frontmatter:
security- Security documentationalerting- Alerting/Signals documentationindex_management- Index Management documentationencryption_at_rest- Encryption at Rest documentationanomaly_detection- Anomaly Detection documentation
Critical Rule: The slug value in navigation YAML files MUST match the permalink in the page's frontmatter exactly (1:1 match).
Navigation file:
- title: Configuring TLS
slug: configuring-tlsPage frontmatter:
permalink: configuring-tlsAlways use the permalink/slug, NOT the file path:
✅ Correct:
[Search Guard FLX 3.0.0](changelog-searchguard-flx-3_0_0)❌ Incorrect:
[Search Guard FLX 3.0.0](../_changelogs/changelog_searchguard_flx_3_0_0.md)Required:
title- Page titlepermalink- URL sluglayout- Usuallydocssection- Section identifier
Optional but Recommended:
html_title- SEO-optimized titledescription- Meta description for search enginesedition-communityorenterpriseresources- Array of external resource linksindex_algolia- Set tofalseto exclude from search (default:true)
Location: _plugins/category_pages_generator.rb
Purpose: Automatically generates landing pages for navigation items that have children but no corresponding content file.
How it works:
- Reads all navigation YAML files
- For each nav item with children, checks if a content file exists with that permalink
- If no file exists, generates a category page listing all children
- NEW: Automatically adds the correct
sectionfield to generated pages based on which navigation file they belong to
Generated pages are placed in: _content/_docs_category_pages/
Example: If your navigation has:
- title: Introduction to Search Guard
slug: search-guard-introduction
children:
- title: Overview
slug: security-for-elasticsearchAnd no file exists with permalink: search-guard-introduction, the plugin auto-generates one.
Location: _plugins/breadcrumbs_generator.rb
Purpose: Generates an inverted lookup table of the navigation structure for efficient breadcrumb rendering.
How it works:
- Reads
side_navigation_main_structure.yml - Recursively processes each navigation tree
- Creates a hash mapping each slug to its full ancestor path
- Writes to
_data/breadcrumbs.yml(git-ignored)
Example output:
security:
- title: Security
slug: security
search-guard-introduction:
- title: Security
slug: security
- title: Introduction to Search Guard
slug: search-guard-introductionLocation: _plugins/search.rb
Purpose: Custom hook to chunk documentation content for better search granularity.
How it works:
- Breaks down each page into chunks by headings (h1-h5)
- Each chunk becomes a separate searchable record in Algolia
- Records include hierarchical categorization via
algolia_hierarchy - 20KB size limit per chunk
Note: The algoliasearch-jekyll gem is deprecated but still functional.
Location: _plugins/custom_kramdown.rb
Purpose: Renders fenced code blocks with special HTML structure for copy-to-clipboard functionality.
Features:
- Adds wrapper elements around code blocks
- Enables "Copy Code" button functionality
- Preserves syntax highlighting
Location: _plugins/file_normalizer.rb
Purpose: Normalizes file names to ensure consistency.
Location: .gitlab-ci.yml
- Merge conflict detection: Checks for merge markers
- Clean build: Removes old
_sitedirectory - 2-pass Jekyll build:
- First pass generates basic pages
- Second pass includes auto-generated category pages
- Link validation: Runs HTMLProofer to check for broken internal links
Triggers: Only on release branch
- SFTP Upload: Deploys
_siteto production server - Cloudflare Cache Purge: Clears CDN cache
- Algolia Index Rebuild: Updates search index (unless commit message contains "noindex")
sftp_server- SFTP server addresssftp_user_name- SFTP usernamesftp_user_private_key_base64- SSH private key (base64 encoded)SG_CLOUDFLARE_ZONEID- Cloudflare zone IDSG_CLOUDFLARE_DECACHE_TOKEN- Cloudflare API tokenALGOLIA_APPLICATION_ID- Algolia application IDALGOLIA_API_KEY- Algolia admin API key
Jekyll 4.2.0 is compatible with Ruby 3.0-3.2. If you have Ruby 3.3+, you may encounter errors.
Solution:
# Use rbenv or rvm to switch Ruby version
rvm use 3.0.0
# or
rbenv local 3.0.0
# Reinstall dependencies
bundle installCommon issues:
- Missing gems: Run
bundle install - Sass compilation errors: Check syntax in
sass/*.scssfiles - Plugin errors: Check Ruby syntax in
_plugins/*.rbfiles - YAML parsing errors: Validate YAML files in
_data/directory
Checklist:
- Verify
sectionfield in page frontmatter matches a key inmain_navigation_sections.yml - Check that navigation YAML file is listed in
side_navigation_main_structure.yml - Ensure
slugin navigation matchespermalinkin page frontmatter exactly - Rebuild the site to regenerate breadcrumbs
- Rebuild Algolia index:
bundle exec jekyll algolia push - Check that
index_algolia: falseis not set in frontmatter - Verify Algolia credentials in
_config.yml
Run HTMLProofer:
bundle exec jekyll build
bundle exec htmlproofer ./_site --assume-extension .html --disable-external \
--url-ignore "/^\/(latest|[67]\.x-\d{2}|v[25])(\/|$)/" \
--alt-ignore '/.*/' --allow_hash_href true- Rebuild the site: Sass files need recompilation
- Hard refresh browser: Ctrl+F5 or Cmd+Shift+R
- Check file location: Ensure changes are in
sass/notcss/ - Verify import: Check that SCSS file is imported in main stylesheet
For issues or questions:
- Internal documentation team
- Search Guard Forum
- Search Guard Contact