Skip to content

Commit 8cdaf78

Browse files
committed
adding post on exporting action usage
1 parent d4ad852 commit 8cdaf78

File tree

6 files changed

+218
-5
lines changed

6 files changed

+218
-5
lines changed

β€Ž_posts/2025-08-21-github-actions-allow-list-as-code.mdβ€Ž

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,21 @@ This post explores how to implement a GitHub Actions allow list using configurat
2222

2323
I'm going to be using my [actions-allow-list-as-code](https://github.com/joshjohanning-org/actions-allow-list-as-code) repository as the example implementation. This is the same repository I use to manage my own GitHub Actions allow list, so you can see it in action! πŸš€
2424

25-
> If you're already sold on this idea and just want to get started, skip to the [TLDR / Getting Started](#tldr--getting-started) section below for the quick and dirty implementation details!
26-
{: .prompt-tip }
25+
> **Before implementing an allow list, you'll want to know what Actions your organization are using today!** Check out my follow-up post on [Three Ways to Export GitHub Actions Usage Reports](/posts/github-actions-export-actions-usage/).
26+
{: .prompt-info }
2727

2828
## Why Configuration as Code?
2929

30+
> If you're already sold on this idea and just want to get started, skip to the [TLDR / Getting Started](#tldr--getting-started) section below for the quick and dirty implementation details!
31+
{: .prompt-tip }
32+
3033
Before we talk about the benefits of this method, let's quickly review the GitHub Actions permission options (these can be defined at the enterprise, organization, or repository level):
3134

