diff --git a/content/pages/404.md b/content/pages/404.md index ab2bd468..3ca1740e 100644 --- a/content/pages/404.md +++ b/content/pages/404.md @@ -2,9 +2,7 @@ Title: Page Not Found Status: hidden Save_as: 404.html URL: 404.html -Template: page +Template: 404 The page you were looking for is not here. It may have moved or never existed. - -- Head back to the [home page](/). -- Browse the [DevSecOps guide](/devsecops-guide.html). +Use the search box or the curated links to get back on track. diff --git a/pelicanconf.py b/pelicanconf.py index 929516d2..199399f7 100644 --- a/pelicanconf.py +++ b/pelicanconf.py @@ -218,14 +218,63 @@ def _asset_version() -> str: # Build-time stamp for the llms.txt provenance line. LLMS_GENERATED = datetime.date.today().isoformat() -# One-line intros rendered at the top of each /category/.html page. -# Keys match Category: frontmatter values exactly. +# Intros rendered at the top of each /category/.html page. Keys match +# Category: frontmatter values exactly. Rendered with the |safe filter (see +# themes/Flex/templates/category.html), so each value carries its own

+# blocks and may link key posts. Links are absolute (config strings cannot +# resolve Pelican {filename} refs). The well-populated categories get pillar +# intros that describe the cluster and point to its key posts; single-post +# categories keep a one-line intro. CATEGORY_INTROS = { - 'DevSecOps': 'Security defaults, pipeline hardening, and operational lessons from running production infrastructure under real adversary pressure.', - 'Kubernetes Security': 'Pod-level guardrails, RBAC, and the Pod Security Standards applied to production workloads.', - 'Incident Retrospectives': 'Post-mortems on real outages - what broke, why it broke, and what the industry should have learned.', - 'Projects': 'Tools, plugins, and one-off builds from my homelab and field work.', - 'Threat Intelligence': 'OSINT investigations and case studies on phishing infrastructure, nation-state operations, and emerging threats.', + 'DevSecOps': ( + '

DevSecOps here means security controls that survive contact with ' + 'production, not checklists that pass an audit and then rot. The ' + 'through-line is making the safe path the default path so engineers ' + 'take it without being told, and building guardrails that fail loud ' + 'instead of failing open.

' + '

Start with ' + 'adoption as a security control for why a control nobody uses is ' + 'not a control, then see it applied to identity in ' + 'IAM ' + 'roles that fail loud and ' + '' + 'IAM blast radius as an architecture problem. For the discipline ' + 'of not trusting your own tooling, read ' + '' + 'testing an IAM analyzer against its own claims.

' + ), + 'Kubernetes Security': ( + '

Pod-level guardrails, RBAC, and the Pod Security Standards applied ' + 'to production workloads.

' + ), + 'Incident Retrospectives': ( + '

Post-mortems on real outages - what broke, why it broke, and what ' + 'the industry should have learned.

' + ), + 'Projects': ( + '

Builds from the homelab and field work, written up for the ' + 'mechanism and the failure modes rather than the demo. Each one exists ' + 'because a real gap needed closing and the off-the-shelf answer did ' + 'not fit.

' + '

See ' + 'the Teensy EFI brute force that failed in public for what timing ' + 'assumptions cost you, and ' + '' + 'multi-phone Bluetooth tethering for Pwnagotchi for building a ' + 'fallback that holds when the primary link drops.

' + ), + 'Threat Intelligence': ( + '

Threat intelligence here is investigative work, not a feed ' + 'subscription: pulling on infrastructure, tradecraft, and public ' + 'signals until an operation is named. The focus is method you can ' + 'reproduce, not attribution you have to take on faith.

' + '

See ' + 'OSINT on a nation-state proxy for tracing phishing and influence ' + 'infrastructure from open sources, and ' + '' + 'prompt injection as a coming supply chain evasion technique for ' + 'where the next class of attacker tradecraft is heading.

' + ), } # Homepage featured posts: hand-picked slugs, ordered. Surfaced at the diff --git a/themes/Flex/templates/404.html b/themes/Flex/templates/404.html new file mode 100644 index 00000000..128e35d7 --- /dev/null +++ b/themes/Flex/templates/404.html @@ -0,0 +1,34 @@ +{% extends "base.html" %} +{% block title %}Page Not Found - {{ SITETITLE|default(SITENAME) }}{% endblock %} +{% block meta %} + + + {# Hidden page: base.html already emits noindex,nofollow for hidden_pages. + Mirror pagefind_search.html and load the Pagefind UI stylesheet here. #} + +{% endblock %} +{% block content %} +
+
+

Page Not Found

+
+

That page is not here. It may have moved or never existed. Search every + published post below, or jump to one of the curated links.

+ + + +
+{% endblock %} +{% block additional_js %} + + +{% endblock %} diff --git a/themes/Flex/templates/category.html b/themes/Flex/templates/category.html index 0502f724..1d9ba033 100644 --- a/themes/Flex/templates/category.html +++ b/themes/Flex/templates/category.html @@ -6,7 +6,9 @@ {% if CATEGORY_INTROS and category.name in CATEGORY_INTROS %}

{{ category.name }}

-

{{ CATEGORY_INTROS[category.name] }}

+ {# Intros are our own trusted config strings and may carry their own

+ blocks and links, so render them as HTML rather than escaped text. #} + {{ CATEGORY_INTROS[category.name]|safe }}

{% endif %} {{ super() }}