@ministryofjustice/hmpps-precommit-hooks 0.0.1-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ # Change log
2
+
3
+
4
+ ## 0.0.1-alpha.1
5
+
6
+ Pre-releases which should not be used in projects.
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Crown Copyright (Ministry of Justice)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # @ministryofjustice/precommit-hooks
2
+
3
+ This package aims to automatically install and configure husky with gitleaks to help catch potential secrets before committing them to github.
4
+
5
+ ## Status
6
+
7
+ This library is in alpha. Teams are free to use this library but further breaking changes may occur.
8
+
9
+ ## Migrating existing projects
10
+
11
+ #### Automatically installing the library
12
+
13
+ The package will self install and initialised by running via npx:
14
+ `npx @ministryofjustice/precommit-hooks`
15
+
16
+ Note: The project needs to be initialised before use - solely adding the library will make no difference.
17
+ Once the project has been initialised, other developers should be able to develop against it without further configuration.
18
+
19
+ ### How this works
20
+
21
+ Initialising will add new precommit scripts and a new prepare script in `package.json`:
22
+
23
+ ```json
24
+ "scripts": {
25
+ //...
26
+ "prepare": "hmpps-precommit-hooks",
27
+ "precommit:secrets": "gitleaks git --pre-commit --redact --staged --verbose",
28
+ "precommit:lint": "node_modules/.bin/lint-staged",
29
+ "precommit:verify": "npm run typecheck && npm test"
30
+ }
31
+ ```
32
+
33
+ It will also configure a husky precommit hook using these scripts:
34
+
35
+ ```sh
36
+ #!/bin/bash
37
+ NODE_ENV=dev \
38
+ npm run precommit:secrets \
39
+ && npm run precommit:lint \
40
+ && npm run precommit:verify
41
+ ```
42
+
43
+ The prepare script will trigger on any install and ensure that `gitleaks` is installed and `husky` is initiated.
44
+
45
+ Note: `gitleaks` is installed by `brew`, if `brew` is not available then `prepare` will currently fail loudly and display a message.
46
+
47
+ ### Dealing with false positives
48
+
49
+ When a secret is detected, gitleaks will create a fingerprint. If the secret is a false positive then this can be added to the `./gitleaks/.gitleaksignore` to exclude from future scans.
50
+
51
+ Alternatively you can add a gitleaks:allow comment to a line to ignore a secret on it. Eg:
52
+
53
+ ```
54
+ my_secret = 'some-secret' #gitleaks:allow
55
+ ```
56
+
57
+ ### Adding custom rules
58
+
59
+ HMPPS wide rules can be added to `.config.toml` in this project so that it can be picked up by teams when they upgrade to the next released version of this library.
60
+
61
+ Repo specific rules can be added by teams in `.gitleaks/config.toml` in their individual repos.
62
+
63
+ See the gitleaks documentation for how to create rules and [examples](https://github.com/gitleaks/gitleaks/blob/master/config/gitleaks.toml) or use the [online rule wizard](https://gitleaks.io/playground).
64
+
65
+ ### Testing that hooks are configured correctly
66
+
67
+ Secret protection can be tested using the following command:
68
+
69
+ ```bash
70
+ npx -p @ministryofjustice/precommit-hooks -c test-secret-protection
71
+ ```
72
+
73
+ This should fail similarly to:
74
+
75
+ ```bash
76
+ > npx -p @ministryofjustice/precommit-hooks -c test-secret-protection
77
+ Creating test file containing dummy AWS_KEY=AKIA<SOME-VALUE>ASD
78
+ Attempting to commit file containing secret
79
+
80
+ > some-project@0.0.1 precommit:secrets
81
+ > gitleaks git --pre-commit --redact --staged --verbose
82
+
83
+
84
+
85
+ │╲
86
+ │ ○
87
+ ○ ░
88
+ ░ gitleaks
89
+
90
+ Finding: fake_aws_key=REDACTED
91
+ Secret: REDACTED
92
+ RuleID: aws-access-token
93
+ Entropy: 3.546439
94
+ File: demo-password.txt
95
+ Line: 1
96
+ Fingerprint: demo-password.txt:aws-access-token:1
97
+
98
+ 12:49PM INF 1 commits scanned.
99
+ 12:49PM INF scanned ~34 bytes (34 bytes) in 20.7ms
100
+ 12:49PM WRN leaks found: 1
101
+ ```
102
+
103
+ (This will create a `./demo-password.txt` file that will need to be deleted separately)
package/bin/init.sh ADDED
@@ -0,0 +1,80 @@
1
+ #!/bin/bash
2
+ #
3
+ # Used to install husky with gitleaks
4
+ #
5
+
6
+ set -euo pipefail
7
+
8
+ startStage() {
9
+ printf "\x1b[1;97m%s\x1b[0m" "$1"
10
+ }
11
+
12
+ endStage() {
13
+ printf "\x1b[1;97m%s\x1b[0m\n" "$1"
14
+ }
15
+
16
+ printError() {
17
+ printf "\x1b[1;31m%s\x1b[0m\n" "$1"
18
+ }
19
+
20
+ endStage "Setting up precommit hooks"
21
+ endStage "Checking prerequisites..."
22
+
23
+ if ! [ -f ./package.json ]; then
24
+ printError "Not a node project: $(pwd)! exiting!"
25
+ exit 1
26
+ fi
27
+
28
+ startStage " * Setting prepare script"
29
+ npm pkg set --silent scripts.prepare="hmpps-precommit-hooks"
30
+ endStage " ✅"
31
+
32
+ if npm list husky > /dev/null 2>&1; then
33
+ startStage " * Uninstalling husky"
34
+ npm uninstall --silent husky
35
+ endStage " ✅"
36
+ fi
37
+
38
+ if ! npm list @ministryofjustice/precommit-hooks > /dev/null 2>&1; then
39
+ startStage " * Installing @ministryofjustice/precommit-hooks"
40
+ npm install --silent --save-dev @ministryofjustice/precommit-hooks
41
+ endStage " ✅"
42
+ else
43
+ endStage " * @ministryofjustice/precommit-hooks already installed ✅"
44
+ # Run npm install to trigger prepare script
45
+ npm --silent install
46
+ fi
47
+
48
+ endStage "Installing precommit hooks..."
49
+
50
+ startStage " * Adding npm scripts"
51
+ npm pkg --silent set scripts.precommit:secrets="gitleaks git --pre-commit --redact --staged --verbose --config .gitleaks/config.toml"
52
+ npm pkg --silent set scripts.precommit:lint="node_modules/.bin/lint-staged"
53
+ npm pkg --silent set scripts.precommit:verify="npm run typecheck && npm test"
54
+ endStage " ✅"
55
+
56
+ startStage " * Setting precommit hook"
57
+ mkdir -p .husky
58
+ printf "%s\n" \
59
+ "#!/bin/bash" \
60
+ "NODE_ENV=dev \\" \
61
+ "npm run precommit:secrets \\" \
62
+ "&& npm run precommit:lint \\" \
63
+ "&& npm run precommit:verify" \
64
+ > .husky/pre-commit
65
+ endStage " ✅"
66
+
67
+ startStage " * Creating .gitleaksignore "
68
+ mkdir -p .gitleaks
69
+ echo "# The Fingerprint of false positive alerts can be added here to be excluded from future scans." > .gitleaks/.gitleaksignore
70
+ endStage " ✅"
71
+
72
+ startStage " * Creating project gitleaks config"
73
+ printf "%s\n" \
74
+ "title = \"HMPPS Gitleaks configuration\"" \
75
+ "[extend]" \
76
+ "path = \"./node_modules/@ministryofjustice/precommit-hooks/config.toml\"" \
77
+ > .gitleaks/config.toml
78
+ endStage " ✅"
79
+
80
+ endStage "FIN!"
package/bin/prepare.sh ADDED
@@ -0,0 +1,35 @@
1
+ #!/bin/bash
2
+ #
3
+ # This runs as part of any `npm install` via `prepare`
4
+ #
5
+
6
+ set -euo pipefail
7
+
8
+ startStage() {
9
+ printf "\x1b[1;97m%s\x1b[0m" "$1"
10
+ }
11
+
12
+ endStage() {
13
+ printf "\x1b[1;97m%s\x1b[0m\n" "$1"
14
+ }
15
+
16
+ printError() {
17
+ printf "\x1b[1;31m%s\x1b[0m\n" "$1"
18
+ }
19
+
20
+ # Initialise husky
21
+ node_modules/.bin/husky
22
+
23
+ # Check brew exists
24
+ if ! command -v brew &> /dev/null; then
25
+ printError "Brew is not installed, WARNING: no precommit hook protection. exiting..."
26
+ exit 0
27
+ fi
28
+
29
+ # Initialise gitleaks
30
+ if ! command -v gitleaks &> /dev/null; then
31
+ startStage "Installing gitleaks"
32
+ brew install gitleaks
33
+ endStage " ✅ "
34
+ fi
35
+
package/bin/test.sh ADDED
@@ -0,0 +1,13 @@
1
+ #!/bin/bash
2
+
3
+ # Test that secret protection is set up correctly.
4
+ # This will create a separate file ./demo-password.txt which will need to be deleted separately.
5
+
6
+ RANDOM_NUMBER="$(LC_ALL=C tr -cd '[:digit:]' < /dev/urandom | fold -w 13 | head -n 1)"
7
+ AWS_KEY="AKIA${RANDOM_NUMBER}ASD"
8
+
9
+ echo "Creating test file containing dummy AWS_KEY=${AWS_KEY}"
10
+ echo "fake_aws_key=${AWS_KEY}" > ./demo-password.txt
11
+
12
+ echo "Attempting to commit file containing secret"
13
+ git add ./demo-password.txt && git commit -m "This should fail due to detecting dummy AWS creds"
package/config.toml ADDED
@@ -0,0 +1,11 @@
1
+ title = "HMPPS Gitleaks configuration"
2
+
3
+ [extend]
4
+ useDefault = true
5
+
6
+ [[rules]]
7
+ id = "token"
8
+ description = "Possible token detected"
9
+ regex = '''(?i)\b(.{55,65})(?:[\x60'"\s;]|\\[nr]|$)'''
10
+ secretGroup = 1
11
+ entropy = 5.1
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@ministryofjustice/hmpps-precommit-hooks",
3
+ "version": "0.0.1-alpha.1",
4
+ "description": "Precommit hooks for HMPPS typescript projects",
5
+ "keywords": [
6
+ "precommit"
7
+ ],
8
+ "author": "hmpps-developers",
9
+ "license": "MIT",
10
+ "homepage": "https://github.com/ministryofjustice/hmpps-typescript-lib/tree/main/packages/precommit-hooks#readme",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/ministryofjustice/hmpps-typescript-lib.git"
14
+ },
15
+ "bin": {
16
+ "@ministryofjustice/precommit-hooks": "./bin/init.sh",
17
+ "hmpps-precommit-hooks": "./bin/prepare.sh",
18
+ "test-secret-protection": "./bin/test.sh"
19
+ },
20
+ "files": [
21
+ "*.md",
22
+ "bin/*.sh",
23
+ "config.toml"
24
+ ],
25
+ "engines": {
26
+ "node": "20 || 22"
27
+ },
28
+ "dependencies": {
29
+ "husky": "^9.1.7"
30
+ }
31
+ }