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
149 changes: 149 additions & 0 deletions .github/workflows/analyze.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
name: AI Slop Gate Compliance Analysis

on:
pull_request:
branches: [ main ]
push:
branches: [ main ]
workflow_dispatch:

permissions:
pull-requests: write
contents: read

jobs:
compliance-analysis:
runs-on: ubuntu-22.04
timeout-minutes: 20

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Cache ai-slop-gate cache directory
uses: actions/cache@v4
with:
path: ~/.cache/ai-slop-gate
key: ai-slop-gate-cache-${{ runner.os }}-${{ hashFiles('**/*.py', '**/*.yml', '**/*.yaml') }}
restore-keys: |
ai-slop-gate-cache-${{ runner.os }}-

# Run compliance analysis
- name: Compliance Analysis (ai-slop-gate)
id: compliance_gate
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
continue-on-error: true
run: |
mkdir -p ~/.cache/ai-slop-gate

# Run compliance check and capture output (don't fail on non-zero exit)
set +e # Disable exit on error temporarily
docker run --rm \
-v "${{ github.workspace }}:/data" \
-v ~/.cache/ai-slop-gate:/root/.cache/ai-slop-gate \
-e GITHUB_TOKEN \
ghcr.io/sergudo/ai-slop-gate:latest \
run --compliance --policy /data/policy.yml --path /data > raw_report.txt 2>&1

EXIT_CODE=$?
set -e # Re-enable exit on error

# Always show report
cat raw_report.txt

# Save exit code for later steps
echo "exit_code=$EXIT_CODE" >> $GITHUB_OUTPUT

# Extract verdict (default to UNKNOWN if not found)
VERDICT=$(grep "Policy Verdict:" raw_report.txt | awk '{print $NF}' || echo "UNKNOWN")
echo "verdict=$VERDICT" >> $GITHUB_OUTPUT

# Count findings (default to 0 if not found)
FINDINGS=$(grep "Total findings:" raw_report.txt | awk '{print $NF}' || echo "0")
echo "findings=$FINDINGS" >> $GITHUB_OUTPUT

# Log extracted values
echo "📊 Extracted values:"
echo " Exit code: $EXIT_CODE"
echo " Verdict: $VERDICT"
echo " Findings: $FINDINGS"

# Don't fail here - let continue-on-error handle it
exit 0

# Post comment on PR (always, not just on failure)
- name: Post Compliance Report to PR
if: github.event_name == 'pull_request' && always()
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Extract clean report (fix sed pattern)
sed -n '/=== AI SLOP GATE REPORT ===/,/=== END OF REPORT ===/p' raw_report.txt > clean_report.md

# Determine emoji and status based on verdict
VERDICT="${{ steps.compliance_gate.outputs.verdict }}"
FINDINGS="${{ steps.compliance_gate.outputs.findings }}"

if [ "$VERDICT" = "BLOCKING" ]; then
EMOJI="🚨"
STATUS="**BLOCKING** - Action Required"
COLOR="⚠️"
elif [ "$VERDICT" = "ADVISORY" ]; then
EMOJI="⚠️"
STATUS="**ADVISORY** - Review Recommended"
COLOR="📋"
else
EMOJI="✅"
STATUS="**PASSED** - No Issues Found"
COLOR="✨"
fi

# Create professional comment
cat > final_comment.md << EOF
## $EMOJI AI Slop Gate Compliance Analysis

**Status:** $STATUS
**Findings:** $FINDINGS issue(s) detected

---

EOF

# Append the clean report
cat clean_report.md >> final_comment.md

# Add footer
cat >> final_comment.md << EOF

---

<details>
<summary>📚 How to fix violations</summary>