32-
> - Allow all actions and reusable workflows
35+
> - **"Allow all actions and reusable workflows"**
3336
> - *Increasingly less common for security-conscious organizations*
34-
> - Allow enterprise actions and reusable workflows
37+
> - **"Allow enterprise actions and reusable workflows"**
3538
> - *Not as common; don't allow any marketplace actions including GitHub's own actions*
36-
> - ⭐️ **Allow enterprise, and select non-enterprise, actions and reusable workflows**
39+
> - ⭐️ **"Allow enterprise, and select non-enterprise, actions and reusable workflows"**
3740
> - *This is becoming increasingly more common since organizations want to maintain better control over their third-party actions usage*
3841
3942
> As of [August 2025](https://github.blog/changelog/2025-08-15-github-actions-policy-now-supports-blocking-and-sha-pinning-actions/), there's a new setting below these to "Require actions to be pinned to a full-length commit SHA" which is the best practice to prevent against supply chain attacks.
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
---
2+
title: 'Three Ways to Export GitHub Actions Usage Reports for an Organization'
3+
author: Josh Johanning
4+
date: 2025-08-24 09:30:00 -0500
5+
description: 'Compare three methods for getting GitHub Actions usage data for organization governance: The Dependency Insights view in GitHub, @stoe/action-reporting-cli, and my custom SBOM script'
6+
categories: [GitHub, Actions]
7+
tags: [GitHub Actions, SBOM, gh cli]
8+
media_subpath: /assets/screenshots/2025-08-22-github-actions-export-actions-usage
9+
image:
10+
path: actions-usage-sbom-by-version-light.png
11+
width: 100%
12+
height: 100%
13+
alt: GitHub Actions usage reporting comparison
14+
---
15+
16+
## Overview
17+
18+
In my [previous post on GitHub Actions Allow Lists](/posts/github-actions-allow-list-as-code/), I discussed how to manage which Actions your organization can use through configuration as code. But before you implement an allow list, you might ask: **What Actions are my organization actually using?**
19+
20+
Whether you're building an allow list, conducting a security audit, hunting down deprecated versions, or just want to know what's actually running in your CI/CD pipelines, you need visibility into which GitHub Actions are being used across your repositories.
21+
22+
This post covers three different approaches for getting that data:
23+
24+
1. **[GitHub's Dependency Insights](#method-1-githubs-dependency-insights-view-only)** - Native viewing capabilities (but no export)
25+
2. **[@stoe/action-reporting-cli](#method-2-stoeaction-reporting-cli-full-featured-solution)** - Full-featured CLI tool with multiple export formats (csv, json, or markdown)
26+
3. **[My Custom Software Bill of Materials (SBOM) Script](#method-3-custom-sbom-script-my-lightweight-solution)** - Lightweight shell script for automated reporting on Actions usage with capabilities to resolve SHAs to tag versions (exports to csv or markdown)
27+
28+
> If you want to skip ahead, use the links above to jump to any of these methods.
29+
{: .prompt-tip }
30+
31+
## Why This Matters
32+
33+
Let's quickly recap why Actions usage reporting is important:
34+
35+
1. **Security & Compliance**: Know your third-party dependencies and assess potential security risks
36+
2. **Governance Planning**: Make informed decisions about which Actions to allow or restrict
37+
3. **Dependency Management**: Track Action versions and identify outdated or deprecated Actions (like `actions/upload-artifact` and `actions/download-artifact` versions earlier than `v4`)
38+
4. **Supply Chain Visibility**: Build a Software Bill of Materials (SBOM) for your CI/CD pipeline
39+
40+
## Three Methods for Getting Actions Usage Data
41+
42+
### Method 1: GitHub's Dependency Insights (View-Only)
43+
44+
GitHub's [Dependency Insights](https://docs.github.com/en/enterprise-cloud@latest/organizations/collaborating-with-groups-in-organizations/viewing-insights-for-dependencies-in-your-organization) feature provides visibility into dependencies used across your organization. You'll need to filter specifically for GitHub Actions to see only Actions usage:
45+
46+
![Dependency Insights screenshot showing Actions usage](dependency-insights-light.png){: .light }
47+
![Dependency Insights screenshot showing Actions usage](dependency-insights-dark.png){: .dark }
48+
*GitHub's native Dependency Insights showing Actions usage across an organization*
49+
50+
While this view provides excellent visibility, it has limitations:
51+
52+
- **No export functionality**: You can view the data but not export it for further analysis
53+
- **Limited filtering**: Basic filtering options compared to programmatic approaches
54+
- **No historical data**: Shows current state but lacks trend analysis
55+
56+
That's where the automated tools come in handy - they give you more control and can export data for deeper analysis.
57+
58+
### Method 2: @stoe/action-reporting-cli (Full-Featured Solution)
59+
60+
The [`@stoe/action-reporting-cli`](https://github.com/stoe/action-reporting-cli) tool by Stefan StΓΆlzle provides comprehensive GitHub Actions reporting capabilities.
61+
62+
> See my [automated workflow implementation](https://github.com/joshjohanning-org/export-actions-usage-report/blob/main/.github/workflows/action-usage.yml) that runs this tool on a schedule and save the outputs back to the repository.
63+
{: .prompt-tip }
64+
65+
**Key features:**
66+
67+
- **Multiple export formats**: CSV, JSON, and Markdown outputs
68+
- **Comprehensive data collection**: workflows, permissions, secrets, variables, runner environments
69+
- **Flexible scope options**: enterprise, organization, or repository-level analysis
70+
- **Advanced filtering**: exclude GitHub-created actions, unique actions reporting
71+
72+
**Sample output**:
73+
74+
> owner | repo | name | workflow | state | created_at | updated_at | last_run_at | uses
75+
> --- | --- | --- | --- | --- | --- | --- | --- | ---
76+
> joshjohanning-org | .github | | [.github/workflows/update-organization-readme-badges.yml](https://github.com/joshjohanning-org/.github/blob/HEAD/.github/workflows/update-organization-readme-badges.yml) | active | 2024-05-23T16:58:49.000Z | 2024-05-23T16:58:49.000Z | 2025-08-17T07:07:40.000Z | <ul><li>[actions/checkout](https://github.com/actions/checkout) <code>v4</code></li><li>[actions/create-github-app-token](https://github.com/actions/create-github-app-token) <code>v2</code></li><li>[joshjohanning/organization-readme-badge-generator](https://github.com/joshjohanning/organization-readme-badge-generator) <code>v1</code></li></ul>
77+
> joshjohanning-org | issueops-samples | | [.github/workflows/delete-repos-delete.yml](https://github.com/joshjohanning-org/issueops-samples/blob/HEAD/.github/workflows/delete-repos-delete.yml) | active | 2023-11-08T16:05:40.000Z | 2025-04-02T15:48:27.000Z | 2025-08-13T14:57:36.000Z | <ul><li>[actions/checkout](https://github.com/actions/checkout) <code>v5</code></li><li>[issue-ops/parser](https://github.com/issue-ops/parser) <code>76d5aa095754de1493cbe41934484c4287e16350</code></li><li>[actions/create-github-app-token](https://github.com/actions/create-github-app-token) <code>v2</code></li><li>[actions/github-script](https://github.com/actions/github-script) <code>v7</code></li><li>[joshjohanning/approveops](https://github.com/joshjohanning/approveops) <code>caad905b2ba78301a0db7f484ef6fe3c770e6985</code></li></ul>
78+
>
79+
> ```md
80+
> owner | repo | name | workflow | state | created_at | updated_at | last_run_at | uses
81+
> --- | --- | --- | --- | --- | --- | --- | --- | ---
82+
> joshjohanning-org | .github | | [.github/workflows/update-organization-readme-badges.yml](https://github.com/joshjohanning-org/.github/blob/HEAD/.github/workflows/update-organization-readme-badges.yml) | active | 2024-05-23T16:58:49.000Z | 2024-05-23T16:58:49.000Z | 2025-08-17T07:07:40.000Z | <ul><li>[actions/checkout](https://github.com/actions/checkout) <code>v4</code></li><li>[actions/create-github-app-token](https://github.com/actions/create-github-app-token) <code>v2</code></li><li>[joshjohanning/organization-readme-badge-generator](https://github.com/joshjohanning/organization-readme-badge-generator) <code>v1</code></li></ul>
83+
> joshjohanning-org | issueops-samples | | [.github/workflows/delete-repos-delete.yml](https://github.com/joshjohanning-org/issueops-samples/blob/HEAD/.github/workflows/delete-repos-delete.yml) | active | 2023-11-08T16:05:40.000Z | 2025-04-02T15:48:27.000Z | 2025-08-13T14:57:36.000Z | <ul><li>[actions/checkout](https://github.com/actions/checkout) <code>v5</code></li><li>[issue-ops/parser](https://github.com/issue-ops/parser) <code>76d5aa095754de1493cbe41934484c4287e16350</code></li><li>[actions/create-github-app-token](https://github.com/actions/create-github-app-token) <code>v2</code></li><li>[actions/github-script](https://github.com/actions/github-script) <code>v7</code></li><li>[joshjohanning/approveops](https://github.com/joshjohanning/approveops) <code>caad905b2ba78301a0db7f484ef6fe3c770e6985</code></li></ul>
84+
> ```
85+
> {: file='actions-output.md'}
86+
87+
> *Full example output - `@stoe/action-reporting-cli`: [`json`](https://github.com/joshjohanning-org/export-actions-usage-report/blob/main/actions-output.json), [`md`](https://github.com/joshjohanning-org/export-actions-usage-report/blob/main/actions-output.md), [`csv`](https://github.com/joshjohanning-org/export-actions-usage-report/blob/main/actions-output.csv)*
88+
{: .prompt-info }
89+
90+
**Sample Usage:**
91+
92+
```bash
93+
# Organization-wide analysis with all data types
94+
npx @stoe/action-reporting-cli
95+
--owner my-org
96+
--all
97+
--exclude
98+
--unique both
99+
--csv ./reports/actions.csv
100+
--json ./reports/actions.json
101+
--md ./reports/actions.md
102+
```
103+
104+
### Method 3: Custom SBOM Script (My Lightweight Solution)
105+
106+
The approach I've developed focuses on SBOM-style reporting with automated GitHub workflows. The [script](https://github.com/joshjohanning/github-misc-scripts/blob/main/gh-cli/get-actions-usage-in-organization.sh) is located in my [`github-misc-scripts` repository](https://github.com/joshjohanning/github-misc-scripts).
107+
108+
> See my [automated workflow implementation](https://github.com/joshjohanning-org/export-actions-usage-report/blob/main/.github/workflows/action-usage-sbom.yml) that runs this tool on a schedule and save the outputs back to the repository.
109+
{: .prompt-tip }
110+
111+
**Key features:**
112+
113+
What makes this script useful:
114+
115+
- **Usage frequency counts**: Shows how many times each Action is used across the organization
116+
- **Version distribution**: Identifies which versions of Actions are most commonly used
117+
- **SHA resolution**: Automatically resolves commit SHAs to readable tag versions when possible
118+
119+
**Sample Output - Count by Action:**
120+
121+
> | Count | Action |
122+
> | --- | --- |
123+
> | 121 | actions/checkout |
124+
> | 28 | actions/upload-artifact |
125+
> | 10 | github/codeql-action/upload-sarif |
126+
> | 4 | joshjohanning/approveops |
127+
>
128+
> ```markdown
129+
> | Count | Action |
130+
> | --- | --- |
131+
> | 121 | actions/checkout |
132+
> | 28 | actions/upload-artifact |
133+
> | 10 | github/codeql-action/upload-sarif |
134+
> | 4 | joshjohanning/approveops |
135+
> ```
136+
> {: file='count-by-action-sbom.md'}
137+
138+
> [*Full example output - SBOM Count by Action*](https://github.com/joshjohanning-org/export-actions-usage-report/blob/main/count-by-action-sbom.md)
139+
{: .prompt-info }
140+
141+
**Sample Output - Count by Version:**
142+
143+
> | Count | Action |
144+
> | --- | --- |
145+
> | 57 | actions/checkout@v3 |
146+
> | 54 | actions/checkout@v4 |
147+
> | 11 | actions/upload-artifact@v4 |
148+
> | 3 | github/codeql-action/upload-sarif@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # sha not associated to tag |
149+
> | 2 | joshjohanning/approveops@caad905b2ba78301a0db7f484ef6fe3c770e6985 # v2.0.3 |
150+
>
151+
> ```markdown
152+
> | Count | Action |
153+
> | --- | --- |
154+
> | 57 | actions/checkout@v3 |
155+
> | 54 | actions/checkout@v4 |
156+
> | 11 | actions/upload-artifact@v4 |
157+
> | 3 | github/codeql-action/upload-sarif@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # sha not associated to tag |
158+
> | 2 | joshjohanning/approveops@caad905b2ba78301a0db7f484ef6fe3c770e6985 # v2.0.3 |
159+
> ```
160+
> {: file='count-by-version-sbom.md'}
161+
162+
> [*Full example output - SBOM Count by Version*](https://github.com/joshjohanning-org/export-actions-usage-report/blob/main/count-by-version-sbom.md)
163+
{: .prompt-info }
164+
165+
**Sample Usage:**
166+
167+
```sh
168+
# different options
169+
./get-actions-usage-in-organization.sh joshjohanning-org count-by-version csv > output.csv
170+
./get-actions-usage-in-organization.sh joshjohanning-org count-by-action md > output.md
171+
./get-actions-usage-in-organization.sh joshjohanning-org count-by-version md --resolve-shas > output.md
172+
./get-actions-usage-in-organization.sh joshjohanning-org count-by-action md --dedupe-by-repo > output.md
173+
```
174+
175+
> **Need single repository analysis?** I also have a [repository-level version of this script](https://github.com/joshjohanning/github-misc-scripts/blob/main/gh-cli/get-actions-usage-in-repository.sh) that works the same way but analyzes just one repository instead of an entire organization.
176+
{: .prompt-tip }
177+
178+
## Choosing the Right Method
179+
180+
- [**Use GitHub Dependency Insights**](#method-1-githubs-dependency-insights-view-only) first to get familiar with your organization's usage patterns
181+
- [**Use @stoe/action-reporting-cli**](#method-2-stoeaction-reporting-cli-full-featured-solution) for comprehensive analysis with flexible export options, and especially if you want to report on other things like secrets, variables, or permissions (see: [Using the Pre-Built Workflows](#using-the-pre-built-workflows) section)
182+
- [**Use my custom SBOM script**](#method-3-custom-sbom-script-my-lightweight-solution) if you want usage statistics and the ability to resolve SHAs to tag versions (see: [Using the Pre-Built Workflows](#using-the-pre-built-workflows) section)
183+
184+
## Using the Pre-Built Workflows
185+
186+
To implement these solutions in your organization:
187+
188+
1. **Fork or copy** the [export-actions-usage-report](https://github.com/joshjohanning-org/export-actions-usage-report) repository
189+
- If you fork it, make sure to enable Actions for the forked repository to allow the scheduled job to run
190+
2. **Set up GitHub App authentication**:
191+
- Create a GitHub App with Organization Administration permissions (Read & Write)
192+
- Add the App ID as a repository variable (`APP_ID`)
193+
- Add the private key as a repository secret (`PRIVATE_KEY`)
194+
- See my [post on GitHub Apps](/posts/github-apps/) for detailed instructions on creating and configuring a GitHub App
195+
3. **Customize the workflows** if needed (different schedule, additional output formats, etc.)
196+
197+
The workflows will automatically:
198+
199+
- Run on a weekly schedule (or manually triggered)
200+
- Generate usage reports using both [`@stoe/action-reporting-cli`](https://github.com/stoe/action-reporting-cli) and [my custom SBOM script](https://github.com/joshjohanning/github-misc-scripts/blob/main/gh-cli/get-actions-usage-in-organization.sh)
201+
- Commits results back to the repository to be able to track changes over time
202+
- Additionally, pushes results as [workflow job summaries](/posts/github-code-coverage/#adding-code-coverage-to-job-summary)
203+
204+
## Summary
205+
206+
Having visibility into your organization's GitHub Actions usage is essential for security, managing dependencies, and making informed decisions about your CI/CD pipelines. While GitHub's native Dependency Insights provide a good starting point, automated export solutions offer the flexibility and depth needed for comprehensive and historical analysis.
207+
208+
Whether you're implementing an Actions allow list, conducting security audits, or just wanting better visibility into your CI/CD dependencies, these tools provide the foundation for data-driven decision making.
209+
210+
πŸš€ Ready to get started? Check out the [export-actions-usage-report repository](https://github.com/joshjohanning-org/export-actions-usage-report) and start building your Actions usage reporting today!
225 KB
Loading
225 KB
Loading
340 KB
Loading
370 KB
Loading

0 commit comments

Comments
Β (0)