Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 15 additions & 32 deletions .github/workflows/ci-docker.yml
Original file line number Diff line number Diff line change
@@ -1,37 +1,20 @@
name: Docker CI
# Generated automatically by org-governance-bot. Do not edit manually.
name: "Docker CI"

on:
pull_request:
branches: ['main']
paths: ['Dockerfile','cmd/**','docs/**','internal/**','go.*','.github/workflows/ci-docker.yml']

env:
REGISTRY: ghcr.io
IMAGE_NAME: '${{ github.repository }}'

permissions:
contents: read
branches:
- main
paths:
- Dockerfile
- cmd/**
- docs/**
- internal/**
- go.*
- .github/workflows/ci-docker.yml

jobs:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 https://github.com/actions/checkout/releases/tag/v6.0.3
with:
fetch-depth: '0'
- name: qemu
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4 https://github.com/docker/setup-qemu-action/releases/tag/v4
- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4 https://github.com/docker/setup-buildx-action/releases/tag/v4
- id: meta
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6 https://github.com/docker/metadata-action/releases/tag/v6
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: build
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7 https://github.com/docker/build-push-action/releases/tag/v7
with:
context: .
push: false
### TODO: test multiple platforms
# platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
orchestrate:
uses: blinklabs-io/actions/.github/workflows/reuseable-ci-docker.yml@main

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

git ls-files .github/workflows/ | head -20

Repository: blinklabs-io/tx-submit-api-mirror

Length of output: 428


🏁 Script executed:

cat -n .github/workflows/ci-docker.yml

Repository: blinklabs-io/tx-submit-api-mirror

Length of output: 744


🏁 Script executed:

rg "uses:.*`@main`" .github/workflows/

Repository: blinklabs-io/tx-submit-api-mirror

Length of output: 1009


🏁 Script executed:

rg "uses:.*@" .github/workflows/ | head -20

Repository: blinklabs-io/tx-submit-api-mirror

Length of output: 1009


Fix all unpinned reusable workflow references at source.

This file is auto-generated by org-governance-bot and cannot be manually edited. Additionally, this unpinned @main reference is a systemic issue—all seven workflows in .github/workflows/ use the same mutable reference pattern to blinklabs-io/actions.

The fix must be applied upstream in the org-governance-bot configuration or the template it uses to ensure all generated workflows pin to immutable commit SHAs instead of @main.

🧰 Tools
🪛 zizmor (1.26.1)

[error] 18-18: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci-docker.yml at line 18, The workflow reference in the
`uses` statement for
`blinklabs-io/actions/.github/workflows/reuseable-ci-docker.yml` is pinned to
`@main` which is a mutable reference instead of an immutable commit SHA. Since
this file is auto-generated by org-governance-bot and cannot be manually edited,
the fix must be applied upstream. Locate the org-governance-bot configuration or
template file that generates these CI workflows and update the reference pattern
to pin to a specific commit SHA instead of `@main` to ensure all seven generated
workflows in `.github/workflows/` use immutable references going forward.

Source: Linters/SAST tools

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Docker CI caller workflow removed explicit least-privilege permissions; the reusable job now inherits the repository default GITHUB_TOKEN scope, which may be broader than the previous contents: read and violates least-privilege.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/ci-docker.yml, line 18:

<comment>Docker CI caller workflow removed explicit least-privilege permissions; the reusable job now inherits the repository default GITHUB_TOKEN scope, which may be broader than the previous `contents: read` and violates least-privilege.</comment>

<file context>
@@ -1,37 +1,20 @@
-          tags: ${{ steps.meta.outputs.tags }}
-          labels: ${{ steps.meta.outputs.labels }}
+  orchestrate:
+    uses: blinklabs-io/actions/.github/workflows/reuseable-ci-docker.yml@main
+    with:
+      image-name: blinklabs-io/tx-submit-api-mirror
</file context>
Suggested change
uses: blinklabs-io/actions/.github/workflows/reuseable-ci-docker.yml@main
+ permissions:
+ contents: read
+ uses: blinklabs-io/actions/.github/workflows/reuseable-ci-docker.yml@main

with:
image-name: blinklabs-io/tx-submit-api-mirror

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {}
Comment on lines +18 to +20
16 changes: 4 additions & 12 deletions .github/workflows/conventional-commits.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
# The below is pulled from upstream and slightly modified
# https://github.com/webiny/action-conventional-commits/blob/master/README.md#usage

name: Conventional Commits
# Generated automatically by org-governance-bot. Do not edit manually.
name: "Conventional Commits"

on:
pull_request:

jobs:
build:
name: Conventional Commits
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 https://github.com/actions/checkout/releases/tag/v6.0.3
- uses: webiny/action-conventional-commits@7f91b1595ca1951cdb671ddc9f07a49081ec5b69 # v1.4.2 https://github.com/webiny/action-conventional-commits/releases/tag/v1.4.2
orchestrate:
uses: blinklabs-io/actions/.github/workflows/reuseable-conventional-commits.yml@main

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if the file exists and examine its contents
if [ -f ".github/workflows/conventional-commits.yml" ]; then
  echo "=== File content ==="
  cat -n ".github/workflows/conventional-commits.yml"
else
  echo "File not found. Searching for it..."
  find . -name "conventional-commits.yml" 2>/dev/null
fi

Repository: blinklabs-io/tx-submit-api-mirror

Length of output: 487


🏁 Script executed:

#!/bin/bash
# List all workflow files to understand the repository context
find .github/workflows -type f -name "*.yml" -o -name "*.yaml" 2>/dev/null | head -20

Repository: blinklabs-io/tx-submit-api-mirror

Length of output: 428


🏁 Script executed:

#!/bin/bash
# Check the remote repository that is being used in the workflow
# Look for any references to blinklabs-io/actions in all workflow files
rg "blinklabs-io/actions" .github/workflows/ -A 2 -B 2

Repository: blinklabs-io/tx-submit-api-mirror

Length of output: 2374


Pin reusable workflow refs to immutable SHAs.

This call uses @main, which is mutable and bypasses change control. However, this file is auto-generated by org-governance-bot (see line 1), so the fix must be applied to the governance bot's configuration rather than this file directly. Update the bot configuration to pin blinklabs-io/actions workflows to specific commit SHAs instead of @main.

🧰 Tools
🪛 zizmor (1.26.1)

[error] 9-9: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/conventional-commits.yml at line 9, The workflow reference
in this file uses `@main` which is mutable and bypasses change control. Since this
file is auto-generated by org-governance-bot (as noted in line 1), the fix
cannot be applied directly to this file. Instead, update the
org-governance-bot's configuration to pin the blinklabs-io/actions workflow
reference to a specific immutable commit SHA instead of using `@main` when it
generates the conventional-commits workflow file.

Source: Linters/SAST tools

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Explicit permissions: contents: read was removed from the orchestrate job when migrating to the reusable workflow. This causes the caller job to inherit the repository's default GITHUB_TOKEN permissions, which may be broader than the previous least-privilege restriction and creates potential privilege drift.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/conventional-commits.yml, line 9:

<comment>Explicit `permissions: contents: read` was removed from the `orchestrate` job when migrating to the reusable workflow. This causes the caller job to inherit the repository's default `GITHUB_TOKEN` permissions, which may be broader than the previous least-privilege restriction and creates potential privilege drift.</comment>

<file context>
@@ -1,17 +1,9 @@
-      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 https://github.com/actions/checkout/releases/tag/v6.0.3
-      - uses: webiny/action-conventional-commits@7f91b1595ca1951cdb671ddc9f07a49081ec5b69 # v1.4.2 https://github.com/webiny/action-conventional-commits/releases/tag/v1.4.2
+  orchestrate:
+    uses: blinklabs-io/actions/.github/workflows/reuseable-conventional-commits.yml@main
</file context>

25 changes: 8 additions & 17 deletions .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
name: golangci-lint
# Generated automatically by org-governance-bot. Do not edit manually.
name: "golangci-lint"

on:
pull_request:
push:
tags:
- v*
branches:
- main
pull_request:

permissions:
contents: read
tags:
- v*

jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 https://github.com/actions/checkout/releases/tag/v6.0.3
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 https://github.com/actions/setup-go/releases/tag/v6.4.0
with:
go-version: 1.25.x
- name: golangci-lint
uses: golangci/golangci-lint-action@82606bf257cbaff209d206a39f5134f0cfbfd2ee # v9.2.1 https://github.com/golangci/golangci-lint-action/releases/tag/v9.2.1
orchestrate:
uses: blinklabs-io/actions/.github/workflows/reuseable-golangci-lint.yml@main

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's check if the file exists and view its contents
find . -name "golangci-lint.yml" -type f 2>/dev/null | head -20

Repository: blinklabs-io/tx-submit-api-mirror

Length of output: 209


🏁 Script executed:

# If found, let's examine the file around line 14
if [ -f ".github/workflows/golangci-lint.yml" ]; then
  cat -n ".github/workflows/golangci-lint.yml" | head -20
fi

Repository: blinklabs-io/tx-submit-api-mirror

Length of output: 543


🏁 Script executed:

# Also check for any other workflow files that might use unpinned references
fd -e yml -e yaml ".github/workflows" 2>/dev/null | xargs grep -l "uses:.*`@main`\|uses:.*`@master`\|uses:.*@\(head\|trunk\)" 2>/dev/null || echo "No dynamic refs found or files not accessible"

Repository: blinklabs-io/tx-submit-api-mirror

Length of output: 217


Pin reusable workflow ref to immutable SHA.

The uses target at @main is mutable and introduces supply chain risk. Pin to a commit digest instead.

Suggested fix
-    uses: blinklabs-io/actions/.github/workflows/reuseable-golangci-lint.yml@main
+    uses: blinklabs-io/actions/.github/workflows/reuseable-golangci-lint.yml@<commit-sha>
🧰 Tools
🪛 zizmor (1.26.1)

[error] 14-14: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/golangci-lint.yml at line 14, The `uses` clause
referencing blinklabs-io/actions/.github/workflows/reuseable-golangci-lint.yml
is using a mutable branch reference (`@main`) which introduces supply chain risk.
Replace the `@main` reference with a specific immutable commit SHA to pin the
reusable workflow to a fixed version. This ensures the workflow definition
cannot unexpectedly change when the main branch is updated.

Source: Linters/SAST tools

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Reusable workflow is referenced via the mutable @main branch instead of a pinned commit SHA or trusted version tag, which removes build determinism and increases supply-chain risk.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/golangci-lint.yml, line 14:

<comment>Reusable workflow is referenced via the mutable `@main` branch instead of a pinned commit SHA or trusted version tag, which removes build determinism and increases supply-chain risk.</comment>

<file context>
@@ -1,23 +1,14 @@
-      - name: golangci-lint
-        uses: golangci/golangci-lint-action@82606bf257cbaff209d206a39f5134f0cfbfd2ee # v9.2.1 https://github.com/golangci/golangci-lint-action/releases/tag/v9.2.1
+  orchestrate:
+    uses: blinklabs-io/actions/.github/workflows/reuseable-golangci-lint.yml@main
</file context>

Comment on lines +13 to +14

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The caller workflow removed the explicit least-privilege permissions: contents: read block. Without a permissions envelope, the GITHUB_TOKEN scope depends on repository/org default settings and may be wider than the previous setup. Add explicit permissions to the caller job (or workflow) to restore least-privilege constraints.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/golangci-lint.yml, line 13:

<comment>The caller workflow removed the explicit least-privilege `permissions: contents: read` block. Without a permissions envelope, the GITHUB_TOKEN scope depends on repository/org default settings and may be wider than the previous setup. Add explicit permissions to the caller job (or workflow) to restore least-privilege constraints.</comment>

<file context>
@@ -1,23 +1,14 @@
-          go-version: 1.25.x
-      - name: golangci-lint
-        uses: golangci/golangci-lint-action@82606bf257cbaff209d206a39f5134f0cfbfd2ee # v9.2.1 https://github.com/golangci/golangci-lint-action/releases/tag/v9.2.1
+  orchestrate:
+    uses: blinklabs-io/actions/.github/workflows/reuseable-golangci-lint.yml@main
</file context>
Suggested change
orchestrate:
uses: blinklabs-io/actions/.github/workflows/reuseable-golangci-lint.yml@main
orchestrate:
permissions:
contents: read
uses: blinklabs-io/actions/.github/workflows/reuseable-golangci-lint.yml@main

29 changes: 10 additions & 19 deletions .github/workflows/nilaway.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,16 @@
name: nilaway
# Generated automatically by org-governance-bot. Do not edit manually.
name: "nilaway"

on:
pull_request:
push:
tags:
- v*
branches:
- main
pull_request:

permissions:
contents: read
tags:
- v*

jobs:
nilaway:
name: nilaway
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 https://github.com/actions/checkout/releases/tag/v6.0.3
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 https://github.com/actions/setup-go/releases/tag/v6.4.0
with:
go-version: 1.25.x
- name: install nilaway
run: go install go.uber.org/nilaway/cmd/nilaway@latest
- name: run nilaway
run: nilaway ./...
orchestrate:
uses: blinklabs-io/actions/.github/workflows/reuseable-nilaway.yml@main

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check if the file exists and examine the workflow
cat -n .github/workflows/nilaway.yml

Repository: blinklabs-io/tx-submit-api-mirror

Length of output: 620


🌐 Web query:

GitHub Actions security best practices pinning reusable workflow SHA

💡 Result:

Best practice: pin reusable workflow references to a full-length commit SHA (not a branch or tag) in the caller workflow’s uses: line, and enforce this with GitHub’s “allowed actions and reusable workflows” policy where available. 1) Pin reusable workflows to full commit SHA in the caller - GitHub’s documentation states that if you use a commit SHA when referencing a reusable workflow, you ensure everyone always uses the same YAML code, whereas referencing by tag/branch requires trust in that version. [1] - GitHub’s “secure use” guidance likewise says pinning to a full-length commit SHA is the only way to use an action as an immutable release, and that the same principles apply to reusable workflows. [2] Example (caller workflow): - uses: OWNER/REPO/.github/workflows/workflow.yml@<FULL_SHA> 2) Enforce SHA pinning at the org/policy level - GitHub introduced policy support to enforce SHA pinning via the “allowed actions and reusable workflows” policy; workflows that attempt to use an action/reusable workflow that isn’t pinned to a full commit SHA can fail when the policy is enabled. [3] - GitHub’s enterprise enforcement documentation also notes the option “Require actions to be pinned to a full-length commit SHA”, and documents the different @TAG-OR-SHA selection syntax for reusable workflows: OWNER/REPOSITORY/PATH/FILENAME@TAG-OR-SHA. [4] 3) Understand why this matters (security model) - Because reusable workflows are referenced by the caller’s uses: line, mutable refs (tags/branches) can shift what code runs. GitHub explains that using a commit SHA ensures the called workflow’s code is stable, while tags/branches require trust. [1] If you want, tell me whether you’re on GitHub.com vs GitHub Enterprise Cloud/Server and whether you manage policies at the org or repo level—I can tailor a concrete rollout checklist for enabling the SHA-pinning policy and how to format reusable-workflow uses: pins accordingly.

Citations:


Pin reusable workflow refs to immutable SHAs.

@main should be replaced with an immutable commit SHA to avoid unreviewed upstream drift.

Suggested fix
-    uses: blinklabs-io/actions/.github/workflows/reuseable-nilaway.yml@main
+    uses: blinklabs-io/actions/.github/workflows/reuseable-nilaway.yml@<commit-sha>
🧰 Tools
🪛 zizmor (1.26.1)

[error] 14-14: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/nilaway.yml at line 14, The reusable workflow reference in
the nilaway.yml workflow file uses the `@main` branch reference instead of
pinning to an immutable commit SHA. Replace the `@main` reference in the `uses:
blinklabs-io/actions/.github/workflows/reuseable-nilaway.yml@main` line with a
specific commit SHA to ensure that only reviewed and tested versions of the
upstream workflow are executed, preventing unintended drift from upstream
changes.

Source: Linters/SAST tools

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Reusable nilaway workflow is referenced with a mutable @main branch instead of an immutable commit SHA, introducing supply-chain and reproducibility risk.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/nilaway.yml, line 14:

<comment>Reusable nilaway workflow is referenced with a mutable `@main` branch instead of an immutable commit SHA, introducing supply-chain and reproducibility risk.</comment>

<file context>
@@ -1,25 +1,16 @@
-      - name: run nilaway
-        run: nilaway ./...
+  orchestrate:
+    uses: blinklabs-io/actions/.github/workflows/reuseable-nilaway.yml@main
+    with:
+      include-pkgs: github.com/blinklabs-io/tx-submit-api-mirror
</file context>

with:
include-pkgs: github.com/blinklabs-io/tx-submit-api-mirror

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {}
Comment on lines +14 to +16
194 changes: 21 additions & 173 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,180 +1,28 @@
name: publish
# Generated automatically by org-governance-bot. Do not edit manually.
name: "publish"

on:
push:
branches: ['main']
branches:
- main
tags:
- 'v*.*.*'
- v*.*.*

concurrency: ${{ github.ref }}
permissions:
actions: write

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: These top-level permissions grant broad write access (actions, checks, packages, statuses) that may not be required by the called reusable workflow. Following the principle of least privilege, reduce these to only the scopes the reusable workflow actually needs (likely attestations: write, contents: write, id-token: write, and packages: write for a publish workflow).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/publish.yml, line 12:

<comment>These top-level permissions grant broad write access (`actions`, `checks`, `packages`, `statuses`) that may not be required by the called reusable workflow. Following the principle of least privilege, reduce these to only the scopes the reusable workflow actually needs (likely `attestations: write`, `contents: write`, `id-token: write`, and `packages: write` for a publish workflow).</comment>

<file context>
@@ -1,180 +1,28 @@
 
-concurrency: ${{ github.ref }}
+permissions:
+  actions: write
+  attestations: write
+  checks: write
</file context>

attestations: write
checks: write
contents: write
id-token: write
packages: write
statuses: write
Comment on lines +11 to +18

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's read the publish.yml file to understand its full context
cat -n .github/workflows/publish.yml

Repository: blinklabs-io/tx-submit-api-mirror

Length of output: 981


🏁 Script executed:

# The workflow calls blinklabs-io/actions/.github/workflows/reuseable-publish.yml@main
# Let's try to fetch this external workflow to understand what permissions it needs
curl -s https://raw.githubusercontent.com/blinklabs-io/actions/main/.github/workflows/reuseable-publish.yml

Repository: blinklabs-io/tx-submit-api-mirror

Length of output: 8068


Reduce top-level token scopes to least privilege.

The workflow grants multiple write scopes (actions, checks, packages, statuses) that are not used by the called workflow and represent unnecessary blast radius.

Suggested tightening (adjust to exact needs of the called workflow)
 permissions:
-  actions: write
   attestations: write
-  checks: write
   contents: write
   id-token: write
-  packages: write
-  statuses: write
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
permissions:
actions: write
attestations: write
checks: write
contents: write
id-token: write
packages: write
statuses: write
permissions:
attestations: write
contents: write
id-token: write
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/publish.yml around lines 11 - 18, The permissions block in
the publish workflow is granting write access to multiple scopes that are not
required by the workflow, which violates the principle of least privilege and
increases the security blast radius. Remove the unused write permission scopes
for actions, checks, packages, and statuses from the permissions block, keeping
only the scopes that are actually needed by the workflow (such as attestations,
contents, and id-token). Verify that the remaining permissions are sufficient
for the workflow's actual operations.


jobs:
create-draft-release:
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
RELEASE_ID: ${{ steps.create-release.outputs.result }}
steps:
- run: "echo \"RELEASE_TAG=${GITHUB_REF#refs/tags/}\" >> $GITHUB_ENV"
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 https://github.com/actions/github-script/releases/tag/v9
id: create-release
if: startsWith(github.ref, 'refs/tags/')
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
result-encoding: string
script: |
try {
const response = await github.rest.repos.createRelease({
draft: true,
generate_release_notes: true,
name: process.env.RELEASE_TAG,
owner: context.repo.owner,
prerelease: false,
repo: context.repo.repo,
tag_name: process.env.RELEASE_TAG,
});

return response.data.id;
} catch (error) {
core.setFailed(error.message);
}

build-binaries:
strategy:
matrix:
os: [linux, darwin, freebsd, windows]
arch: [amd64, arm64]
runs-on: ubuntu-latest
needs: [create-draft-release]
permissions:
actions: write
attestations: write
checks: write
contents: write
id-token: write
packages: write
statuses: write
steps:
- run: "echo \"RELEASE_TAG=${GITHUB_REF#refs/tags/}\" >> $GITHUB_ENV"
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 https://github.com/actions/checkout/releases/tag/v6.0.3
with:
fetch-depth: '0'
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 https://github.com/actions/setup-go/releases/tag/v6
with:
go-version: 1.25.x
- name: Build binary
run: GOOS=${{ matrix.os }} GOARCH=${{ matrix.arch }} make build
- name: Upload release asset
if: startsWith(github.ref, 'refs/tags/')
run: |
_filename=tx-submit-api-mirror-${{ env.RELEASE_TAG }}-${{ matrix.os }}-${{ matrix.arch }}
if [[ ${{ matrix.os }} == windows ]]; then
_filename=${_filename}.exe
fi
cp tx-submit-api-mirror ${_filename}
curl \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Content-Type: application/octet-stream" \
--data-binary @${_filename} \
https://uploads.github.com/repos/${{ github.repository_owner }}/tx-submit-api-mirror/releases/${{ needs.create-draft-release.outputs.RELEASE_ID }}/assets?name=${_filename}
- name: Attest binary
uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0 https://github.com/actions/attest/releases/tag/v4.1.0
with:
subject-path: 'tx-submit-api-mirror'

build-images:
runs-on: ubuntu-latest
needs: [create-draft-release]
permissions:
actions: write
attestations: write
checks: write
contents: write
id-token: write
packages: write
statuses: write
steps:
- run: "echo \"RELEASE_TAG=${GITHUB_REF#refs/tags/}\" >> $GITHUB_ENV"
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 https://github.com/actions/checkout/releases/tag/v6.0.3
with:
fetch-depth: '0'
- name: Set up QEMU
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4 https://github.com/docker/setup-qemu-action/releases/tag/v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4 https://github.com/docker/setup-buildx-action/releases/tag/v4
- name: Login to Docker Hub
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4 https://github.com/docker/login-action/releases/tag/v4
with:
username: blinklabs
password: ${{ secrets.DOCKER_PASSWORD }} # uses token
- name: Login to GHCR
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4 https://github.com/docker/login-action/releases/tag/v4
with:
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
registry: ghcr.io
- id: meta
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6 https://github.com/docker/metadata-action/releases/tag/v6
with:
images: |
blinklabs/tx-submit-api-mirror
ghcr.io/${{ github.repository }}
tags: |
# Only version, no revision
type=match,pattern=v(.*)-(.*),group=1
# branch
type=ref,event=branch
# semver
type=semver,pattern={{version}}
- name: Build images
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7 https://github.com/docker/build-push-action/releases/tag/v7
id: push
with:
outputs: "type=registry,push=true"
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Attest Docker Hub image
uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0 https://github.com/actions/attest/releases/tag/v4.1.0
with:
subject-name: index.docker.io/blinklabs/tx-submit-api-mirror
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
- name: Attest GHCR image
uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0 https://github.com/actions/attest/releases/tag/v4.1.0
with:
subject-name: ghcr.io/${{ github.repository }}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
# Update Docker Hub from README
- name: Docker Hub Description
uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5 https://github.com/peter-evans/dockerhub-description/releases/tag/v5
with:
username: blinklabs
password: ${{ secrets.DOCKER_PASSWORD }}
repository: blinklabs/tx-submit-api-mirror
readme-filepath: ./README.md
short-description: "A Cardano Submit API mirror service"

finalize-release:
runs-on: ubuntu-latest
permissions:
contents: write
needs: [create-draft-release, build-binaries, build-images]
steps:
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 https://github.com/actions/github-script/releases/tag/v9
if: startsWith(github.ref, 'refs/tags/')
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
try {
await github.rest.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: ${{ needs.create-draft-release.outputs.RELEASE_ID }},
draft: false,
});
} catch (error) {
core.setFailed(error.message);
}
orchestrate:
uses: blinklabs-io/actions/.github/workflows/reuseable-publish.yml@main

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Check if the file exists and read the relevant section
cat -n .github/workflows/publish.yml | head -30

Repository: blinklabs-io/tx-submit-api-mirror

Length of output: 981


🌐 Web query:

GitHub Actions reusable workflow security best practices pinning SHA commit

💡 Result:

Pinning reusable workflows and actions to a full-length commit SHA is a critical security best practice for GitHub Actions [1][2][3]. Because tags and branches are mutable references that can be moved via force-push, they are vulnerable to supply chain attacks where a compromised upstream repository could inject malicious code into your workflows [2][3]. Pinning to a full-length commit SHA ensures that your workflow consistently runs the exact, immutable code you have audited [1][3]. Best Practices for Implementation: 1. Use Full-Length SHAs: Always use the full-length (40-character) commit SHA rather than abbreviated SHAs to prevent potential collisions and ensure immutability [1][3]. 2. Enable Organization-Level Policies: Administrators should enable the Require actions to be pinned to a full-length commit SHA policy at the organization or enterprise level [1][4]. As of August 2025, this policy can be configured to force all workflows to fail if they use unpinned actions [5][6]. 3. Automate Updates with Dependency Managers: SHA pinning creates a maintenance burden. Use tools like Dependabot or Renovate to automatically open pull requests when new versions are released [3]. These tools allow you to review the diff before merging, ensuring you stay updated without manually tracking SHAs [3]. 4. Enforce Cooldown Periods: To further mitigate risk, implement a 7-14 day cooldown period for dependency updates [6]. This allows time for potential compromises in new releases to be discovered by the community before you adopt them [6]. 5. Audit Transitive Dependencies: SHA pinning a direct reference is necessary but not always sufficient. Reusable workflows may pull in other dependencies that are not pinned [4]. Perform periodic audits of your call graph to ensure security practices are applied consistently across all levels [4]. 6. Layer with Additional Security Controls: SHA pinning should be part of a broader security strategy, including: - Restricting usage to authorized, verified creators [1][7]. - Explicitly defining secrets rather than using secrets: inherit [2][8]. - Granting minimal permissions to the GITHUB_TOKEN [2][8]. - Using environment protection rules and OIDC for cloud credentials [2][3].

Citations:


Pin reusable workflow to a full-length commit SHA.

The publish workflow depends on a mutable branch ref (@main) from an external repository, creating a supply chain vulnerability. A compromised upstream repository could inject malicious code into your pipeline without detection. GitHub best practices require pinning to a full-length (40-character) commit SHA for immutability.

Suggested fix
-    uses: blinklabs-io/actions/.github/workflows/reuseable-publish.yml@main
+    uses: blinklabs-io/actions/.github/workflows/reuseable-publish.yml@<commit-sha>
🧰 Tools
🪛 zizmor (1.26.1)

[error] 22-22: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/publish.yml at line 22, The reusable workflow reference in
the publish workflow is using a mutable branch reference `@main` instead of a
pinned commit SHA. Replace the `@main` reference in the uses statement for
blinklabs-io/actions/.github/workflows/reuseable-publish.yml with a full-length
40-character commit SHA to ensure workflow immutability and prevent supply chain
vulnerabilities from upstream changes.

Source: Linters/SAST tools

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0: Reusable publish workflow is referenced with a mutable @main branch ref instead of a pinned commit SHA, introducing supply-chain and reproducibility risk for the release pipeline.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/publish.yml, line 22:

<comment>Reusable publish workflow is referenced with a mutable `@main` branch ref instead of a pinned commit SHA, introducing supply-chain and reproducibility risk for the release pipeline.</comment>

<file context>
@@ -1,180 +1,28 @@
-              core.setFailed(error.message);
-            }
+  orchestrate:
+    uses: blinklabs-io/actions/.github/workflows/reuseable-publish.yml@main
+    secrets:
+      docker-password: ${{ secrets.DOCKER_PASSWORD }}
</file context>

secrets:
docker-password: ${{ secrets.DOCKER_PASSWORD }}
with:
binary-name: tx-submit-api-mirror
description: A Cardano Submit API mirror service
docker-image: blinklabs/tx-submit-api-mirror
29 changes: 10 additions & 19 deletions .github/workflows/test-issue-on-close.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
name: Test Issue Close Trigger
permissions:
contents: read
# Generated automatically by org-governance-bot. Do not edit manually.
name: "Test Issue Close Trigger"

on:
issues:
types: [closed]
types:
- closed

jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Print closed issue info
env:
ISSUE_NUMBER: ${{ github.event.issue.number }}
ISSUE_TITLE: ${{ github.event.issue.title }}
run: |
echo "Issue Number: $ISSUE_NUMBER"
# Prevent workflow command injection from untrusted issue titles
TOKEN=$(uuidgen)
echo "::stop-commands::${TOKEN}"
echo "Title: $ISSUE_TITLE"
echo "::${TOKEN}::"
echo "Workflow triggered successfully when issue was closed."
orchestrate:
uses: blinklabs-io/actions/.github/workflows/reuseable-test-issue-on-close.yml@main

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Verify the file exists and check the exact content at line 11
cat -n .github/workflows/test-issue-on-close.yml 2>/dev/null | head -20

Repository: blinklabs-io/tx-submit-api-mirror

Length of output: 638


🏁 Script executed:

# Also check if there are other workflow files with similar patterns
find .github/workflows -name "*.yml" -o -name "*.yaml" | head -20

Repository: blinklabs-io/tx-submit-api-mirror

Length of output: 428


🏁 Script executed:

# Search for all 'uses' directives in workflow files to understand the pinning pattern used in this repo
rg "uses:" .github/workflows/ -A 1 | head -40

Repository: blinklabs-io/tx-submit-api-mirror

Length of output: 1343


🏁 Script executed:

# Check if there's any documentation or policy file about workflow pinning
find . -maxdepth 2 -type f \( -name "*.md" -o -name "SECURITY*" -o -name ".github/CODEOWNERS" \) -exec cat -n {} + 2>/dev/null | head -100

Repository: blinklabs-io/tx-submit-api-mirror

Length of output: 4181


Address unpinned workflow reference through org-governance-bot configuration.

Line 11 references @main, which is mutable and presents a supply-chain security risk. However, this file is auto-generated by org-governance-bot (see line 1) and should not be manually edited—changes will be overwritten.

File a separate issue with the governance bot configuration to pin reusable workflow references to immutable commit SHAs instead of branch names.

🧰 Tools
🪛 zizmor (1.26.1)

[error] 11-11: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/test-issue-on-close.yml at line 11, The workflow reference
in the reuseable-test-issue-on-close.yml uses `@main` which is a mutable branch
reference presenting a supply-chain security risk. Since this file is
auto-generated by org-governance-bot and manual edits will be overwritten, do
not modify this file directly. Instead, file a separate issue with the
org-governance-bot configuration requesting that it pin all reusable workflow
references to immutable commit SHAs instead of mutable branch names like `@main`.

Source: Linters/SAST tools

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Reusable workflow is referenced via the mutable @main branch instead of an immutable commit SHA. This reduces reproducibility and allows unreviewed upstream changes in blinklabs-io/actions to alter CI behavior unexpectedly.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/test-issue-on-close.yml, line 11:

<comment>Reusable workflow is referenced via the mutable `@main` branch instead of an immutable commit SHA. This reduces reproducibility and allows unreviewed upstream changes in `blinklabs-io/actions` to alter CI behavior unexpectedly.</comment>

<file context>
@@ -1,23 +1,14 @@
-          echo "::${TOKEN}::"
-          echo "Workflow triggered successfully when issue was closed."
+  orchestrate:
+    uses: blinklabs-io/actions/.github/workflows/reuseable-test-issue-on-close.yml@main
+    with:
+      issue_number: ${{ github.event.issue.number }}
</file context>

with:
issue_number: ${{ github.event.issue.number }}
issue_title: ${{ github.event.issue.title }}

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium test

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {}
Comment on lines +11 to +14
Loading
Loading