### License Violations (GPL/AGPL)
1. Remove the dependency or find an alternative with a permissive license
2. If the dependency is necessary, consult with legal team
3. Add to \`.trivyignore\` only if approved by compliance team

### Data Residency Violations
1. Ensure all endpoints use EU regions
2. Update configuration to use \`eu-west-1\`, \`eu-central-1\`, etc.
3. Remove references to US/AP regions

</details>

<sub>🤖 Powered by [AI Slop Gate](https://github.com/SergUdo/ai-slop-gate) | Run: \`${{ github.run_id }}\`</sub>
EOF

# Post comment
gh pr comment ${{ github.event.pull_request.number }} \
--body-file final_comment.md \
--repo ${{ github.repository }}

# Set job status based on verdict
- name: Check Compliance Result
if: steps.compliance_gate.outputs.verdict == 'BLOCKING'
run: |
echo "❌ Compliance analysis found blocking violations"
exit 1
21 changes: 0 additions & 21 deletions Dockerfile

This file was deleted.

14 changes: 14 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# GPL-3.0 License (FORBIDDEN)
source 'https://rubygems.org'

ruby '2.3.0' # EOL Ruby — Trivy flag

# Known vulnerable gems
gem 'rails', '4.2.0' # CVE-2015-7576, CVE-2016-6316
gem 'rack', '1.6.0' # CVE-2018-16470
gem 'nokogiri', '1.6.6' # CVE-2017-9050
gem 'json', '1.8.1' # CVE-2020-10663
gem 'devise', '3.2.4' # multiple CVEs
gem 'rest-client', '1.6.7' # CVE-2015-1820
gem 'webrick', '1.3.1' # CVE-2020-25613

11 changes: 11 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
GEM
specs:

PLATFORMS
ruby
x86_64-linux

DEPENDENCIES

BUNDLED WITH
2.6.3
128 changes: 128 additions & 0 deletions app.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# frozen_string_literal: false
# License: GPL-3.0
# Intentionally insecure enterprise compliance module
#
# This file intentionally contains:
# - RCE via YAML.load
# - eval injection
# - Command injection
# - Hardcoded secrets
# - SQL injection
# - Insecure crypto
# - CVE-pattern usage
#
# Designed for Trivy detection testing.

require 'yaml'
require 'json'
require 'openssl'
require 'net/http'
require 'uri'
require 'sqlite3'

DB = SQLite3::Database.new(":memory:")

# Hardcoded secret (Trivy secret scanner)
MASTER_KEY = "SUPER_SECRET_PRODUCTION_KEY_123456"
AWS_SECRET_ACCESS_KEY = "AKIAIOSFODNN7EXAMPLE"
PRIVATE_RSA_KEY = <<~KEY
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAtestfakekeyfortrivyexample123456789
-----END RSA PRIVATE KEY-----
KEY

class EnterpriseComplianceEngine

def initialize
@debug = true
end

# ❌ RCE via YAML (CVE-2013-0156 pattern)
def unsafe_yaml_deserialize(payload)
YAML.load(payload)
end

# ❌ eval injection
def execute_dynamic_code(code)
eval(code)
end

# ❌ Command Injection
def run_shell(user_input)
system("echo #{user_input}")
end

# ❌ SQL Injection
def find_user(username)
DB.execute("CREATE TABLE IF NOT EXISTS users (name TEXT)")
DB.execute("INSERT INTO users (name) VALUES ('admin')")
DB.execute("SELECT * FROM users WHERE name = '#{username}'")
end

# ❌ Insecure crypto (static IV)
def insecure_encrypt(data)
cipher = OpenSSL::Cipher.new("AES-128-CBC")
cipher.encrypt
cipher.key = MASTER_KEY[0..15]
cipher.iv = "AAAAAAAAAAAAAAAA" # static IV
cipher.update(data) + cipher.final
end

# ❌ Insecure HTTP (no TLS validation)
def fetch_policy
Net::HTTP.get(URI("http://example.com"))
end

# ❌ Mass assignment style slop
def update_config(params)
params.each do |k,v|
instance_variable_set("@#{k}", v)
end
end

# Fake compliance check (AI slop)
def deep_enterprise_compliance_scan(input)
result = {
gdpr: false,
nis2: false,
cra: false,
risk_score: rand(100),
timestamp: Time.now
}

if input.include?("GPL")
result[:license_risk] = "HIGH"
end

if input.include?("eval")
result[:dynamic_execution_detected] = true
end

result
end

end

# Procedural slop block
if __FILE__ == $0
engine = EnterpriseComplianceEngine.new

malicious_yaml = <<~YAML
--- !ruby/object:OpenStruct
table:
foo: bar
YAML

engine.unsafe_yaml_deserialize(malicious_yaml)

engine.execute_dynamic_code("puts 'RCE executed'")

engine.run_shell("$(whoami)")

engine.find_user("' OR 1=1 --")

encrypted = engine.insecure_encrypt("sensitive data")
puts encrypted

puts engine.deep_enterprise_compliance_scan("GPL eval test")
end
Loading