tenseleyflow/shithub / 1a1cc3f

Browse files

scripts: add Actions GA audit packet

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
1a1cc3f749bf77150a38af7a3455beae5105f26b
Parents
1538b65
Tree
6978ff5

2 changed files

StatusFile+-
M Makefile 4 1
A scripts/audit-actions-ga.sh 93 0
Makefilemodified
@@ -2,7 +2,7 @@
22
 # Targets mirror what CI runs. The Makefile is the source of truth.
33
 
44
 .DEFAULT_GOAL := help
5
-.PHONY: help dev build test test-race lint lint-policy lint-markdown lint-org-plan lint-secret-logs lint-spdx lint-unused lint-migrations verify-api-docs fmt tidy clean ci assets install-tools version deploy deploy-check restore-drill bench-staging docs docs-serve docs-verify gen-third-party-notices audit-a11y audit-a11y-pa11y audit-a11y-axe load-test
5
+.PHONY: help dev build test test-race lint lint-policy lint-markdown lint-org-plan lint-secret-logs lint-spdx lint-unused lint-migrations verify-api-docs fmt tidy clean ci assets install-tools version deploy deploy-check restore-drill bench-staging docs docs-serve docs-verify gen-third-party-notices audit-actions-ga audit-a11y audit-a11y-pa11y audit-a11y-axe load-test
66
 
77
 # Build metadata embedded into the binary via -ldflags.
88
 VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo dev)
@@ -212,6 +212,9 @@ gen-third-party-notices: ## Regenerate THIRD_PARTY_NOTICES.md from the active go
212212
 	@scripts/gen-third-party-notices.sh > THIRD_PARTY_NOTICES.md
213213
 	@echo "gen-third-party-notices: wrote THIRD_PARTY_NOTICES.md"
214214
 
215
+audit-actions-ga: ## Run the read-only S41h Actions pre-GA static audit packet.
216
+	@scripts/audit-actions-ga.sh
217
+
215218
 # --- S39 hardening ---
216219
 audit-a11y-pa11y: ## pa11y-ci scan of anonymous routes (needs running shithub on 127.0.0.1:8080).
217220
 	@command -v pa11y-ci >/dev/null 2>&1 || { echo "pa11y-ci not installed; npm i -g pa11y-ci"; exit 2; }
scripts/audit-actions-ga.shadded
@@ -0,0 +1,93 @@
1
+#!/usr/bin/env bash
2
+# SPDX-License-Identifier: AGPL-3.0-or-later
3
+
4
+set -eu
5
+
6
+ROOT="$(git rev-parse --show-toplevel)"
7
+cd "$ROOT"
8
+
9
+fail() {
10
+  printf 'audit-actions-ga: %s\n' "$*" >&2
11
+  exit 1
12
+}
13
+
14
+ok() {
15
+  printf 'ok: %s\n' "$*"
16
+}
17
+
18
+require_file() {
19
+  [ -f "$1" ] || fail "missing required file: $1"
20
+  ok "found $1"
21
+}
22
+
23
+require_grep() {
24
+  pattern="$1"
25
+  file="$2"
26
+  desc="$3"
27
+  rg -q "$pattern" "$file" || fail "$desc not found in $file"
28
+  ok "$desc"
29
+}
30
+
31
+require_file ".shithub/workflows/checkout-canary.yml"
32
+require_file "bench/fixtures/actions/checkout-canary.yml"
33
+require_file "bench/k6/actions-load.js"
34
+require_file "deploy/monitoring/grafana/dashboards/actions.json"
35
+require_file "deploy/monitoring/prometheus/rules.yml"
36
+require_file "deploy/runner-config/firewall.sh.j2"
37
+require_file "deploy/runner-config/dnsmasq.conf.j2"
38
+require_file "deploy/runner-config/seccomp.json"
39
+require_file "docs/internal/actions-ga-readiness.md"
40
+require_file "docs/internal/runbooks/actions.md"
41
+require_file "docs/internal/runbooks/runner-deploy.md"
42
+require_file "docs/public/user/actions.md"
43
+require_file "docs/public/api/actions.md"
44
+
45
+uses_hits="$(rg -n '^[[:space:]-]*uses:[[:space:]]*' .shithub/workflows -g '*.yml' -g '*.yaml' || true)"
46
+printf '%s\n' "$uses_hits" | while IFS= read -r hit; do
47
+  [ -n "$hit" ] || continue
48
+  ref="$(printf '%s' "$hit" | sed -E 's/.*uses:[[:space:]]*//; s/[[:space:]]+#.*$//; s/^"//; s/"$//; s/^[[:space:]]*//; s/[[:space:]]*$//')"
49
+  ref="${ref#\'}"
50
+  ref="${ref%\'}"
51
+  case "$ref" in
52
+    actions/checkout@v4|shithub/upload-artifact@v1|shithub/download-artifact@v1)
53
+      ;;
54
+    *)
55
+      fail "unsupported .shithub workflow uses alias $ref in $hit"
56
+      ;;
57
+  esac
58
+done
59
+ok ".shithub workflows use only v1-supported aliases"
60
+
61
+require_grep 'actions/setup-go@v5' ".github/workflows/ci.yml" "GitHub CI still documents setup-go dependency"
62
+require_grep 'golangci/golangci-lint-action@v8' ".github/workflows/ci.yml" "GitHub CI still documents golangci action dependency"
63
+require_grep 'Do not move `.github/workflows/ci.yml`' "docs/internal/actions-ga-readiness.md" "dogfood decision"
64
+
65
+for alert in \
66
+  ActionsRunnerHeartbeatStale \
67
+  ActionsQueueDepthHigh \
68
+  ActionsRunDurationP99Regressed \
69
+  ActionsLogScrubberPossiblyMissing
70
+do
71
+  require_grep "$alert" "deploy/monitoring/prometheus/rules.yml" "alert $alert"
72
+done
73
+
74
+for metric in \
75
+  shithub_actions_queue_depth \
76
+  shithub_actions_active \
77
+  shithub_actions_runner_heartbeat_age_seconds \
78
+  shithub_actions_run_duration_seconds \
79
+  shithub_actions_log_chunk_bytes_total
80
+do
81
+  require_grep "$metric" "docs/internal/runbooks/observability.md" "observability doc metric $metric"
82
+done
83
+
84
+require_grep 'runner_jwt_used' "docs/internal/actions-schema.md" "runner JWT replay table documentation"
85
+require_grep 'workflow_job_secret_masks' "docs/internal/actions-schema.md" "claim-time mask table documentation"
86
+require_grep 'direct-IP' "docs/internal/runbooks/runner-deploy.md" "direct-IP egress mitigation"
87
+require_grep 'checkout token leaked into argv' "internal/runner/engine/docker_test.go" "checkout-token argv regression test"
88
+require_grep 'checkout token push unexpectedly succeeded' "internal/web/handlers/githttp/githttp_test.go" "checkout-token push denial test"
89
+require_grep 'TestEval_GithubAliasIsTainted' "internal/actions/expr/eval_test.go" "github alias taint test"
90
+require_grep 'Actions workflow API' "docs/public/SUMMARY.md" "public Actions API docs link"
91
+require_grep '\[Actions\]\(\./user/actions\.md\)' "docs/public/SUMMARY.md" "public Actions user docs link"
92
+
93
+ok "S41h Actions pre-GA static audit packet complete"