cuonztech-privacy-chaos-gate 0.2.0 → 0.2.2
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/LICENSE +97 -0
- package/README.md +197 -30
- package/action.yml +187 -26
- package/dist/chunk-42D7PLVP.js +9146 -0
- package/dist/cli.js +96 -93
- package/dist/index.d.ts +710 -88
- package/dist/index.js +41 -12
- package/docs/BRAND-PILOT-EVIDENCE.md +41 -49
- package/package.json +6 -5
- package/dist/chunk-FN3QUFUZ.js +0 -36
- package/dist/chunk-FN3QUFUZ.js.map +0 -1
- package/dist/chunk-T5D6BUAC.js +0 -4514
- package/dist/chunk-T5D6BUAC.js.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/resolveGrant-6U6VG3DM.js +0 -230
- package/dist/resolveGrant-6U6VG3DM.js.map +0 -1
- package/docs/LIZENZ-KAUFFLUSS.md +0 -105
- package/docs/PREISMODELL.md +0 -63
package/action.yml
CHANGED
|
@@ -10,11 +10,15 @@ inputs:
|
|
|
10
10
|
description: "The URL of the staging or localhost web environment to stress-test"
|
|
11
11
|
required: true
|
|
12
12
|
api-key:
|
|
13
|
-
description: "API key for the
|
|
13
|
+
description: "API key for the optional LLM patch generation. Only OpenAI is implemented (llm-provider openai); other providers fall back to the built-in rules. Has no effect without llm-remediation: true. Passed via the CPCG_LLM_API_KEY environment variable."
|
|
14
14
|
required: false
|
|
15
15
|
default: ""
|
|
16
|
+
llm-remediation:
|
|
17
|
+
description: "Opt-in: allow the source code to be sent to the LLM provider (OpenAI only) to generate patches (needs api-key). Off by default; only passed on if the installed CLI supports it."
|
|
18
|
+
required: false
|
|
19
|
+
default: "false"
|
|
16
20
|
llm-provider:
|
|
17
|
-
description: "LLM
|
|
21
|
+
description: "LLM provider for auto-remediation. Only 'openai' is implemented; 'anthropic' and 'gemini' fall back to the built-in rules."
|
|
18
22
|
required: false
|
|
19
23
|
default: "openai"
|
|
20
24
|
llm-model:
|
|
@@ -22,13 +26,49 @@ inputs:
|
|
|
22
26
|
required: false
|
|
23
27
|
default: "gpt-4o"
|
|
24
28
|
auto-fix:
|
|
25
|
-
description: "
|
|
29
|
+
description: "Generate and apply code patches on the runner when tracker leaks are detected. Off by default: a gate should not silently change files; combine with create-pr to receive the fix as a pull request."
|
|
26
30
|
required: false
|
|
27
|
-
default: "
|
|
31
|
+
default: "false"
|
|
28
32
|
fail-on-leak:
|
|
29
33
|
description: "Block the build (exit code 1) if unpatched critical leaks remain"
|
|
30
34
|
required: false
|
|
31
35
|
default: "true"
|
|
36
|
+
fail-on-uncheckable:
|
|
37
|
+
description: "Block the build (exit code 4) if core scenarios could not be checked conclusively (e.g. consent banner not found). Only passed on if the installed CLI supports it; otherwise a warning is printed."
|
|
38
|
+
required: false
|
|
39
|
+
default: "true"
|
|
40
|
+
strict:
|
|
41
|
+
description: "Hints (purely functional third parties such as Google Fonts) also block the gate. Off by default: they are reported as hints, not as blockers. Only passed on if the installed CLI supports it."
|
|
42
|
+
required: false
|
|
43
|
+
default: "false"
|
|
44
|
+
ignore:
|
|
45
|
+
description: "Findings to ignore: tracker name or host pattern, one per line or comma-separated (e.g. fonts.googleapis.com or *.hotjar.com). Ignored findings are listed as ignored in the report."
|
|
46
|
+
required: false
|
|
47
|
+
default: ""
|
|
48
|
+
accept-selector:
|
|
49
|
+
description: "Own CSS selector of the accept button, one per line (when the built-in CMP detection does not find it)"
|
|
50
|
+
required: false
|
|
51
|
+
default: ""
|
|
52
|
+
reject-selector:
|
|
53
|
+
description: "Own CSS selector of the reject button, one per line"
|
|
54
|
+
required: false
|
|
55
|
+
default: ""
|
|
56
|
+
settings-selector:
|
|
57
|
+
description: "Own CSS selector of the settings button, one per line"
|
|
58
|
+
required: false
|
|
59
|
+
default: ""
|
|
60
|
+
banner-frame:
|
|
61
|
+
description: "Part of the URL of the iframe that contains the consent banner (CMP inside a frame)"
|
|
62
|
+
required: false
|
|
63
|
+
default: ""
|
|
64
|
+
max-subpages:
|
|
65
|
+
description: "Maximum number of linked subpages checked for trackers (default 12, max 40; larger values take longer)"
|
|
66
|
+
required: false
|
|
67
|
+
default: ""
|
|
68
|
+
banner-wait:
|
|
69
|
+
description: "Seconds to wait for a late consent banner (1-60; default as in the CLI)"
|
|
70
|
+
required: false
|
|
71
|
+
default: ""
|
|
32
72
|
report-output:
|
|
33
73
|
description: "File path where the JSON LeakReport will be written"
|
|
34
74
|
required: false
|
|
@@ -38,23 +78,31 @@ inputs:
|
|
|
38
78
|
required: false
|
|
39
79
|
default: "."
|
|
40
80
|
git-commit:
|
|
41
|
-
description: "
|
|
81
|
+
description: "Commit generated privacy fixes into the checked-out branch (requires auto-fix and a valid license; skipped without one)"
|
|
82
|
+
required: false
|
|
83
|
+
default: "false"
|
|
84
|
+
create-pr:
|
|
85
|
+
description: "Create a fix branch and open a GitHub Pull Request with the generated fix (requires auto-fix, github-token and a valid license; takes precedence over git-commit)"
|
|
42
86
|
required: false
|
|
43
87
|
default: "false"
|
|
88
|
+
github-token:
|
|
89
|
+
description: "GitHub token for create-pr (contents: write and pull-requests: write). Passed via the GITHUB_TOKEN environment variable, never on the command line."
|
|
90
|
+
required: false
|
|
91
|
+
default: ""
|
|
44
92
|
license:
|
|
45
|
-
description: "CuonzTech CPCG
|
|
93
|
+
description: "CuonzTech CPCG license (CPCG-… or customer key CPCG-K-…) — from secrets, after online purchase. Not needed for scan and console gate; required for customer report/PDF, git-commit and create-pr. Passed via the CPCG_LICENSE environment variable."
|
|
46
94
|
required: false
|
|
47
95
|
default: ""
|
|
48
96
|
report-pdf:
|
|
49
|
-
description: "
|
|
97
|
+
description: "Create the deluxe PDF (cover page + evidence) after the scan. Requires a valid license; skipped without one."
|
|
50
98
|
required: false
|
|
51
99
|
default: "false"
|
|
52
100
|
client-name:
|
|
53
|
-
description: "
|
|
101
|
+
description: "Client name for the customer report and the PDF cover page. Requires a valid license."
|
|
54
102
|
required: false
|
|
55
103
|
default: ""
|
|
56
104
|
jurisdiction:
|
|
57
|
-
description: "
|
|
105
|
+
description: "Jurisdiction highlighted in the console and report: CH | EU | UK | US-CA | BR | ROW"
|
|
58
106
|
required: false
|
|
59
107
|
default: "CH"
|
|
60
108
|
|
|
@@ -71,39 +119,152 @@ outputs:
|
|
|
71
119
|
report-path:
|
|
72
120
|
description: "Absolute or relative path to the generated JSON report"
|
|
73
121
|
value: ${{ steps.cpcg-run.outputs.report_path }}
|
|
122
|
+
gate_state:
|
|
123
|
+
description: "Gate result as written by the CLI (for example blocked, fix-proposed, inconclusive, passed). Empty if the installed CLI predates this output."
|
|
124
|
+
value: ${{ steps.cpcg-run.outputs.gate_state }}
|
|
125
|
+
incomplete:
|
|
126
|
+
description: "'true' if core scenarios could not be checked conclusively"
|
|
127
|
+
value: ${{ steps.cpcg-run.outputs.incomplete }}
|
|
128
|
+
uncheckable_count:
|
|
129
|
+
description: "Number of scenarios that could not be checked"
|
|
130
|
+
value: ${{ steps.cpcg-run.outputs.uncheckable_count }}
|
|
131
|
+
leak_requests:
|
|
132
|
+
description: "Number of tracker requests observed before consent"
|
|
133
|
+
value: ${{ steps.cpcg-run.outputs.leak_requests }}
|
|
134
|
+
exit_code:
|
|
135
|
+
description: "Exit code of the CLI (0 ok, 1 leaks, 2 license invalid or revoked, 3 error, 4 incomplete)"
|
|
136
|
+
value: ${{ steps.cpcg-run.outputs.exit_code }}
|
|
74
137
|
|
|
75
138
|
runs:
|
|
76
139
|
using: "composite"
|
|
77
140
|
steps:
|
|
78
141
|
- name: Setup Node.js
|
|
79
|
-
uses: actions/setup-node@v4
|
|
142
|
+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
|
80
143
|
with:
|
|
81
144
|
node-version: "20"
|
|
82
145
|
|
|
146
|
+
# Installationsschritt: bewusst ohne Secrets (Lizenz, Token, API-Key) in der Umgebung. Nur hier läuft npm.
|
|
147
|
+
- name: Install Privacy Chaos Gate
|
|
148
|
+
id: cpcg-install
|
|
149
|
+
shell: bash
|
|
150
|
+
env:
|
|
151
|
+
ACTION_PATH: ${{ github.action_path }}
|
|
152
|
+
CPCG_PINNED_VERSION: "0.2.2" # = package.json version; bei jedem Release mit anheben (tests/action-pin.test.ts prüft das)
|
|
153
|
+
run: |
|
|
154
|
+
set -euo pipefail
|
|
155
|
+
|
|
156
|
+
CLI_PATH="$ACTION_PATH/dist/cli.js"
|
|
157
|
+
if [ -f "$CLI_PATH" ]; then
|
|
158
|
+
# Eigener Build im Action-Pfad (Repo-CI): Abhängigkeiten und Browser bringt der Workflow mit.
|
|
159
|
+
echo "cli=$CLI_PATH" >> "$GITHUB_OUTPUT"
|
|
160
|
+
exit 0
|
|
161
|
+
fi
|
|
162
|
+
|
|
163
|
+
# Veröffentlichtes Paket in der gepinnten Version. Lifecycle-Skripte der Abhängigkeiten laufen nicht
|
|
164
|
+
# (--ignore-scripts); der Playwright-Browser wird unten ausdrücklich installiert.
|
|
165
|
+
TOOL_DIR="$(mktemp -d "${RUNNER_TEMP:-${TMPDIR:-/tmp}}/cpcg-XXXXXX")"
|
|
166
|
+
npm install --prefix "$TOOL_DIR" --ignore-scripts --no-audit --no-fund --loglevel=error "cuonztech-privacy-chaos-gate@${CPCG_PINNED_VERSION}"
|
|
167
|
+
PW_CLI="$TOOL_DIR/node_modules/playwright/cli.js"
|
|
168
|
+
if [ -f "$PW_CLI" ]; then
|
|
169
|
+
node "$PW_CLI" install --with-deps chromium
|
|
170
|
+
else
|
|
171
|
+
npx --yes playwright install --with-deps chromium
|
|
172
|
+
fi
|
|
173
|
+
echo "cli=$TOOL_DIR/node_modules/cuonztech-privacy-chaos-gate/dist/cli.js" >> "$GITHUB_OUTPUT"
|
|
174
|
+
|
|
83
175
|
- name: Run Privacy Chaos Gate
|
|
84
176
|
id: cpcg-run
|
|
85
177
|
shell: bash
|
|
178
|
+
# Alle Inputs gelangen nur über env in das Skript (keine ${{ }}-Interpolation im run-Block:
|
|
179
|
+
# sonst könnten Input-Werte als Shell-Code ausgeführt werden). Die Lizenz steht nie in der Kommandozeile.
|
|
86
180
|
env:
|
|
181
|
+
CPCG_CLI: ${{ steps.cpcg-install.outputs.cli }}
|
|
87
182
|
CPCG_LLM_API_KEY: ${{ inputs.api-key }}
|
|
88
183
|
CPCG_LLM_PROVIDER: ${{ inputs.llm-provider }}
|
|
89
184
|
CPCG_LLM_MODEL: ${{ inputs.llm-model }}
|
|
90
185
|
CPCG_LICENSE: ${{ inputs.license }}
|
|
186
|
+
GITHUB_TOKEN: ${{ inputs.github-token }}
|
|
187
|
+
IN_STAGING_URL: ${{ inputs.staging-url }}
|
|
188
|
+
IN_LLM_REMEDIATION: ${{ inputs.llm-remediation }}
|
|
189
|
+
IN_AUTO_FIX: ${{ inputs.auto-fix }}
|
|
190
|
+
IN_FAIL_ON_LEAK: ${{ inputs.fail-on-leak }}
|
|
191
|
+
IN_FAIL_ON_UNCHECKABLE: ${{ inputs.fail-on-uncheckable }}
|
|
192
|
+
IN_STRICT: ${{ inputs.strict }}
|
|
193
|
+
IN_IGNORE: ${{ inputs.ignore }}
|
|
194
|
+
IN_ACCEPT_SELECTOR: ${{ inputs.accept-selector }}
|
|
195
|
+
IN_REJECT_SELECTOR: ${{ inputs.reject-selector }}
|
|
196
|
+
IN_SETTINGS_SELECTOR: ${{ inputs.settings-selector }}
|
|
197
|
+
IN_BANNER_FRAME: ${{ inputs.banner-frame }}
|
|
198
|
+
IN_MAX_SUBPAGES: ${{ inputs.max-subpages }}
|
|
199
|
+
IN_BANNER_WAIT: ${{ inputs.banner-wait }}
|
|
200
|
+
IN_REPORT_OUTPUT: ${{ inputs.report-output }}
|
|
201
|
+
IN_SOURCE_DIR: ${{ inputs.target-source-dir }}
|
|
202
|
+
IN_GIT_COMMIT: ${{ inputs.git-commit }}
|
|
203
|
+
IN_CREATE_PR: ${{ inputs.create-pr }}
|
|
204
|
+
IN_REPORT_PDF: ${{ inputs.report-pdf }}
|
|
205
|
+
IN_CLIENT: ${{ inputs.client-name }}
|
|
206
|
+
IN_JURISDICTION: ${{ inputs.jurisdiction }}
|
|
91
207
|
run: |
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
208
|
+
set -euo pipefail
|
|
209
|
+
|
|
210
|
+
RUNNER=(node "$CPCG_CLI")
|
|
211
|
+
|
|
212
|
+
# Optionen immer als --name=wert: ein Wert, der mit "-" beginnt, wird so nie als eigene Option gelesen.
|
|
213
|
+
ARGS=(
|
|
214
|
+
"--url=$IN_STAGING_URL"
|
|
215
|
+
"--auto-fix=$IN_AUTO_FIX"
|
|
216
|
+
"--fail-on-leak=$IN_FAIL_ON_LEAK"
|
|
217
|
+
"--report-output=$IN_REPORT_OUTPUT"
|
|
218
|
+
"--source-dir=$IN_SOURCE_DIR"
|
|
219
|
+
"--git-commit=$IN_GIT_COMMIT"
|
|
220
|
+
"--create-pr=$IN_CREATE_PR"
|
|
221
|
+
"--report-pdf=$IN_REPORT_PDF"
|
|
222
|
+
"--jurisdiction=$IN_JURISDICTION"
|
|
223
|
+
)
|
|
224
|
+
if [ -n "$IN_CLIENT" ]; then
|
|
225
|
+
ARGS+=("--client=$IN_CLIENT")
|
|
97
226
|
fi
|
|
98
227
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
228
|
+
# Neuere Optionen nur weitergeben, wenn die installierte CLI sie kennt (ältere Versionen würden sonst mit
|
|
229
|
+
# "unknown option" abbrechen). Kennt sie eine gewünschte Option nicht, wird das gemeldet, nicht still übergangen.
|
|
230
|
+
HELP="$("${RUNNER[@]}" --help 2>&1 || true)"
|
|
231
|
+
supports() { printf '%s\n' "$HELP" | grep -q -- "$1"; }
|
|
232
|
+
warn_unsupported() {
|
|
233
|
+
echo "::warning title=CPCG::Die installierte CLI kennt --$1 nicht; der Input wird ignoriert. Paket- und Action-Version angleichen."
|
|
234
|
+
}
|
|
235
|
+
# Boolesche Option: übergeben, wenn bekannt; unbekannt und angefordert ("true") → Warnung.
|
|
236
|
+
opt_bool() {
|
|
237
|
+
if supports "--$1"; then
|
|
238
|
+
ARGS+=("--$1=$2")
|
|
239
|
+
elif [ "$2" = "true" ]; then
|
|
240
|
+
warn_unsupported "$1"
|
|
241
|
+
fi
|
|
242
|
+
return 0
|
|
243
|
+
}
|
|
244
|
+
# Wert-Option (mehrzeilig erlaubt: je nichtleere Zeile eine Option): nur wenn gesetzt.
|
|
245
|
+
opt_lines() {
|
|
246
|
+
local flag="$1" value="$2" line
|
|
247
|
+
[ -n "${value//[[:space:]]/}" ] || return 0
|
|
248
|
+
if ! supports "--$flag"; then
|
|
249
|
+
warn_unsupported "$flag"
|
|
250
|
+
return 0
|
|
251
|
+
fi
|
|
252
|
+
while IFS= read -r line; do
|
|
253
|
+
line="${line#"${line%%[![:space:]]*}"}"
|
|
254
|
+
line="${line%"${line##*[![:space:]]}"}"
|
|
255
|
+
if [ -n "$line" ]; then ARGS+=("--$flag=$line"); fi
|
|
256
|
+
done <<< "$value"
|
|
257
|
+
return 0
|
|
258
|
+
}
|
|
259
|
+
opt_bool fail-on-uncheckable "$IN_FAIL_ON_UNCHECKABLE"
|
|
260
|
+
opt_bool llm-remediation "$IN_LLM_REMEDIATION"
|
|
261
|
+
opt_bool strict "$IN_STRICT"
|
|
262
|
+
opt_lines ignore "$IN_IGNORE"
|
|
263
|
+
opt_lines accept-selector "$IN_ACCEPT_SELECTOR"
|
|
264
|
+
opt_lines reject-selector "$IN_REJECT_SELECTOR"
|
|
265
|
+
opt_lines settings-selector "$IN_SETTINGS_SELECTOR"
|
|
266
|
+
opt_lines banner-frame "$IN_BANNER_FRAME"
|
|
267
|
+
opt_lines max-subpages "$IN_MAX_SUBPAGES"
|
|
268
|
+
opt_lines banner-wait "$IN_BANNER_WAIT"
|
|
269
|
+
|
|
270
|
+
"${RUNNER[@]}" "${ARGS[@]}"
|