Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/zola-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,15 @@ jobs:
repository: valkey-io/valkey-json
path: valkey-json

- name: Init commands, topics and clients
- name: Init commands, topics, clients and security.txt
run: |
cd website
./build/init-topics-and-clients.sh ../valkey-doc/topics \
../valkey-doc/clients
./build/init-commands.sh ../valkey-doc/commands \
../valkey/src/commands ../valkey-bloom/src/commands \
../valkey-json/src/commands ../valkey-search/src/commands
./build/init-security-txt.sh .

- name: Build only
uses: shalzz/zola-deploy-action@v0.22.0
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ _data/modules.json
.idea/*
tmp/*
static/debug
static/.well-known/security.txt
42 changes: 42 additions & 0 deletions build/init-security-txt.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash
# See README for usage
# This file will generate static/.well-known/security.txt (RFC 9116).
#
# The Expires field is derived from the build date rather than committed, so it
# always sits one year past the last site build and cannot silently go stale.

# first check to make sure there are arguments
if [ -z "$1" ]; then
echo "You must supply a path to the site root as the first argument"
exit 1
fi

# check for validity of this argument as a path
if [ ! -d "$1" ]; then
echo "The site root must exist and be a valid path"
exit 1
fi

SITE_ROOT="$1"
WELL_KNOWN="${SITE_ROOT}/static/.well-known"

# one year past this build, in the RFC 3339 form RFC 9116 requires
if date -u -d '+1 year' >/dev/null 2>&1; then
EXPIRES=$(date -u -d '+1 year' +%Y-%m-%dT%H:%M:%SZ) # GNU date
else
EXPIRES=$(date -u -v+1y +%Y-%m-%dT%H:%M:%SZ) # BSD date
Comment on lines +24 to +27

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file context =="
sed -n '1,80p' build/init-security-txt.sh 2>/dev/null || true

echo
echo "== RFC references in repo =="
rg -n "rfc9116|Expires|security.txt|policy.txt" .

echo
echo "== date semantics for one year vs days =="
python3 - <<'PY'
import datetime

for start in ["2023-02-28", "2024-02-28", "2024-12-31", "2025-02-28", "2025-01-01"]:
    d = datetime.date.fromisoformat(start)
    one = d + datetime.timedelta(days=366)
    years = d.replace(year=2026) if d.month == d.month and d.day == d.day else None
    print(f"{start}: +366d={one.isoformat()} days={366}, next-cm=2026-02-28")
PY

tmp="$(mktemp -d)"
if command -v date >/dev/null; then
  echo "== date behavior on this system =="
  printf '%s ' 'GNU/BSD date is:'
  date -u -v+1y +%Y-%m-%dT%H:%M:%SZ >/dev/null 2>&1 && echo "BSD" || echo "not BSD"
  date -u -d '+1 day' +%Y-%m-%dT%H:%M:%SZ >/dev/null 2>&1 && echo "GNU" || echo "not GNU"
  for base in 2023-02-28 2024-02-28 2024-12-31 2025-02-28; do
    d=$(TZ=UTC date -d "$base" +%s)
    echo "----- base $base (epoch $d) -----"
    date -u -d "@$((d + 366*86400))" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || true
    date -u -d "+1 year" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || true
  done
else
  echo "no date command"
fi
rm -rf "$tmp"

Repository: valkey-io/valkey-io.github.io

Length of output: 2976


🌐 Web query:

RFC 9116 security.txt Expires field recommended expiration less than one year

💡 Result:

RFC 9116 explicitly recommends that the "Expires" field in a security.txt file be set to a date and time less than one year in the future [1][2]. This recommendation is intended to help prevent the use of stale information [1][2]. Because inaccurate or outdated security contact information can result in security reports being lost or misdirected—potentially leaving vulnerabilities exposed—the standard emphasizes the importance of keeping the information current [2]. The "Expires" field serves as a mechanism to signal to security researchers when the information in the file is no longer considered valid [1][2]. The field is mandatory and must appear exactly once in the file [1][2].

Citations:


Keep Expires strictly below one year.

RFC 9116 recommends security.txt expirations less than one year in the future. +1 year can be 366 days across a leap year; use a fixed interval such as +364 days instead of a calendar year shift.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@build/init-security-txt.sh` around lines 24 - 27, Update the date calculation
in init-security-txt.sh to use a fixed interval of 364 days in both the GNU date
and BSD date branches, replacing the current calendar-year shift. Keep the
existing UTC timestamp format and platform detection intact so Expires remains
strictly under one year.

Source: MCP tools

fi

mkdir -p "$WELL_KNOWN"

cat > "${WELL_KNOWN}/security.txt" <<EOF
# Valkey security contact — see https://github.com/valkey-io/valkey/security/policy
# Generated at build time by build/init-security-txt.sh — do not edit by hand.
Contact: mailto:security@lists.valkey.io
Expires: ${EXPIRES}
Preferred-Languages: en
Canonical: https://valkey.io/.well-known/security.txt
Policy: https://github.com/valkey-io/valkey/security/policy

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 security Policy Route Remains Indirect

The generated security.txt still points Policy at GitHub's /security/policy UI route. If that route is unavailable or renders a generic page instead of the repository policy, researchers following the published policy link can miss the disclosure instructions even though the repository has a concrete SECURITY.md document.

Suggested change
Policy: https://github.com/valkey-io/valkey/security/policy
Policy: https://github.com/valkey-io/valkey/blob/unstable/SECURITY.md
Artifacts

Repro: security.txt generation output showing indirect Policy line

  • The full command output behind this check.

Repro: Policy line verification script

  • Evidence file captured while the check ran.

Repro: Policy line assertion output

  • The full command output behind this check.

Repro: HTTP comparison script for generated and concrete policy URLs

  • Evidence file captured while the check ran.

Repro: HTTP status and response trace for generated and concrete policy URLs

  • The full command output behind this check.

View artifacts

T-Rex Ran code and verified through T-Rex

EOF
Comment on lines +24 to +40

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Fail the build when generation fails.

Without set -e or explicit status checks, a failed date, mkdir, or cat can be followed by the successful echo, causing .github/workflows/zola-deploy.yml Line 65 to continue with a missing or invalid security.txt.

Add set -euo pipefail after argument validation, or check each command explicitly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@build/init-security-txt.sh` around lines 24 - 40, Make
build/init-security-txt.sh fail immediately when any generation command fails by
enabling strict shell options after argument validation, including set -euo
pipefail. Ensure failures from date, mkdir, or the security.txt heredoc prevent
the script from completing successfully.


echo "Wrote ${WELL_KNOWN}/security.txt (Expires: ${EXPIRES})"