Skip to content
Merged
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
8 changes: 8 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,14 @@ jobs:
shell: bash
run: bash scripts/verify/tests/verify-vulnerability-gates.Tests.sh

- name: Self-test gosec gate (fail-closed contract)
shell: bash
run: bash scripts/verify/tests/verify-gosec-gates.Tests.sh

- name: Self-test secret guard (fail-closed contract)
shell: bash
run: bash scripts/verify/tests/check-secrets.Tests.sh

- name: Verify Web Hub-only boundary
run: python scripts/verify/verify-web-hub-boundary.py

Expand Down
104 changes: 104 additions & 0 deletions scripts/verify/tests/check-secrets.Tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/usr/bin/env bash
# Self-tests for check-secrets.sh — fail-closed secret guard contract.
#
# Positive: placeholder values, *.env.example files, and *_URL endpoint
# assignments pass.
# Negative: real AWS keys, GitHub tokens, private key blocks, and API keys
# (sk-...) in staged diffs must ALL exit non-zero.
#
# Runs in CI validate job alongside verify-vulnerability-gates.Tests.sh.
set -uo pipefail

SCRIPT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/check-secrets.sh"
PASS=0
FAIL=0

check() {
local name="$1" expect_fail="$2" actual="$3"
if { [[ "$expect_fail" == "yes" ]] && [[ "$actual" -ne 0 ]]; } || \
{ [[ "$expect_fail" == "no" ]] && [[ "$actual" -eq 0 ]]; }; then
echo " PASS $name (exit=$actual)"
PASS=$((PASS + 1))
else
echo " FAIL $name (exit=$actual, expected $([[ "$expect_fail" == "yes" ]] && echo "!=0" || echo "0"))"
FAIL=$((FAIL + 1))
fi
}

# Create a temp git repo so check-secrets.sh has a git root to scan.
TMP_REPO="$(mktemp -d)"
trap 'rm -rf "$TMP_REPO"' EXIT
cd "$TMP_REPO"
git init --quiet
git config user.email "test@example.com"
git config user.name "Test"

echo "=== empty worktree (no changes) ==="
bash "$SCRIPT" --worktree >/dev/null 2>&1
check "empty worktree exits 0" no $?

echo "=== placeholder .env.example passes ==="
cat > .env.example <<'ENV'
AGENTHUB_TOKENDANCE_ID_CLIENT_SECRET=your-client-secret-here
AGENTHUB_HUB_JWT_SECRET=change-me-in-production
ENV
git add .env.example
bash "$SCRIPT" --staged >/dev/null 2>&1
check "placeholder .env.example passes" no $?

echo "=== *_URL endpoint assignment passes ==="
cat > config.yaml <<'YAML'
AGENTHUB_TOKENDANCE_ID_ISSUER_URL=https://id.example.com
AGENTHUB_TOKENDANCE_ID_REDIRECT_URI=https://hub.example.com/client/auth/callback
YAML
git add config.yaml
git commit --quiet -m "add config" 2>/dev/null
# Now stage a new change with a URL assignment
echo 'AGENTHUB_WEB_URL=https://web.example.com' >> config.yaml
git add config.yaml
bash "$SCRIPT" --staged >/dev/null 2>&1
check "*_URL endpoint assignment passes" no $?

echo "=== real AWS access key fails ==="
git reset --quiet
cat > secrets.yaml <<'YAML'
aws_access_key_id: AKIAIOSFODNN7EXAMPLE

Check failure on line 65 in scripts/verify/tests/check-secrets.Tests.sh

View workflow job for this annotation

GitHub Actions / validate

possible AWS access key detected
YAML
git add secrets.yaml
bash "$SCRIPT" --staged >/dev/null 2>&1
check "AWS access key fails" yes $?

echo "=== GitHub token fails ==="
git reset --quiet
cat > gh-token.json <<'JSON'
{"token": "ghp_1234567890abcdefghijklmnopqrstuvwxyzABCD"}

Check failure on line 74 in scripts/verify/tests/check-secrets.Tests.sh

View workflow job for this annotation

GitHub Actions / validate

possible GitHub token detected
JSON
git add gh-token.json
bash "$SCRIPT" --staged >/dev/null 2>&1
check "GitHub token fails" yes $?

echo "=== private key block fails ==="
git reset --quiet
cat > key.pem <<'PEM'
-----BEGIN RSA PRIVATE KEY-----

Check failure on line 83 in scripts/verify/tests/check-secrets.Tests.sh

View workflow job for this annotation

GitHub Actions / validate

private key block detected
MIIEpAIBAAKCAQEA1234567890abcdefghijklmnopqrstuvwxyz
-----END RSA PRIVATE KEY-----
PEM
git add key.pem
bash "$SCRIPT" --staged >/dev/null 2>&1
check "private key file path fails" yes $?

echo "=== API key (sk-) fails ==="
git reset --quiet
cat > api.yaml <<'YAML'
openai_api_key: sk-proj-1234567890abcdefghijklmnopqrstuvwxyz

Check failure on line 94 in scripts/verify/tests/check-secrets.Tests.sh

View workflow job for this annotation

GitHub Actions / validate

possible API key detected
YAML
git add api.yaml
bash "$SCRIPT" --staged >/dev/null 2>&1
check "sk- API key fails" yes $?

echo ""
echo "Results: $PASS passed, $FAIL failed"
if [[ "$FAIL" -gt 0 ]]; then
exit 1
fi
2 changes: 2 additions & 0 deletions scripts/verify/verify-ci-gates.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ def main() -> int:
assert_contains(vuln_go, re.escape("verify-vulnerability-gates.sh govulncheck"), "vuln-scan-go must run the fail-closed govulncheck verifier")
assert_contains(vuln_js, re.escape("verify-vulnerability-gates.sh pnpm-audit"), "vuln-scan-js must run the fail-closed pnpm audit verifier")
assert_contains(validate, r"Self-test vulnerability gates", "validate must self-test the vulnerability gates")
assert_contains(validate, r"Self-test gosec gate", "validate must self-test the gosec fail-closed contract")
assert_contains(validate, r"Self-test secret guard", "validate must self-test the secret guard fail-closed contract")

# Native Windows is a compatibility contract, not a duplicate release
# pipeline: backend and frontend matrix legs must remain path-filtered and
Expand Down
Loading