Universal, platform-agnostic, zero-trust static publishing engine with automated Gitleaks scanning, headless Python DevSecOps quality gates, shift-left CLI tooling, and pluggable edge deployment adapters.
Traditional Content Management Systems (CMS) like WordPress or Drupal run monolithic application stacks: PHP interpreters, SQL databases, administrative user logins, and hundreds of third-party plugins. For technical blogs, research publications, and documentation portals, this architecture introduces a massive, unnecessary attack surface:
- SQL Injection (SQLi) and Broken Object-Level Authorization (BOLA).
- Admin Credential Stuffing and brute-force authentication attacks.
- Supply-Chain Vulnerabilities in dynamic server plugins.
- Accidental Draft & Workstation Leakage into publicly indexed assets.
The Solution: Treat static publishing like an enterprise software release.
This starter compiles markdown into an immutable static bundle (./public), validates that output against automated security, accessibility, and functional unit tests, and delivers it to edge CDNs with zero server-side runtime code.
A key design principle of this engine is Provider Independence:
graph TD
subgraph Core Gatekeeper [Platform-Agnostic Starter Engine]
A[Git Commit] --> B[Gitleaks Secret Scan]
B --> C[Hugo Extended Compilation]
C --> D[Headless Python Security, Functional & Agent Gates]
D --> E[Verified Static Artifact: ./public]
end
subgraph Pluggable Deployment Adapters [Destination Layer]
E -->|Adapter 1| F[Cloudflare Pages Deployer]
E -->|Adapter 2| G[GitHub Pages Deployer]
E -->|Adapter 3| H[AWS S3 + CloudFront Invalidation]
E -->|Adapter 4| I[Netlify Deployer]
end
The core verification workflow (.github/workflows/reusable-verify.yml) contains zero cloud provider tokens. It produces a cryptographically verified static artifact bundle that can be deployed to any hosting target.
Every build is validated against 5 automated quality pillars:
- Zero Heavy Framework Bloat: Scans compiled HTML, JS, and layout templates to prohibit heavy client-side frameworks (React, Vue, jQuery, Angular, Svelte runtime).
- Universal Design for Learning (UDL): Enforces lightweight vanilla HTML5/CSS and minimal progressive-enhancement JavaScript so content is 100% accessible on low-spec hardware and mobile networks.
- Draft Containment (
test_no_draft_leakage): Asserts that markdown files withdraft: trueare never compiled intopublic/, leaked intositemap.xml, or indexed inindex.json. - Future-Date Isolation (
test_no_future_dated_posts_leakage): Validates scheduled posts (publishDate > now) remain withheld whenbuildFuture = false. - Local Path Sanitization (
test_no_local_path_leakage): Confirms no workstation paths (C:\Users\...,/home/runner/...,/Users/...) leak into generated HTML/JS/JSON/CSS artifacts. - Sensitive File Elimination (
test_no_sensitive_files_in_public): Guarantees.env,.git,.lock, private keys (-----BEGIN KEY-----), or config secrets never end up in distribution. - Editorial Quarantine (
test_editorial_drafts_quarantine): Quarantines_distribution*, staging notes, and vault sync buffers.
- HTML5 Landmarks (
test_landmark_html5_semantics): Enforces<header>,<nav>,<main>, and<footer>semantic hierarchy on all viewable pages. - Keyboard Focus Indicators (
test_focus_visible_css_present): Requires visible:focus-visibleCSS rules for keyboard navigation. - SEO & Single H1 (
test_seo_single_h1_per_page): Restricts every non-redirect page to exactly one<h1>. - Accessible Imagery (
test_seo_image_alt_attributes): Requires non-emptyaltattributes on all images.
- Baseline Slug Verification (
test_canonical_slug_baseline_integrity): Validates that 100% of URLs indata/canonical_slugs.jsonexist in the build. - Root-Relative Isolation (
test_no_hardcoded_production_origin_in_templates): Internal navigation in templates and markdown must use root-relative links (/posts/or{{ .RelPermalink }}), keeping staging/preview and local environments isolated from production. - Academic Citation Integrity (
test_citation_identifier_formats): Enforces standard formatting for DOI (10.xxxx/...) and ORCID identifiers.
- Subresource Integrity (SRI) (
test_subresource_integrity_on_cdn_assets): Verifies external CDN assets enforce SHA hashes (sha256-,sha384-,sha512-) withcrossorigin="anonymous". - Tabnabbing Protection (
test_external_links_tabnabbing_protection): Ensures alltarget="_blank"links enforcerel="noopener noreferrer". - RFC 9116 Compliance (
test_security_txt_rfc9116): Validates.well-known/security.txthas a validContact:URI and futureExpires:timestamp. - Security Headers (
test_edge_security_headers): Enforces pre-configured HTTP security headers:/* X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN Content-Security-Policy: frame-ancestors 'self' Referrer-Policy: strict-origin-when-cross-origin Permissions-Policy: geolocation=(), camera=(), microphone=() Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
The test harness in tests/ is fully modular and dynamically configurable:
| Module | Purpose | Key Tests |
|---|---|---|
tests/test_security.py |
Anti-leakage, SRI, XSS, tabnabbing, headers | test_no_draft_leakage, test_no_future_dated_posts_leakage, test_no_local_path_leakage, test_subresource_integrity_on_cdn_assets, test_edge_security_headers, test_security_txt_rfc9116 |
tests/test_functional.py |
HTML semantic structure, SEO, sitemaps, RSS | test_html_document_structure, test_viewport_meta_responsive, test_seo_single_h1_per_page, test_canonical_links, test_internal_links_and_assets, test_sitemap_xml, test_rss_feed_xml |
tests/test_agent_rules.py |
AGENTS.md rules, static purity, landmarks, baseline slugs | test_static_purity_no_heavy_js_frameworks, test_landmark_html5_semantics, test_focus_visible_css_present, test_canonical_slug_baseline_integrity, test_no_hardcoded_production_origin_in_templates |
tests/test_utils.py |
Dynamic config discovery, DOM parsing, caching | Auto-detects hugo.toml, .devsecops.json, data/canonical_slugs.json, parses HTML AST |
Catch regressions and vulnerabilities on your local machine before pushing to git:
Run secret scans, Hugo compilation, and the full DevSecOps test harness:
python scripts/verify.pyOptions:
python scripts/verify.py -v: Enable verbose test execution output.python scripts/verify.py --skip-gitleaks: Skip local Gitleaks check (if not installed locally).python scripts/verify.py --skip-hugo: Run tests against existingpublic/directory.
Install the turnkey pre-push hook to automatically block any failing push:
python scripts/install_git_hooks.pyNow, every time you run git push, the entire DevSecOps test engine runs locally. If a draft leaks or a broken link is introduced, the push is safely aborted.
Adopt this entire DevSecOps engine into any private or public Hugo repository using GitHub Actions:
Create .github/workflows/deploy.yml in your repository:
name: Production Release Pipeline
on:
push:
branches: [main, master]
jobs:
# 1-Line DevSecOps Verification Gate
verify:
uses: SixFiveMil/hugo-devsecops-starter/.github/workflows/reusable-verify.yml@main
secrets: inherit
# Pluggable Deployment Adapter (runs only if 100% of gates pass)
deploy:
needs: verify
runs-on: ubuntu-latest
steps:
- name: Download Verified Static Artifact
uses: actions/download-artifact@v4
with:
name: verified-public-site
path: public/
# Example: Deploy to Cloudflare Pages
- name: Deploy to Cloudflare Pages
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy public --project-name=my-site --commit-dirty=trueThe starter ships with a pre-configured .github/dependabot.yml to automate vulnerability patching and continuous maintenance:
- GitHub Actions Ecosystem: Weekly automated updates for all actions in
.github/workflows/, grouped into a single unified PR to eliminate alert fatigue. - Git Submodules Ecosystem: Automatically tracks upstream releases and security patches for Hugo themes residing in
themes/*. - Zero-Trust Gated Validation: Dependabot PRs run under restricted read-only permissions and must pass 100% of the 33+ headless Python DevSecOps test gates and Gitleaks scans before merge approval.
When merging changes from develop into main, .github/workflows/release.yml automatically:
- Analyzes Conventional Commits: Computes semantic version increments (
feat:β minor,fix:/chore:/chore(deps-actions):β patch,BREAKING CHANGE:β major). - Creates Annotated Git Tags: Publishes
vX.Y.Ztags and updates floating major version pointers (e.g.,v1). - Publishes GitHub Releases: Automatically generates release notes and categorized changelogs for downstream dependency tracking.
The test engine automatically adapts to your site settings, with optional configuration overrides:
The engine automatically extracts baseURL, title, locale, buildDrafts, and buildFuture from hugo.toml.
Override or extend security rules:
{
"canonical_domain": "example.com",
"cdn_domains": [
"cdnjs.cloudflare.com",
"cdn.jsdelivr.net",
"unpkg.com"
],
"banned_js_frameworks": [
"react",
"react-dom",
"vue",
"angular",
"jquery"
],
"require_security_txt": true,
"require_edge_headers": true
}Protect your search rankings and citations by enforcing a baseline of permanent slugs:
[
"hello-devsecops",
"posts/getting-started",
"about"
]# 1. Clone repository
git clone https://github.com/SixFiveMil/hugo-devsecops-starter.git
cd hugo-devsecops-starter
# 2. Install pre-push hooks
python scripts/install_git_hooks.py
# 3. Start local development server
hugo server -D
# 4. Run full DevSecOps verification
python scripts/verify.pyThis engine was extracted and generalized from the production DevSecOps and release architecture powering Code and Cypher, an enterprise cybersecurity and cryptography research publication by Joshua A. Wortz.
This project is open-source under the MIT License.