26382a7ac6
CI / Clippy (push) Failing after 15m13s
CI / Test (ubuntu-latest) (push) Failing after 16m1s
CI / Test (macos-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Build (no embeddings / no ORT) (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Cookbook (Node) (push) Has been cancelled
CI / Pi Extension (Node) (push) Has been cancelled
CI / Rust SDK (lean-ctx-client) (push) Has been cancelled
CI / Embed SDK (lean-ctx-sdk) (push) Has been cancelled
CI / Python SDK (leanctx) (push) Has been cancelled
CI / Hermes Plugin (Python) (push) Has been cancelled
CI / SDK Conformance Matrix (push) Has been cancelled
CI / Coverage (push) Has been cancelled
CI / cargo-deny (push) Has been cancelled
CI / Adversarial Safety (push) Has been cancelled
CI / Benchmarks (push) Has been cancelled
CI / Output-Quality Gate (eval A/B) (push) Has been cancelled
CI / Documentation (push) Has been cancelled
CI / CI Green (push) Has been cancelled
JetBrains Plugin / Actionlint (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (rust) (push) Has been cancelled
JetBrains Plugin / Validation (push) Has been cancelled
JetBrains Plugin / Build (push) Has been cancelled
JetBrains Plugin / Test (push) Has been cancelled
Security Check / Security Scan (push) Has been cancelled
172 lines
7.1 KiB
YAML
172 lines
7.1 KiB
YAML
name: Security Check
|
||
|
||
on:
|
||
push:
|
||
branches: [main]
|
||
pull_request:
|
||
branches: [main]
|
||
|
||
permissions:
|
||
contents: read
|
||
|
||
jobs:
|
||
security:
|
||
name: Security Scan
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: Check for dangerous patterns
|
||
run: |
|
||
echo "## Security Pattern Scan" >> $GITHUB_STEP_SUMMARY
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
FOUND=0
|
||
|
||
# Check for unauthorized network libraries
|
||
# Allowed: ureq (used for opt-in cloud sync, updates, error reports)
|
||
# Allowed: std::net::TcpListener (used for local dashboard server)
|
||
# Blocked: reqwest, hyper (heavy HTTP clients not needed)
|
||
if grep -rn 'reqwest::' rust/src/ 2>/dev/null; then
|
||
echo "::warning::Found reqwest usage — use ureq instead"
|
||
echo "- ⚠️ Found reqwest usage (use ureq)" >> $GITHUB_STEP_SUMMARY
|
||
FOUND=1
|
||
fi
|
||
if grep -rn 'hyper::' rust/src/ 2>/dev/null; then
|
||
echo "::warning::Found hyper usage — use ureq instead"
|
||
echo "- ⚠️ Found hyper usage (use ureq)" >> $GITHUB_STEP_SUMMARY
|
||
FOUND=1
|
||
fi
|
||
|
||
# Check for unsafe code
|
||
UNSAFE_COUNT=$(grep -rn 'unsafe {' rust/src/ 2>/dev/null | wc -l)
|
||
if [ "$UNSAFE_COUNT" -gt 0 ]; then
|
||
echo "::warning::Found $UNSAFE_COUNT unsafe blocks"
|
||
echo "- ⚠️ Found $UNSAFE_COUNT unsafe blocks" >> $GITHUB_STEP_SUMMARY
|
||
grep -rn 'unsafe {' rust/src/ >> $GITHUB_STEP_SUMMARY
|
||
FOUND=1
|
||
fi
|
||
|
||
# Check for environment manipulation
|
||
if grep -rn '\.env("LD_PRELOAD")' rust/src/ 2>/dev/null; then
|
||
echo "::error::Found LD_PRELOAD manipulation — potential library hijacking"
|
||
echo "- ❌ Found LD_PRELOAD manipulation" >> $GITHUB_STEP_SUMMARY
|
||
FOUND=1
|
||
fi
|
||
if grep -rn '\.env("DYLD_' rust/src/ 2>/dev/null; then
|
||
echo "::error::Found DYLD manipulation — potential library hijacking"
|
||
echo "- ❌ Found DYLD manipulation" >> $GITHUB_STEP_SUMMARY
|
||
FOUND=1
|
||
fi
|
||
|
||
# Check for hardcoded secrets patterns
|
||
if grep -rn 'sk_live_\|sk_test_\|AKIA[0-9A-Z]\|ghp_[a-zA-Z0-9]' rust/src/ 2>/dev/null; then
|
||
echo "::error::Found potential hardcoded secrets"
|
||
echo "- ❌ Found potential hardcoded secrets" >> $GITHUB_STEP_SUMMARY
|
||
FOUND=1
|
||
fi
|
||
|
||
# Check for shell injection vectors
|
||
SHELL_INJECT=$(grep -rn 'Command::new("sh")\.arg("-c")\.arg(format!' rust/src/ 2>/dev/null | wc -l)
|
||
if [ "$SHELL_INJECT" -gt 0 ]; then
|
||
echo "::warning::Found $SHELL_INJECT potential shell injection vectors"
|
||
echo "- ⚠️ Found $SHELL_INJECT shell injection patterns" >> $GITHUB_STEP_SUMMARY
|
||
FOUND=1
|
||
fi
|
||
|
||
# Check for unwrap() in production code (excluding tests)
|
||
UNWRAP_COUNT=$(grep -rn '\.unwrap()' rust/src/ 2>/dev/null | grep -v '#\[test\]' | grep -v 'mod tests' | wc -l)
|
||
echo "- ℹ️ Found $UNWRAP_COUNT .unwrap() calls in src/" >> $GITHUB_STEP_SUMMARY
|
||
|
||
if [ "$FOUND" -eq 0 ]; then
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
echo "✅ No dangerous patterns detected" >> $GITHUB_STEP_SUMMARY
|
||
fi
|
||
|
||
- name: Proprietary code guardrail
|
||
run: |
|
||
echo "## Proprietary Code Guard" >> $GITHUB_STEP_SUMMARY
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
LEAK=0
|
||
|
||
# Keep in sync with .github-ignore. Business/monetization dirs are
|
||
# gitignored locally; listing them here is server-side defense-in-depth
|
||
# in case the local pre-push hook is not installed.
|
||
PRIVATE_PATHS="cloud/ docker-compose.yml .gitlab-ci.yml deploy.sh DEVELOPMENT.md Makefile.deploy docs/business/ memory-bank/ discord-bot/ n8n-workflows/ lab/ server.md"
|
||
for path in $PRIVATE_PATHS; do
|
||
if [ -e "$path" ]; then
|
||
echo "::error::PROPRIETARY CODE DETECTED: $path exists in the GitHub repository!"
|
||
echo "- **$path** — must not be on GitHub" >> $GITHUB_STEP_SUMMARY
|
||
LEAK=1
|
||
fi
|
||
done
|
||
|
||
if [ "$LEAK" -eq 1 ]; then
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
echo "These paths belong on GitLab only. See .github-ignore." >> $GITHUB_STEP_SUMMARY
|
||
exit 1
|
||
fi
|
||
|
||
echo "No proprietary code found." >> $GITHUB_STEP_SUMMARY
|
||
|
||
- name: Commercial-plane guard
|
||
run: |
|
||
echo "## Commercial-plane Guard" >> $GITHUB_STEP_SUMMARY
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
LEAK=0
|
||
|
||
# Billing/licensing logic lives in the private lean-ctx-cloud repo
|
||
# (oss-plane-separation-v1). core/billing/ is partially OPEN (metering,
|
||
# plans, mod), so we name the specific commercial files rather than the
|
||
# whole directory — the path guard above can't blanket-block them.
|
||
COMMERCIAL_PATHS="rust/src/core/license rust/src/core/licensing/keygen.rs rust/src/cli/license_cmd.rs rust/src/core/billing/success_fee.rs rust/src/core/billing/stripe_invoice.rs docs/contracts/license-v1.md docs/contracts/success-fee-invoice-v1.md"
|
||
for path in $COMMERCIAL_PATHS; do
|
||
if [ -e "$path" ]; then
|
||
echo "::error::COMMERCIAL CODE DETECTED: $path belongs in lean-ctx-cloud, not the open engine!"
|
||
echo "- **$path** — implement in lean-ctx-cloud" >> $GITHUB_STEP_SUMMARY
|
||
LEAK=1
|
||
fi
|
||
done
|
||
|
||
if [ "$LEAK" -eq 1 ]; then
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
echo "The open engine bills nothing and issues no licenses; it only emits the signed savings ledger. See .github-ignore." >> $GITHUB_STEP_SUMMARY
|
||
exit 1
|
||
fi
|
||
|
||
echo "No commercial-plane code found." >> $GITHUB_STEP_SUMMARY
|
||
|
||
- name: Critical files check
|
||
if: github.event_name == 'pull_request'
|
||
run: |
|
||
echo "## Critical Files Modified" >> $GITHUB_STEP_SUMMARY
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
|
||
CRITICAL_FILES="rust/src/shell.rs rust/src/server.rs rust/src/hooks.rs rust/src/core/cache.rs rust/Cargo.toml .github/workflows"
|
||
FOUND_CRITICAL=0
|
||
|
||
for file in $CRITICAL_FILES; do
|
||
if git diff --name-only origin/main...HEAD | grep -q "$file"; then
|
||
echo "- ⚠️ **$file** modified (requires security review)" >> $GITHUB_STEP_SUMMARY
|
||
FOUND_CRITICAL=1
|
||
fi
|
||
done
|
||
|
||
if [ "$FOUND_CRITICAL" -eq 0 ]; then
|
||
echo "✅ No critical files modified" >> $GITHUB_STEP_SUMMARY
|
||
fi
|
||
|
||
- name: Dependency audit
|
||
shell: bash
|
||
run: |
|
||
set -o pipefail
|
||
cargo install cargo-audit
|
||
cd rust && cargo audit 2>&1 | tee audit-output.txt
|
||
AUDIT_EXIT=${PIPESTATUS[0]}
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
echo "## Dependency Audit" >> $GITHUB_STEP_SUMMARY
|
||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||
cat audit-output.txt >> $GITHUB_STEP_SUMMARY
|
||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||
exit $AUDIT_EXIT
|
||
|