|
| 1 | +description: > |
| 2 | + Validates the `Expires` field of `.well-known/security.txt` (RFC 9116). |
| 3 | +
|
| 4 | + If no security.txt file exists in the repo, the step halts (passes) so repos |
| 5 | + that haven't adopted one yet are unaffected. If the file exists but has no |
| 6 | + `Expires` field, this passes with a warning (the field is recommended, not |
| 7 | + universally adopted yet). If `Expires` is present and its date is in the |
| 8 | + past, the step fails the job. |
| 9 | +steps: |
| 10 | + - run: |
| 11 | + name: Check security.txt expiration |
| 12 | + command: | |
| 13 | + SECURITY_TXT=".well-known/security.txt" |
| 14 | +
|
| 15 | + if [ ! -f "$SECURITY_TXT" ]; then |
| 16 | + echo "No $SECURITY_TXT found, skipping check." |
| 17 | + circleci-agent step halt |
| 18 | + exit 0 |
| 19 | + fi |
| 20 | +
|
| 21 | + node -e ' |
| 22 | + const fs = require("fs"); |
| 23 | + const path = ".well-known/security.txt"; |
| 24 | + const content = fs.readFileSync(path, "utf8"); |
| 25 | + const match = content.match(/^Expires:\s*(.+)$/mi); |
| 26 | +
|
| 27 | + if (!match) { |
| 28 | + console.warn("WARNING: " + path + " has no Expires field (RFC 9116 requires one). Skipping."); |
| 29 | + process.exit(0); |
| 30 | + } |
| 31 | +
|
| 32 | + const raw = match[1].trim(); |
| 33 | + const expires = new Date(raw); |
| 34 | +
|
| 35 | + if (isNaN(expires.getTime())) { |
| 36 | + console.error("ERROR: could not parse Expires value in " + path + ": \"" + raw + "\""); |
| 37 | + console.error("Expected an RFC 3339 date-time, e.g. 2027-09-18T00:00:00.000Z"); |
| 38 | + process.exit(1); |
| 39 | + } |
| 40 | +
|
| 41 | + const now = new Date(); |
| 42 | + const daysDiff = Math.floor((expires.getTime() - now.getTime()) / 86400000); |
| 43 | +
|
| 44 | + if (expires.getTime() < now.getTime()) { |
| 45 | + console.error("FAIL: " + path + " expired on " + expires.toISOString() + " (" + Math.abs(daysDiff) + " day(s) ago)."); |
| 46 | + console.error("Update the Expires field in " + path + "."); |
| 47 | + process.exit(1); |
| 48 | + } |
| 49 | +
|
| 50 | + console.log("OK: " + path + " valid until " + expires.toISOString() + " (" + daysDiff + " day(s) remaining)."); |
| 51 | + ' |
0 commit comments