How to Secure Github Actions Workflows

Explore top LinkedIn content from expert professionals.

Summary

Securing GitHub Actions workflows means making sure your automated processes (like testing and deployment) aren’t vulnerable to attacks that could steal secrets or disrupt your code releases. With supply chain threats on the rise, careful setup and ongoing monitoring helps protect both your CI/CD pipeline and developer workstations from compromise.

  • Pin actions carefully: Always pin GitHub Actions to a verified commit SHA instead of tags to make sure you’re running trusted code, and review dependencies before updating.
  • Limit permissions: Restrict workflow access so only the necessary branches, repositories, or environments can assume sensitive roles or deploy to production.
  • Sanitize inputs: Treat all user input and AI-generated output as untrusted, never let unverified data influence workflow automation, and regularly scan files for vulnerable patterns.
Summarized by AI based on LinkedIn member posts
Image Image Image
  • View profile for Yan Cui
    51,403 followers

    Wiz published a great guide on hardening GitHub Actions. For AWS teams, this is worth more than a quick skim. Most of you know the basics already: * Use least-privilege permissions. * Avoid long-lived secrets. * Be careful with third-party actions. * Pin your dependencies. But there are a few points in the article that are easy to miss, and they matter a lot when your CI/CD pipeline can deploy to AWS. 1. Tag pinning is weaker than many teams think Pinning an action to v3 or v4 is better than nothing, but tags can move. If you want stronger supply-chain protection, pin actions to a full commit SHA. That way, your workflow runs the exact code you reviewed, not whatever code that tag points to later. 2. SHA pinning still doesn't remove all risk An action can have its own dependencies. So even if the action itself is pinned, you still need to think about transitive dependencies and whether you adopt new versions too quickly after release. Similar to how we should use NPM's minimumReleaseAge to avoid fresh versions, so the community has time to catch malicious updates, we should use a short cooldown period before updating third-party actions. 3. pull_request_target deserves extra caution This trigger can run with elevated permissions compared with a normal pull request workflow. That may be useful for some automation, but it can become dangerous if the workflow checks out and runs code from an untrusted PR. (See my previous post on how this can be exploited https://lnkd.in/e6-cjV-u) For AWS teams, this is especially important if the workflow can assume a role, deploy infrastructure, publish artefacts, or access production data. 4. OIDC is better than storing AWS keys in GitHub Secrets But do not stop there. Lock the role trust policy down to the specific repository, branch, environment, or workflow that should be allowed to assume it. For example, a production deployment role should not be assumable from every branch, every workflow, or every pull request. ----- Supply chain attacks are on the rise, and CI/CD pipelines have become a popular target (see the recent Trivy and Axios compromises). Often, attackers aim to steal sensitive data, such as AWS credentials, from our pipelines and use them to establish a foothold in our AWS environments (see the recent European Commission compromise). We need to pay more attention to securing our CI/CD pipelines, so this guide has come out at a good time! Read the full article here: https://lnkd.in/eJyMqyUC

  • Two weeks ago, I wrote that attackers no longer need code review approval. They just need automation to run. This week’s follow-up is even more direct: a lot of the recent GitHub Actions attacks were not exotic zero-days. They were basic workflow hygiene failures — mutable action tags, unsafe use of untrusted inputs, and over-privileged tokens. Those are exactly the kinds of issues disciplined policy-as-code scanning should catch before a pipeline ever runs. This is why supply chain security has to start with policy-as-code discipline and hygiene in CI/CD. - Review workflow files like production code. - Pin third-party actions by SHA. - Default tokens to least privilege. - Treat PR metadata, comments, and other untrusted inputs as hostile. - And enforce these checks continuously, not occasionally. Attackers are not winning because of magical new zero-days. They are winning because basic CI/CD and software supply chain security hygiene is still inconsistent. Recent GitHub Actions attacks exploited workflow misconfigurations that should never make it to runtime: mutable tags, unsafe interpolation of untrusted input, and over-privileged tokens. Policy-as-code based guardrails can catch many of these issues early and turn fragile pipelines into governed ones. In 2026, supply chain security starts with workflow hygiene. If it runs in CI/CD, it needs guardrails. https://lnkd.in/gz2ktNBF #RSA #policyascode #softwaresupplychainsecurity

  • 🚨𝗪𝗲 𝗣𝘄𝗻𝗲𝗱 𝗚𝗼𝗼𝗴𝗹𝗲 𝗚𝗲𝗺𝗶𝗻𝗶 𝗮𝗻𝗱 𝗺𝘂𝗹𝘁𝗶𝗽𝗹𝗲 𝗼𝘁𝗵𝗲𝗿 𝗙𝗼𝗿𝘁𝘂𝗻𝗲 𝟱𝟬𝟬 𝗰𝗼𝗺𝗽𝗮𝗻𝗶𝗲𝘀 𝗯𝘆 𝘂𝘀𝗶𝗻𝗴 𝗽𝗿𝗼𝗺𝗽𝘁 𝗶𝗻𝗷𝗲𝗰𝘁𝗶𝗼𝗻 𝗶𝗻 𝘁𝗵𝗲𝗶𝗿 𝗚𝗶𝘁𝗛𝘂𝗯 𝗔𝗰𝘁𝗶𝗼𝗻𝘀 Rein Daelman and the rest of the Aikido Security research team uncovered a new class of GitHub Actions vulnerabilities triggered by using AI agents (Gemini, Claude Code Actions, OpenAI Codex, GitHub AI Inference) within GitHub Action workflows. 𝗕𝗲𝗰𝗮𝘂𝘀𝗲 𝗮𝗹𝗹 𝘁𝗵𝗲 𝗴𝗼𝗼𝗱 𝘃𝘂𝗹𝗻𝘀 𝗵𝗮𝘃𝗲 𝗰𝘂𝘁𝗲 𝗻𝗮𝗺𝗲𝘀 𝗻𝗼𝘄, 𝘄𝗲 𝗮𝗿𝗲 𝗰𝗮𝗹𝗹𝗶𝗻𝗴 𝘁𝗵𝗶𝘀 𝗣𝗿𝗼𝗺𝗽𝘁𝗣𝘄𝗻𝗱  As you may guess by the name, it is essentially prompt injection through the GitHub actions workflow, which is pretty wild. The problem is actually quite simple: untrusted data, like a commit message, is being used within prompts for GitHub Actions. The result is that we can use this to get AI tools to perform like posting secrets publicly.  𝗨𝗻𝘁𝗿𝘂𝘀𝘁𝗲𝗱 𝘂𝘀𝗲𝗿 𝗶𝗻𝗽𝘂𝘁 → 𝗶𝗻𝘀𝗲𝗿𝘁𝗲𝗱 𝗶𝗻𝘁𝗼 𝗔𝗜 𝗽𝗿𝗼𝗺𝗽𝘁𝘀 → 𝗔𝗜 𝗮𝗴𝗲𝗻𝘁𝘀 𝗲𝘅𝗲𝗰𝘂𝘁𝗲 𝗽𝗿𝗶𝘃𝗶𝗹𝗲𝗴𝗲𝗱 𝗚𝗶𝘁𝗛𝘂𝗯 𝘁𝗼𝗼𝗹𝘀 → 𝘀𝗲𝗰𝗿𝗲𝘁𝘀 𝗹𝗲𝗮𝗸𝗲𝗱 𝗼𝗿 𝘄𝗼𝗿𝗸𝗳𝗹𝗼𝘄𝘀 𝗺𝗮𝗻𝗶𝗽𝘂𝗹𝗮𝘁𝗲𝗱. A single issue, PR description, or commit message can silently contain instructions the AI will follow. Example of a vulnerable pattern inside a GitHub Action: 𝘱𝘳𝘰𝘮𝘱𝘵: | 𝘙𝘦𝘷𝘪𝘦𝘸 𝘵𝘩𝘦 𝘪𝘴𝘴𝘶𝘦: "${{ 𝘨𝘪𝘵𝘩𝘶𝘣.𝘦𝘷𝘦𝘯𝘵.𝘪𝘴𝘴𝘶𝘦.𝘣𝘰𝘥𝘺 }}" That innocent line can leak your GITHUB_TOKEN, cloud access tokens, or API keys, because the AI treats attacker-controlled text as instructions, then uses its built-in tools (like gh issue edit) to execute them. Following our disclosure in August, Google patched the Gemini CLI workflow which is no longer vulnerable and we have sent out multiple disclosures to other orgs. 𝗛𝗼𝘄 𝘁𝗼 𝗰𝗵𝗲𝗰𝗸 𝗶𝗳 𝘆𝗼𝘂'𝗿𝗲 𝗮𝗳𝗳𝗲𝗰𝘁𝗲𝗱 ✔️ Scan your GitHub Action files with Opengrep (we created open-source rules to detect this)  ✔️ Or scan with Aikido Security, our free version flags vulnerable patterns automatically 𝗛𝗼𝘄 𝘁𝗼 𝗳𝗶𝘅 𝗶𝘁 – Restrict which tools your AI agents can call  – Don’t inject untrusted user text into prompts  – Sanitize/validate user input if unavoidable  – Treat AI output as untrusted code AI in CI/CD is powerful… but also a brand-new attack surface. If you’re using AI inside GitHub Actions, now is the time to audit your workflows. Link in comments friends.

  • 🚨 Another GitHub Action compromised today: simonecorsi/mawesome This is the second action compromise we are tracking today, and it uses the same technique as the earlier codfish/semantic-release-action incident. Almost certainly the same attacker. 🔁 A few things from the earlier compromise that are worth highlighting, because they change how defenders should think about this class of attack: 🏷 The attacker published the major version tags, including v5, as immutable tags pointing at the malicious commit. Once a tag is marked immutable on GitHub, it cannot be moved. 💻 The malicious code does not stop at exfiltrating CI/CD credentials. It also writes malicious VS Code settings and Cursor rules files into every branch of the repository. Any developer who later clones this repo and opens it in VS Code or Cursor will silently execute the attacker's payload, turning a CI/CD compromise into a developer machine compromise. 🎯 This is a pattern we are seeing more and more: a single supply chain compromise designed to hit both CI/CD pipelines AND developer workstations. ⏱ Also worth noting: the earlier codfish/semantic-release-action repository is still in a compromised state nearly 9 hours after the initial compromise was identified. The malicious commits and immutable tags have not been remediated. Anyone running the action today is still pulling the attacker's code. 🛡 StepSecurity customers are protected on multiple fronts: 🚫 The Compromised Actions Policy has been updated to block simonecorsi/mawesome (and codfish/semantic-release-action). Workflows referencing either action are blocked before they execute. ⛔ StepSecurity Harden Runner blocks both compromised actions at runtime. The malicious payload reads memory from the Runner.Worker process to harvest CI/CD secrets, a behavior Harden Runner detects and prevents on every protected workflow, regardless of which action introduces it. 🧰 Dev Machine Guard now includes a recently shipped capability that detects suspicious IDE extension settings and rules files (VS Code settings.json, Cursor rules, etc.) dropped into repositories on developer machines. This is exactly the persistence mechanism this attacker is using. ✅ If you use either action: stop using it immediately, pin to a known good commit SHA from before the compromise, rotate any secrets exposed to recent workflows, and check developer machines that have cloned these repositories for the dropped IDE config files.

  • 🚨 On March 19, Trivy, one of the most widely used open-source vulnerability scanners, was compromised for the second time in three weeks, including the trivy-action and setup-trivy GitHub Actions used by ~40,000 repositories. On March 22, trivy Docker Hub images (v0.69.5 and v0.69.6) were found to be compromised as well. 🔍 Here's what we did on the community side: → StepSecurity Harden-Runner's free community tier, used by 12,000+ open-source projects, detected the compromised trivy Action and trivy binary making anomalous outbound connections to the attacker's C2 domain in real time from several open-source projects. → We open-sourced trivy-compromise-scanner and ran it across prominent users of the affected actions to identify compromised workflow runs. → We found multiple CNCF projects, healthcare standards projects, and other widely used repositories that had executed the compromised action during the incident window. → We responsibly disclosed our findings to the maintainers of all affected projects through GitHub issues and other channels, so they could assess their exposure and rotate credentials. 🛡️ If you use GitHub Actions, here are free community resources that can help with this incident and future ones: → secure-workflow / secure-repo: Automatically pins your GitHub Actions to commit SHAs, which would have prevented the tag-hijacking technique used in this attack. secure-workflow is free for everyone, and secure-repo is free for open-source repositories. → Harden-Runner: Monitors and filters runtime network egress from your CI/CD workflows, flagging anomalous connections. Free for open-source. → trivy-compromise-scanner: Check if any of your repository's workflow runs executed the compromised action. Free for everyone. 🤝 We want to make sure the community has the tools to detect and respond to these incidents quickly. If you have questions about your exposure or need help, reach out. We are happy to help. 📎 Find the link to the community tools and blog post in comments.

  • I've been using GitHub Actions since they were in beta. Today's update is the biggest I've seen, and the headline feature is not the reason. GitHub Agentic Workflows are now in public preview. You describe automation in plain Markdown; it compiles into the same workflow files that Actions already runs, and coding agents inside your pipeline pick up the work. Issue triage, build-failure analysis, and documentation updates all run without a human driving. Plenty of updates since the beta made Actions bigger, faster, and easier to share. This is the first one that changes what a workflow is. A workflow was a script that did exactly what you wrote. Now it can be an agent that decides. The security model is the real story here. The agents run read-only. The credentials that can write stay in separate jobs that the agent never touches, so a change becomes a request, not an action. They work inside a sealed sandbox, behind a firewall that controls what they can reach. Filters govern what content is allowed to steer them. And before any request lands, a dedicated threat-detection job inspects it and blocks anything suspicious. Read that list again as a governance map. Permissions are scoped before the agent starts, the boundary is enforced while it runs, and the output is verified before anything lands. Yesterday I wrote that the lines where agents reach their tools are the busiest crossings in an agent system and the least watched. Today GitHub put a watchtower on one of them and turned it on by default. The teams that read security sections as feature lists will govern coding agents before their first incident. Everyone else will keep bolting guardrails on afterward, wondering why trust arrived faster than oversight.

  • Hey Engineering Leaders -- see this setting in your GitHub Org Settings? ⬇️ **"Require actions to be pinned to a full-length commit SHA"** Sounds perfect, right? With the recent GH Action security concerns, we thought so. Flip the switch and your CI/CD pipelines are safe from supply chain attacks we thought. Here's the problem: **this applies to transitive dependencies too.** Your action pins `trunk-io/trunk-action@sha123` -- great. But trunk's action internally uses `peter-evans/find-comment@v3`. That's not SHA-pinned. So GitHub blocks your entire workflow. Your options become: - Allowlist every upstream action org -- defeats the purpose - Fork and maintain your own versions -- not fun - File PRs with every upstream action to get them to SHA-pin their deps -- not fun + good luck I do understand why GH built it this way -- actions aren't packaged artifacts from a registry. They're just YAML files pulling other YAML files. Even if YOU pin to a SHA, the action's own `uses:` references can change underneath you. So GH enforces the whole chain or nothing. We're going to go a different direction: SHA-pin everything we control, use zizmor for enforcement, and file PRs upstream where we can. How is your team handling GH Actions supply chain security? Are you enforcing SHA pinning somehow and limiting the use of marketplace actions, or just trusting Dependabot and hoping for the best? We're figuring this out internally, but I'm curious what others are doing in this realm -- share in the comments below! #github #devops #security #supplychainsecurity #cicd #platformengineering #infrastructure #githubactions

  • One of the awesome things about GitHub Actions is that you can use it to completely automate the running of scripts. There are infinite use cases for this, but a common one is to create some kind of report/dashboard/table/visualization/etc that gets automatically updated whenever the newest data are available. This is great when the data are publicly available and are easy to get your hands on, but what about when you need to authenticate before you can access what you're looking for? 🤔 Using a .Renviron file is a great way to avoid putting passwords/API keys/etc directly in your scripts. You can make reference to the confidential information by using the `Sys.getenv` function, and `Sys.getenv` will pull the information from the .Renviron file. 👏 Authentication is a bigger deal when you're using GitHub Actions, though, as compared to running something locally on your own computer, since the stakes are higher -- if you accidentally upload the .Renviron file, or accidentally put the password directly in your code somewhere, now it's online for anyone in the world to see and use. In my newest #rstats video, I walk through how to use "Actions Secrets" in your GitHub Actions workflows. This provides a safe way to perform authentication (or use other confidential info) when you're using GitHub Actions and GitHub Pages. You can create "repository secrets" and define environment variables, and then you'll be able to use the `Sys.getenv` function in any of your scripts, just like you normally would! 🎉 🔗 Check it out here: https://lnkd.in/e6pfJJGh This video is the second video in a six-video series I'm creating as my entry for Posit's 2024 #tablecontest. Over the next 2 weeks, I'll be posting all 6 videos and showing you step-by-step how I created my table/dashboard. Each video stands completely on its own and doesn't require you to watch all 6 videos (but if you do watch them all, you'll be able to completely reproduce my dashboard 🙂). Below are the videos, and the dates that each one will be added to the playlist: 1. 🌐 Publishing Quarto Dashboards for FREE using GitHub Actions and GitHub Pages: https://lnkd.in/ej-xicvS 2. 🔒 How to securely store passwords as environment variables using GitHub Actions: https://lnkd.in/eUWzk8sk 3. 🎵 How to access Spotify data using R (Friday, May 24th) 4. 🖼️ Embedding media in Quarto projects using iframes (Tuesday, May 28th) 5. 🖱️ Creating interactive Quarto dashboards with Observable JS, GitHub Actions, and GitHub Pages (Wednesday, May 29th) 6. 🎨 Creating and styling a gt table, plus some Quarto styling in general (Thursday, May 30th) If you want to make sure that you never miss a video of mine, you can subscribe to my YouTube channel here 😊: https://lnkd.in/eNpc5Bic

  • For folks scrambling to rotate CSP creds leaked in the actions attack…. Maybe don’t. This is treating the symptoms, not the “disease”. Instead replace your need for long lived credentials with identity federation. You can do this with all the major CSPs. If it’s GitHub PATs, this is why we created Octo STS (which is 100% free to use, and incredibly cheap to host your own instance of). Federation means you no longer have a long lived credential to leak because you trade a short lived GitHub credential for a short lived credential with your CSP. It really is like magic, and a security super power. It cures the “disease”, and you won’t have to treat the symptoms! The one gotcha I see is folks inadequately understanding a provider’s (eg github) claims and creating weak trust rules, so make sure you understand what workflows you are authorizing! However, mark my words: learning how to do federation right now WILL pay dividends.

  • GitHub Actions Exploitation via Dependabot. A new GitHub Actions exploit leverages Dependabot to compromise repositories and push arbitrary code. Note, that GitHub long ago acquired Dependabot, and it's likely not a typical GitHub App. The vulnerability affects repositories using GitHub Actions workflows with the pull_request_target trigger and insufficient PR author checks. The default behavior in Dependabot is similar to the default behavior in the Pull Request UI, where pull requests from forks target the upstream repo by default. This would run in the target repository with Dependabot's permissions, which has some elevated privileges. The attack involves forking a vulnerable repository, triggering Dependabot on the fork to create a PR, then opening a PR from that Dependabot branch to the original repository. Forcing Dependabot to push again to the PR changes the github.actor to 'dependabot[bot]', bypassing checks and allowing malicious code to be merged. This vulnerability was found in projects like Spring Security and tRPC. The multiple ways of obtaining user identity in GitHub Actions workflows can lead to security gaps. Tools like octoscan and following GitHub's documentation on choosing correct identity variables can help prevent this exploit. I'm skeptical of the effective/practical severity, but it's interesting how it was orchestrated to show possible attacks. If you're developing open source project on GitHub, you should require approval for all outside collaborators to run workflows. Repository maintainers should review their Dependabot and GitHub Actions configurations to ensure proper security controls. https://lnkd.in/gZpqSkdB

Explore categories