#!/usr/bin/env bash # AI SDLC Standards — Deterministic Compliance Checker # Checks organizational and architectural policy, NOT static code analysis. # Usage: ./check.sh [--diff ] set -euo pipefail REPO="${1:-.}" DIFF_MODE=false BASE_BRANCH="" VIOLATIONS=0 WARNINGS=0 if [[ "${2:-}" == "--diff" ]]; then DIFF_MODE=true BASE_BRANCH="${3:-main}" fi RED='\033[0;31m' YELLOW='\033[1;33m' GREEN='\033[0;32m' CYAN='\033[0;36m' NC='\033[0m' pass() { echo -e " ${GREEN}✓${NC} $1"; } warn() { echo -e " ${YELLOW}⚠${NC} $1"; WARNINGS=$((WARNINGS + 1)); } fail() { echo -e " ${RED}✗${NC} $1"; VIOLATIONS=$((VIOLATIONS + 1)); } echo "═══════════════════════════════════════" echo " AI SDLC Standards Compliance Check" echo "═══════════════════════════════════════" echo "" # ── SECURITY ── echo -e "${CYAN}Security${NC}" # SEC-001: No IAM Resources in Service Repos echo "▸ SEC-001: No IAM in Service Repos" IAM_FILES=$(find "$REPO" -name '*.tf' -exec grep -l 'aws_iam_\|google_project_iam\|azurerm_role' {} \; 2>/dev/null || true) if [[ -n "$IAM_FILES" ]]; then for f in $IAM_FILES; do fail "IAM resources in service repo: $f"; done else pass "No IAM resource definitions found" fi # SEC-002: No Custom Auth / JWT Handling echo "▸ SEC-002: No Custom Auth Mechanisms" CUSTOM_AUTH=$(find "$REPO" -type f \( -name '*.java' -o -name '*.go' -o -name '*.ts' -o -name '*.py' \) ! -path '*/test/*' -exec grep -l 'io\.jsonwebtoken\|jwt\.decode\|jwt\.sign\|JWTVerifier\|PyJWT' {} \; 2>/dev/null || true) LOGIN_ENDPOINTS=$(find "$REPO" -type f \( -name '*.java' -o -name '*.go' -o -name '*.ts' -o -name '*.py' \) ! -path '*/test/*' -exec grep -l '"/login"\|"/authenticate"\|"/signin"' {} \; 2>/dev/null || true) if [[ -n "$CUSTOM_AUTH" ]]; then for f in $CUSTOM_AUTH; do fail "Custom JWT/auth library: $f"; done fi if [[ -n "$LOGIN_ENDPOINTS" ]]; then for f in $LOGIN_ENDPOINTS; do fail "Custom login endpoint: $f"; done fi if [[ -z "$CUSTOM_AUTH" && -z "$LOGIN_ENDPOINTS" ]]; then pass "No custom auth mechanisms found" fi # SEC-003: No Direct External Network Calls echo "▸ SEC-003: No Direct External Calls" EXT_CALLS=$(find "$REPO" -type f \( -name '*.java' -o -name '*.go' -o -name '*.ts' -o -name '*.py' \) ! -path '*/test/*' -exec grep -Pn 'https?://(?!localhost|127\.0\.0\.1|10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.)(?!.*reltio\.(com|net|io))' {} \; 2>/dev/null | grep -v '^\s*//' | head -5 || true) if [[ -n "$EXT_CALLS" ]]; then echo "$EXT_CALLS" | while read -r line; do fail "Direct external call: $line"; done else pass "No direct external network calls" fi echo "" # ── ARCHITECTURE ── echo -e "${CYAN}Architecture${NC}" # ARCH-001: No Cross-Cloud Dependencies echo "▸ ARCH-001: No Cross-Cloud SDK Imports" CLOUD_IMPORTS=$(find "$REPO" -type f \( -name '*.java' -o -name '*.go' -o -name '*.ts' -o -name '*.py' \) ! -path '*/test/*' ! -path '*/platform/*' -exec grep -ln 'com\.amazonaws\.\|com\.google\.cloud\.\|com\.azure\.\|@aws-sdk\|@google-cloud\|@azure' {} \; 2>/dev/null || true) if [[ -n "$CLOUD_IMPORTS" ]]; then for f in $CLOUD_IMPORTS; do fail "Direct cloud SDK import: $f"; done else pass "No direct cloud SDK imports" fi # ARCH-002: No Cross-Service Database Access echo "▸ ARCH-002: No Cross-Service DB Access" CROSS_DB=$(find "$REPO" -type f \( -name '*.java' -o -name '*.go' -o -name '*.ts' -o -name '*.py' -o -name '*.sql' \) ! -path '*/test/*' -exec grep -ln '[a-z_]*_service\.\|cross_schema\|foreign_schema' {} \; 2>/dev/null || true) if [[ -n "$CROSS_DB" ]]; then for f in $CROSS_DB; do warn "Possible cross-service DB access: $f"; done else pass "No cross-service database access detected" fi # ARCH-003: No Hardcoded Tenant/Environment Config echo "▸ ARCH-003: No Hardcoded Tenant/Environment Config" HARDCODED=$(find "$REPO" -type f \( -name '*.java' -o -name '*.go' -o -name '*.ts' -o -name '*.py' \) ! -path '*/test/*' -exec grep -Pln 'https?://(prod|staging|dev)\.\w+\.(com|net|io)|\.equals\("(acme|tenant|customer)-' {} \; 2>/dev/null || true) if [[ -n "$HARDCODED" ]]; then for f in $HARDCODED; do fail "Hardcoded tenant/environment config: $f"; done else pass "No hardcoded tenant/environment configuration" fi echo "" # ── DEVOPS ── echo -e "${CYAN}DevOps${NC}" # OPS-001: Foxtrot-Compatible Helm Chart (no custom ingress) echo "▸ OPS-001: No Custom Ingress (Foxtrot Routing)" CUSTOM_INGRESS=$(find "$REPO" -name '*.yaml' -o -name '*.yml' | xargs grep -l 'kind: Ingress' 2>/dev/null || true) if [[ -n "$CUSTOM_INGRESS" ]]; then for f in $CUSTOM_INGRESS; do fail "Custom Ingress resource (Foxtrot manages routing): $f"; done else pass "No custom Ingress definitions" fi # OPS-002: No Infrastructure Provisioning in Service Repos echo "▸ OPS-002: No Infrastructure in Service Repos" INFRA_FILES=$(find "$REPO" -name '*.tf' -o -name 'Pulumi.*' | grep -v '.terraform' 2>/dev/null || true) CFN_FILES=$(find "$REPO" -name '*.template.yaml' -o -name '*.template.json' | xargs grep -l 'AWSTemplateFormatVersion\|AWS::' 2>/dev/null || true) if [[ -n "$INFRA_FILES" ]]; then for f in $INFRA_FILES; do fail "Infrastructure-as-code in service repo: $f"; done fi if [[ -n "$CFN_FILES" ]]; then for f in $CFN_FILES; do fail "CloudFormation template in service repo: $f"; done fi if [[ -z "$INFRA_FILES" && -z "$CFN_FILES" ]]; then pass "No infrastructure provisioning files" fi # OPS-004: No Pinned Infrastructure Versions echo "▸ OPS-004: No Pinned Infrastructure Versions" PINNED=$(find "$REPO" -name '*.yaml' -o -name '*.yml' | xargs grep -Pn 'image:\s*(postgres|mysql|redis|mongo|elasticsearch|kafka|rabbitmq|zookeeper):\d' 2>/dev/null || true) if [[ -n "$PINNED" ]]; then echo "$PINNED" | while read -r line; do fail "Pinned infra version: $line"; done else pass "No pinned infrastructure image versions" fi echo "" # ── COST ── echo -e "${CYAN}Cost${NC}" # COST-001: Resource Tagging echo "▸ COST-001: Resource Tagging" TF_RESOURCES=$(find "$REPO" -name '*.tf' -exec grep -l 'resource\s' {} \; 2>/dev/null || true) for f in $TF_RESOURCES; do if ! grep -q 'tags' "$f"; then warn "Terraform resource without tags: $f" fi done if [[ -z "$TF_RESOURCES" ]]; then pass "No Terraform resources in scope"; fi echo "" echo "═══════════════════════════════════════" if [[ $VIOLATIONS -gt 0 ]]; then echo -e " Result: ${RED}FAIL${NC} — $VIOLATIONS violation(s), $WARNINGS warning(s)" exit 1 elif [[ $WARNINGS -gt 0 ]]; then echo -e " Result: ${YELLOW}WARN${NC} — $WARNINGS warning(s)" exit 0 else echo -e " Result: ${GREEN}PASS${NC} — all checks passed" exit 0 fi