name: Edu-Space Automated Security Audit (Gitea Local) on: push: branches: [ main, develop ] pull_request: branches: [ main, develop ] jobs: security-scan: # Usamos la etiqueta estándar para contenedores Ubuntu en Gitea Runner runs-on: ubuntu-latest steps: # 1. Clonar el código del repositorio local - name: Checkout Code uses: actions/checkout@v4 # 2. Preparar el entorno de paquetes del sistema (Linux) - name: Install System Dependencies (Python & Node.js) run: | apt-get update && apt-get install -y python3 python3-pip python3-venv nodejs npm curl python3 -m pip install --upgrade pip # 3. Instalar librerías de Python y herramientas de seguridad - name: Install Python Dependencies & Security Tools run: | pip3 install -r backend/requirements.txt pip3 install -r backend/requirements-dev.txt # 4. Instalar librerías de Node.js (Express BFF) - name: Install Node.js Dependencies run: | cd frontend npm ci # --- EJECUCIÓN DE CONTROLES (SAST & SCA) --- - name: [1/5] Python SAST (Bandit) run: bandit -r ./backend/app -ll -ii - name: [2/5] Python SCA (Pip-Audit) run: pip-audit -s osv --progress-spinner off -r backend/requirements.txt - name: [3/5] Node.js SAST (Njsscan) run: njsscan ./frontend/src - name: [4/5] Node.js SCA (Npm Audit) run: | cd frontend npm audit --audit-level=high # --- CONTROL DINÁMICO DAST (Schemathesis) --- - name: [5/5] Start Flask App & Run DAST (Schemathesis) env: PYTHONUTF8: 1 FLASK_APP: backend/app # Ajustar a la ruta de inicio de tu Flask si varía run: | # Levantar Flask en segundo plano dentro del contenedor local # Usamos 'python3 -m flask run' para asegurar el bindeo local cd backend python3 -m flask run --host=127.0.0.1 --port=5000 & # Esperar 5 segundos a que la API responda echo "Esperando a que el backend de Flask inicie en el entorno local..." sleep 5 # Verificar con un curl rápido si el JSON de OpenAPI está disponible curl -s http://127.0.0.1:5000/api/v1/openapi.json > /dev/null # Ejecutar Schemathesis contra la instancia local efímera schemathesis run http://127.0.0.1:5000/api/v1/openapi.json --checks not_a_server_error --max-examples=10