Cameron Yule

Linting GitHub Actions

I’ve recently started using GitHub Actions – e.g., this website is published automatically to GitHub Pages by an action. While they’re convenient, I’ve also read many critical articles, notably from a security perspective. A few recent examples:

There’s clearly sharp edges we need to be mindful of when working with actions, so in addition to reading these types of articles, I also looked for tooling which could help. This led me to configure actionlint and pinact for my projects which rely on actions.

  • actionlint is a static analysis tool for actions which runs basic security tests, such as flagging potential sources of untrusted input and hardcoded credentials.
  • pinact scans actions for dependencies declared using git tags (e.g., actions/cache@v3.3.1) and pins these to the commit hash (e.g., actions/cache@88522a…). This ensures the version of the action used is immutable, but does not apply to any transitive dependencies. GitHub are working on Immutable Actions to fix that, but it’s not yet available.

I use treefmt-nix to manage all formatting and linting, so could easily add actionlint and pinact to my treefmt configuration:

_: {
  programs = {
    actionlint = {
      enable = true;
    };
    pinact = {
      enable = true;
    }
  };
}

In addition to actionlint and pinact, I run an additional linter which validates the configuration of actions per repository. This ensures the only actions which can run are those created by GitHub or third parties which I’ve explicitly allowed.

Needless to say, these tools aren’t a panacea and care must be taken when working with GitHub Actions not to leak secrets, take mutable dependencies, or allow untrusted sources. But this feels like a good starting point for blunting some of the most painful sharp edges.

Tags: til, security, github, ci