<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Https · XB Field Notes</title><link>https://www.xbcatm.com/tags/https/</link><description>Illustrated field notes on HTTP, DNS, TLS, Caddy, SSH, releases, and recovery.</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://www.xbcatm.com/tags/https/index.xml" rel="self" type="application/rss+xml"/><item><title>Read the public edge in two commands</title><link>https://www.xbcatm.com/notes/read-the-public-edge-in-two-commands/</link><pubDate>Mon, 24 Aug 2026 00:00:00 +0000</pubDate><guid>https://www.xbcatm.com/notes/read-the-public-edge-in-two-commands/</guid><description>Run read-only probes against a live site and let the response headers and certificate dates confirm what you think is deployed.</description><content:encoded>&lt;p&gt;A deployment is complete when the public edge agrees with the files you chose, not when the last upload command exits zero. Two read-only helpers from the &lt;a href="https://www.xbcatm.com/resources/"&gt;operator kit&lt;/a&gt; make that agreement visible from any machine that can reach the host.&lt;/p&gt;
&lt;h2 id="inspect-the-response-headers"&gt;Inspect the response headers&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;check-http-headers.sh&lt;/code&gt; fetches one URL and prints the response line, the headers, and the final URL after redirects:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;check-http-headers.sh https://www.xbcatm.com/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A recent read against this site produced:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;HTTP/2 200
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;accept-ranges: bytes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;content-security-policy: default-src &amp;#39;self&amp;#39;; base-uri &amp;#39;self&amp;#39;; form-action &amp;#39;none&amp;#39;; frame-ancestors &amp;#39;none&amp;#39;; object-src &amp;#39;none&amp;#39;; script-src &amp;#39;none&amp;#39;; style-src &amp;#39;self&amp;#39;; img-src &amp;#39;self&amp;#39; data:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;content-type: text/html; charset=utf-8
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;last-modified: Mon, 24 Aug 2026 11:20:54 GMT
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;permissions-policy: accelerometer=(), camera=(), geolocation=(), gyroscope=(), microphone=(), payment=(), usb=()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;referrer-policy: strict-origin-when-cross-origin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;strict-transport-security: max-age=31536000; includeSubDomains
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;x-content-type-options: nosniff
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;x-frame-options: DENY
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;HTTP_STATUS 200
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;FINAL_URL https://www.xbcatm.com/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Two lines matter immediately: a &lt;code&gt;200&lt;/code&gt; status with a &lt;code&gt;FINAL_URL&lt;/code&gt; that matches the host you intended, and a &lt;code&gt;Content-Security-Policy&lt;/code&gt; that still says &lt;code&gt;script-src 'none'&lt;/code&gt;. If any of those differ from the policy you believe is live, the edge is not the tree you staged.&lt;/p&gt;
&lt;h2 id="inspect-the-certificate"&gt;Inspect the certificate&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;check-tls-expiry.sh HOST [DAYS]&lt;/code&gt; reads the public certificate for the hostname and enforces a minimum validity window:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;check-tls-expiry.sh www.xbcatm.com &lt;span class="m"&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A recent read printed:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;subject=CN=www.xbcatm.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;issuer=C=US, O=Let&amp;#39;s Encrypt, CN=YE1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;notBefore=Aug 21 08:37:13 2026 GMT
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;notAfter=Nov 19 08:37:12 2026 GMT
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;certificate remains valid for at least 30 day(s)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Notice the subject is the exact hostname, not a wildcard from an adjacent site. &lt;code&gt;notAfter&lt;/code&gt; is a concrete date; if it is closer than the window you passed, the helper exits non-zero and your release check can treat that as a failing condition.&lt;/p&gt;
&lt;h2 id="use-both-around-a-release"&gt;Use both around a release&lt;/h2&gt;
&lt;p&gt;Once before and once after you swap directories:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Before: record &lt;code&gt;last-modified&lt;/code&gt;, the CSP, and the certificate dates as your baseline.&lt;/li&gt;
&lt;li&gt;Deploy the staged tree.&lt;/li&gt;
&lt;li&gt;After: run the same two commands and compare &lt;code&gt;last-modified&lt;/code&gt; and the checksums.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The two outputs together are a small but complete contract: the certificate is current, the policy is intact, and the bytes changing at the edge match what you published. That is the evidence a release claim is allowed to be.&lt;/p&gt;
&lt;h2 id="sources"&gt;Sources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://caddyserver.com/docs/automatic-https"&gt;Caddy Automatic HTTPS&lt;/a&gt;, automatic TLS certificate management, checked 2026-08-24.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP"&gt;MDN: Content Security Policy guide&lt;/a&gt;, CSP directive names and syntax, checked 2026-08-24.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.openssl.org/3.0/man1/openssl-s_client/"&gt;OpenSSL &lt;code&gt;s_client&lt;/code&gt; documentation&lt;/a&gt;, SNI and certificate inspection options, checked 2026-08-24.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item></channel></rss>