<?xml version="1.0" encoding="utf-8"?>
<!-- 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
-->
<?xml-stylesheet type="text/xsl" href="https://rollerweblogger.org/roller-ui/styles/rss.xsl" media="screen"?><rss version="2.0" 
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:atom="http://www.w3.org/2005/Atom" >
<channel>
  <title>Blogging Roller</title>
  <link>https://rollerweblogger.org/roller/</link>
    <atom:link rel="self" type="application/rss+xml" href="https://rollerweblogger.org/roller/feed/entries/rss?tags=security" />
  <description>Dave Johnson on open web technologies, social software and software development</description>
  <language>en-us</language>
  <copyright>Copyright 2026</copyright>
  <lastBuildDate>Sat, 18 Jul 2026 12:47:24 +0000</lastBuildDate>
  <generator>Apache Roller 6.1.5</generator>
  <item>
    <guid isPermaLink="true">https://rollerweblogger.org/roller/entry/github-actions-and-digitalocean-lessons</guid>
    <title>GitHub Actions and DigitalOcean lessons from Claude</title>
    <dc:creator>Dave Johnson</dc:creator>
    <link>https://rollerweblogger.org/roller/entry/github-actions-and-digitalocean-lessons</link>
    <pubDate>Tue, 2 Jun 2026 21:30:00 +0000</pubDate>
    <category>Web Development</category>
    <category>actions</category>
    <category>cd</category>
    <category>ci</category>
    <category>claude</category>
    <category>code</category>
    <category>digitalocean</category>
    <category>github</category>
    <category>llms</category>
    <category>security</category>
    <category>terraform</category>
<atom:summary type="html">You might find this interesting if you use LLMs to generate code or GitHub Actions to deploy to DigitalOcean.</atom:summary><description>&lt;p&gt;I would say that 99% of the code in the&amp;nbsp;&lt;a href=&quot;https://snoopdavellc.com/investorping&quot; target=&quot;_blank&quot;&gt;Investor Ping&lt;/a&gt;&amp;#39;s backend and iOS app was written by LLMs, but I did not vibe code it. My definition of vibe coding is when you use an LLM to write code that you do not review or even read. Nope, I ran the project like I always do with design docs, issue tracking, pull requests and CI/CD sandbox and production deploys (in this case to DigitalOcean). I review all code and try to enforce some architectural constraints, mostly about separation of concerns, configuration and secrets management; but maybe less so in the iOS app because I am new to iOS and Swift.&lt;/p&gt;
&lt;p&gt;Despite that, I ended up with some poor security practices baked into my codebase. I knew that would happen given the volume of code I was generating and my desire to move fast.&lt;/p&gt;
&lt;p&gt;So, I worked with Claude Code to create a comprehensive &lt;strong&gt;security review&lt;/strong&gt; and Claude found eighteen issues that should be fixed; most were in GitHub Actions workflows and secrets; the rest were vulnerable NPM dependencies and application level problems. The review created is an impressive document that explains each problem and how to fix it. Claude made a list of the top five things to fix and three of them were good lessons to learn.&lt;/p&gt;
&lt;h5&gt;&lt;br&gt;&lt;/h5&gt;&lt;h5&gt;📍 Pin third-party GitHub Actions to a commit SHA&lt;/h5&gt;
&lt;p&gt;The &lt;strong&gt;first&lt;/strong&gt; item is to pin the third-party GitHub Actions used in my workflows to specific commit SHAs to reduce the chance of a supply chain attack. This seems reasonable and easy to do.&lt;/p&gt;
&lt;pre&gt;# Before — tag reference, mutable
- uses: actions/checkout@v4

# After — immutable SHA, version tag in comment for humans
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2&lt;/pre&gt;
&lt;h5&gt;&lt;br&gt;&lt;/h5&gt;&lt;h5&gt;🔐 Lock-down SSH with StrictHostKeyChecking=yes and ForceCommand&lt;/h5&gt;
&lt;p&gt;The &lt;strong&gt;second&lt;/strong&gt; item is about how CI/CD accesses the production servers via SSH using a 3rd party GitHub Action and &lt;code&gt;StrictHostKeyChecking=no&lt;/code&gt;. The workflow uses SSH to do deployment: to write config and secrets to a Docker Compose file and start up my containers. I think this is the most serious issue found. We don&amp;#39;t want CI/CD to have the keys to the kingdom.&lt;/p&gt;
&lt;p&gt;The fix is to add &lt;code&gt;StrictHostKeyChecking=yes&lt;/code&gt; and use an SSH feature called &lt;code&gt;ForceCommand&lt;/code&gt; to lock the SSH key down so that it can only run one specific script on the remote host, and to get the secrets to the hosts via a diferent route: a script I run on my laptop and a different SSH key.&lt;/p&gt;
&lt;p&gt;On the host, restrict the CI key in &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt;&amp;nbsp;to just the deploy script:&lt;/p&gt;
&lt;pre&gt;command=&amp;quot;/usr/local/bin/deploy.sh&amp;quot;,no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ssh-ed25519 AAAA...ci-key... ci-deploy@github&lt;/pre&gt;
&lt;p&gt;In the workflow, drop the third-party SSH action and pin the host key:&lt;/p&gt;
&lt;pre&gt;- name: Deploy
  env:
    DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
    SSH_KEY:     ${{ secrets.DEPLOY_SSH_KEY }}
    KNOWN_HOSTS: ${{ secrets.DEPLOY_KNOWN_HOSTS }}
  run: |
    install -d -m 700 ~/.ssh
    printf &amp;#39;%s\n&amp;#39; &amp;quot;$SSH_KEY&amp;quot;     &amp;gt; ~/.ssh/id_ed25519  &amp;amp;&amp;amp; chmod 600 ~/.ssh/id_ed25519
    printf &amp;#39;%s\n&amp;#39; &amp;quot;$KNOWN_HOSTS&amp;quot; &amp;gt; ~/.ssh/known_hosts &amp;amp;&amp;amp; chmod 600 ~/.ssh/known_hosts
    ssh -o StrictHostKeyChecking=yes -i ~/.ssh/id_ed25519 \
        deploy@&amp;quot;$DEPLOY_HOST&amp;quot; deploy&lt;/pre&gt;
