-
Notifications
You must be signed in to change notification settings - Fork 384
/
Copy pathverify-locked-down-signatures.sh
executable file
·89 lines (75 loc) · 2.87 KB
/
verify-locked-down-signatures.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/usr/bin/env bash
set -eu
shopt -s nullglob
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
readonly SCRIPT_DIR
readonly REPO_DIR="$SCRIPT_DIR/.."
# In the CI environment we would like to import trusted public keys from a file,
# but not in our build environment
import_gpg_keys="false"
# The policy of enforcing lockfiles to be signed was not in place before this commit and
# as such some of the commits before are not signed
# The whitelisted commit can be set in order to allow github actions to only check changes
# since origin/main
whitelisted_commit="618130520"
while [ "$#" -gt 0 ]; do
case "$1" in
"--import-gpg-keys")
import_gpg_keys="true"
;;
"--whitelist")
whitelisted_commit="$2"
shift
;;
*)
echo "Unknown argument $1
The options are --import-gpg-keys and --whitelist"
exit 1
;;
esac
shift
done
if [[ "$import_gpg_keys" == "true" ]]; then
GNUPGHOME=$(mktemp -d)
export GNUPGHOME
for key in "$SCRIPT_DIR"/keys/*; do
gpg --import "$key"
done
fi
# Parse the locked down files from the github actions workflow file.
# We need to define them there since github has no way to trigger on filepaths specified in a file.
# We parse them from there in order to avoid duplicating the locked down files in multiple places.
#
# This regexp line is using a regexp to parse the github .yml file for the YAML list
# that follows the `paths` key.
# It uses `tr` in order to turn the multi-lined file into a single-line that sed can parse
# correctly. This is done by replacing all new-lines with a `;`
readonly SEPARATOR=';'
locked_down_paths=$(\
< "$REPO_DIR/.github/workflows/verify-locked-down-signatures.yml" tr '\n' $SEPARATOR \
| sed "s/.*paths:$SEPARATOR\(\(\s*-\s[a-zA-Z\/.*-]*$SEPARATOR\)*\).*/\1/" \
| tr $SEPARATOR '\n' \
| awk '{print $2}')
unsigned_commits_exist=0
important_file_was_removed=0
for locked_path in $locked_down_paths; do
echo "Checking $locked_path"
locked_path_commit_hashes=$(git rev-list --oneline "$whitelisted_commit"..HEAD \
"$REPO_DIR/$locked_path" | awk '{print $1}')
for commit in $locked_path_commit_hashes; do
echo -e "\tfound a change in $commit.."
if ! git verify-commit "$commit" 2> /dev/null; then
echo "Commit $commit which changed $locked_path is not signed."
unsigned_commits_exist=1
fi
done
# Check if important file has been removed.
if [[ ! -e "$REPO_DIR/$locked_path" ]]; then
echo "$locked_path was removed. If this was intentional, remove it from 'verify-locked-down-signatures.yml'"
important_file_was_removed=1
fi
done
if [[ "$unsigned_commits_exist" != 0 || "$important_file_was_removed" != 0 ]]; then
exit 1
fi
echo "SUCCESS: Could not find any offenses to locked down paths"