Add GitHub Actions workflow for security checks#16
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR introduces a GitHub Actions workflow to enforce security policies and validate code changes. The workflow runs on pull requests targeting the main branch and performs path validation, cryptographic signature verification for configuration files, and static security analysis.
Key Changes:
- Adds automated security checks that run on every pull request
- Implements allowlist-based path validation to prevent unauthorized file modifications
- Introduces cryptographic signature verification for deploy-config.json changes
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| CHANGED=$(git diff --name-only HEAD~1 || true) | ||
| echo "$CHANGED" | grep -E '^(simulator/|tests/|docs/|\.agent/|\.github/)' || (echo "Illegal path change detected" && exit 1) | ||
|
|
||
| - name: Verify deploy-config signatures if changed | ||
| run: | | ||
| if git diff --name-only HEAD~1 | grep -q 'simulator/deploy-config.json'; then |
There was a problem hiding this comment.
Using HEAD~1 may not correctly identify changed files in a pull request context. In GitHub Actions pull_request events, you should compare against the base branch using origin/${{ github.base_ref }} or use ${{ github.event.pull_request.base.sha }} to ensure accurate detection of changed files.
| CHANGED=$(git diff --name-only HEAD~1 || true) | |
| echo "$CHANGED" | grep -E '^(simulator/|tests/|docs/|\.agent/|\.github/)' || (echo "Illegal path change detected" && exit 1) | |
| - name: Verify deploy-config signatures if changed | |
| run: | | |
| if git diff --name-only HEAD~1 | grep -q 'simulator/deploy-config.json'; then | |
| CHANGED=$(git diff --name-only ${{ github.event.pull_request.base.sha }} || true) | |
| echo "$CHANGED" | grep -E '^(simulator/|tests/|docs/|\.agent/|\.github/)' || (echo "Illegal path change detected" && exit 1) | |
| - name: Verify deploy-config signatures if changed | |
| run: | | |
| if git diff --name-only ${{ github.event.pull_request.base.sha }} | grep -q 'simulator/deploy-config.json'; then |
| run: | | ||
| echo "Validating changed paths..." | ||
| CHANGED=$(git diff --name-only HEAD~1 || true) | ||
| echo "$CHANGED" | grep -E '^(simulator/|tests/|docs/|\.agent/|\.github/)' || (echo "Illegal path change detected" && exit 1) |
There was a problem hiding this comment.
This validation logic will fail if there are no changed files (empty $CHANGED), causing false positives. Additionally, it only validates that at least one file matches the allowlist pattern, but doesn't reject files outside the allowlist. Consider using grep -v to explicitly reject non-allowlisted paths or iterate over each changed file individually.
| echo "$CHANGED" | grep -E '^(simulator/|tests/|docs/|\.agent/|\.github/)' || (echo "Illegal path change detected" && exit 1) | |
| if [ -z "$CHANGED" ]; then | |
| echo "No files changed." | |
| elif echo "$CHANGED" | grep -v -E '^(simulator/|tests/|docs/|\.agent/|\.github/)' >/dev/null; then | |
| echo "Illegal path change detected" | |
| echo "$CHANGED" | grep -v -E '^(simulator/|tests/|docs/|\.agent/|\.github/)' | |
| exit 1 | |
| else | |
| echo "All changed files are allowlisted." | |
| fi |
| CHANGED=$(git diff --name-only HEAD~1 || true) | ||
| echo "$CHANGED" | grep -E '^(simulator/|tests/|docs/|\.agent/|\.github/)' || (echo "Illegal path change detected" && exit 1) | ||
|
|
||
| - name: Verify deploy-config signatures if changed | ||
| run: | | ||
| if git diff --name-only HEAD~1 | grep -q 'simulator/deploy-config.json'; then |
There was a problem hiding this comment.
Same issue as Comment 1: HEAD~1 is incorrect for pull request contexts. Use origin/${{ github.base_ref }} or the appropriate base commit reference instead.
| CHANGED=$(git diff --name-only HEAD~1 || true) | |
| echo "$CHANGED" | grep -E '^(simulator/|tests/|docs/|\.agent/|\.github/)' || (echo "Illegal path change detected" && exit 1) | |
| - name: Verify deploy-config signatures if changed | |
| run: | | |
| if git diff --name-only HEAD~1 | grep -q 'simulator/deploy-config.json'; then | |
| CHANGED=$(git diff --name-only origin/${{ github.base_ref }} || true) | |
| echo "$CHANGED" | grep -E '^(simulator/|tests/|docs/|\.agent/|\.github/)' || (echo "Illegal path change detected" && exit 1) | |
| - name: Verify deploy-config signatures if changed | |
| run: | | |
| if git diff --name-only origin/${{ github.base_ref }} | grep -q 'simulator/deploy-config.json'; then |
| def hash_payload(path): | ||
| data = open(path, "rb").read() | ||
| return hashlib.sha256(data).digest() | ||
| vk = VerifyingKey.from_string(bytes.fromhex("04"+"0"*128), curve=SECP256k1) # replace with your pubkey |
There was a problem hiding this comment.
The verification key is a placeholder (all zeros) with a comment to replace it. This means signature verification will always use an invalid public key, rendering the security check ineffective. The actual public key must be configured before this workflow can provide real security.
| vk = VerifyingKey.from_string(bytes.fromhex("04"+"0"*128), curve=SECP256k1) # replace with your pubkey | |
| vk = VerifyingKey.from_string(bytes.fromhex("<YOUR_PUBLIC_KEY_HEX>"), curve=SECP256k1) # TODO: Replace <YOUR_PUBLIC_KEY_HEX> with your actual uncompressed public key hex (starts with 04...) |
| if git diff --name-only HEAD~1 | grep -q 'simulator/deploy-config.json'; then | ||
| python - <<'PY' | ||
| import sys, json, hashlib, base64 | ||
| from ecdsa import VerifyingKey, SECP256k1 |
There was a problem hiding this comment.
The ecdsa Python package is used but never installed. Add a step to install it (e.g., pip install ecdsa) before running this verification script, otherwise the import will fail.
| pip install bandit || true | ||
| bandit -q -r simulator || true |
There was a problem hiding this comment.
Using || true on both the installation and execution of bandit means failures are silently ignored, defeating the purpose of static security analysis. If bandit finds security issues or fails to install, the workflow will still pass. Remove || true to ensure security issues cause the workflow to fail.
| pip install bandit || true | |
| bandit -q -r simulator || true | |
| pip install bandit | |
| bandit -q -r simulator |
No description provided.