&lt;h5&gt;&lt;br&gt;&lt;/h5&gt;&lt;h5&gt;🪖 Use least-privilege DigitalOcean access keys&lt;/h5&gt;
&lt;p&gt;&lt;strong&gt;Third&lt;/strong&gt;, CI/CD runs Terraform with an all-powerful DigitalOcean API access token when some workflows only need a couple of permissions.&lt;/p&gt;
&lt;p&gt;DO supports custom-scoped tokens (Control Panel → API → Generate New Token → Custom Scopes). Create one per workflow, stored as a separate GitHub secret, e.g. a token just for registry management:&lt;/p&gt;
&lt;pre&gt;jobs:
  tf-registry:
    environment: prod              # required reviewer before apply
    env:
      # token scopes: registry:read, registry:create, registry:delete
      DIGITALOCEAN_TOKEN: ${{ secrets.DO_TOKEN_REGISTRY }}
    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
      - uses: hashicorp/setup-terraform@b9cd47afb6f8aabd99b34a4673bf25b95f6d4d0d # v3.1.2
      - run: terraform -chdir=terraform/registry apply -auto-approve&lt;/pre&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;The &lt;strong&gt;fourth&lt;/strong&gt; and &lt;strong&gt;fifth&lt;/strong&gt; items were NPM dependencies with critical vulnerabilities that need an update. I feel like I need to learn some lessons in this area.&lt;/p&gt;
&lt;p&gt;It took me maybe three Claude Code sessions, a couple of afternoons, to deploy fixes for those five problems plus two others. In the end it was nine pull requests and  ~2,200 added / ~630 deleted lines of code.&lt;/p&gt;
&lt;p&gt;The overall lesson: rapidly producing code with LLMs leads to security and other problems, because try as you may, you can&amp;#39;t review every line. But a great LLM harness like Claude Code can search and probe your codebase from every angle and help you find and fix those problems quickly.&lt;/p&gt;
</description>  </item>
  <item>
    <guid isPermaLink="true">https://rollerweblogger.org/roller/entry/windows_security</guid>
    <title>Windows security</title>
    <dc:creator>Dave Johnson</dc:creator>
    <link>https://rollerweblogger.org/roller/entry/windows_security</link>
    <pubDate>Sat, 3 Feb 2007 23:34:15 +0000</pubDate>
    <category>Microsoft</category>
    <category>security</category>
    <category>vista</category>
<description>&lt;p&gt;Usually I find a couple of contradictory stories every time I read the feeds. Here&amp;#39;s a pair from today&amp;#39;s session. First via &lt;a href=&quot;http://daringfireball.net/2007/02/lies_damned_lies_and_bill_gates&quot;&gt;John Gruber&lt;/a&gt;. &lt;/p&gt;&lt;blockquote&gt;&lt;a href=&quot;http://www.msnbc.msn.com/id/16934083/site/newsweek/page/2/&quot;&gt;Bll Gates in Newsweek&lt;/a&gt;: Nowadays, security guys break the Mac every single day. Every single
day, they come out with a total exploit, your machine can be taken over
totally. I dare anybody to do that once a &lt;i&gt;month&lt;/i&gt; on the Windows machine.&lt;/blockquote&gt;&lt;p&gt;And next, via&amp;nbsp; &lt;a href=&quot;http://globalguerrillas.typepad.com/johnrobb/2007/02/unprotected_pc_.html&quot;&gt;John Robb&lt;/a&gt;, I found: &lt;br&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;a href=&quot;http://news.bbc.co.uk/2/hi/programmes/click_online/4423733.stm&quot;&gt;Spencer Kelly, BBC&lt;/a&gt;: We set up a poor Windows XP machine with no firewall or anti-virus software. Connecting it to the internet would be like throwing it into a lion pen with raw meat strapped to its hard drive. How long would it be before we were hit by something nasty on the net? Hours, minutes? As it turned out - eight seconds!&lt;/blockquote&gt;&lt;p&gt;Of course Bill may have been talking about Vista, even though he did not qualify. Maybe Vista is better, but I wouldn&amp;#39;t count on it. Initial reports &lt;a href=&quot;http://blogs.zdnet.com/Ou/?p=418&quot;&gt;don&amp;#39;t sound so good&lt;/a&gt; (Vista users: keep your speakers and microphones turned off).&lt;/p&gt;</description>  </item>
</channel>
</rss>