DevSecOps i CI/CD
Tipus: Document d'Arquitectura
Versió: 1.0
Actualitzat: 2024-12
Estat: Normatiu
Resum
Aquest document defineix l'estratègia DevSecOps per a LDP. Cobreix:
- Checks de seguretat al pipeline CI/CD
- Anàlisi estàtic (SAST)
- Dependency scanning
- Secrets management
- Configuració d'entorns
1. Principis DevSecOps
1.1. Shift Left Security
Tradicional:
Dev → Test → Staging → Security Review → Production
↑
(Massa tard, molt costós)
DevSecOps:
Dev + Security → Test + Security → Staging → Production
↑ ↑
(Detecció primerenca = Menys cost)
1.2. Automatització Obligatòria
| Check | Execució | Bloqueja PR? |
|---|---|---|
| Linting | Cada commit | ⚠️ Warning |
| SAST | Cada PR | ✅ Si HIGH/CRITICAL |
| Dependency check | Cada PR | ✅ Si HIGH/CRITICAL |
| Secrets scan | Cada commit | ✅ Sempre |
| Tests de seguretat | Nightly | ✅ Si falla |
2. Pipeline CI Recomanat
2.1. Estructura
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
jobs:
# 1. Checks ràpids (< 2 min)
quick-checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Secrets scan
- name: Detect secrets
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: ${{ github.event.pull_request.base.sha }}
head: ${{ github.sha }}
# Linting
- name: Lint Backend
run: ./mvnw -B checkstyle:check
working-directory: backend
- name: Lint Frontend
run: npm run lint
working-directory: frontend
# 2. Security checks (paral·lel)
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# SAST amb CodeQL
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: java, javascript
- name: Build for analysis
run: ./mvnw -B compile -DskipTests
working-directory: backend
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
# Dependency check
- name: OWASP Dependency Check
uses: dependency-check/Dependency-Check_Action@main
with:
project: 'line-dance-platform'
path: '.'
format: 'HTML'
args: >-
--failOnCVSS 7
--enableRetired
# 3. Tests
test:
runs-on: ubuntu-latest
needs: quick-checks
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Run tests
run: ./mvnw -B verify
working-directory: backend
- name: Upload coverage
uses: codecov/codecov-action@v4
# 4. Build i Push (només main)
build:
runs-on: ubuntu-latest
needs: [security, test]
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t linedance/backend:${{ github.sha }} ./backend
# Push a registry (quan tinguem)
2.2. Checks Pre-commit (Local)
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-json
- id: detect-private-key
- id: detect-aws-credentials
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.0
hooks:
- id: gitleaks
- repo: local
hooks:
- id: no-todos-in-security
name: No TODOs in security code
entry: bash -c 'grep -rn "TODO\|FIXME" backend/src/main/java/*/security/ && exit 1 || exit 0'
language: system
pass_filenames: false
3. Anàlisi Estàtic (SAST)
3.1. Eines Recomanades
| Eina | Llenguatge | Cost | Integració |
|---|---|---|---|
| CodeQL | Java, JS/TS | Gratis (OSS) | GitHub Actions |
| SpotBugs | Java | Gratis | Maven plugin |
| Semgrep | Multi | Gratis (bàsic) | CLI, CI |
| ESLint Security | JS/TS | Gratis | npm |
3.2. Configuració SpotBugs
<!-- backend/pom.xml -->
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>4.8.3.0</version>
<configuration>
<effort>Max</effort>
<threshold>Medium</threshold>
<failOnError>true</failOnError>
<plugins>
<plugin>
<groupId>com.h3xstream.findsecbugs</groupId>
<artifactId>findsecbugs-plugin</artifactId>
<version>1.12.0</version>
</plugin>
</plugins>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
3.3. ESLint Security (Frontend)
// frontend/eslint.config.js
import security from 'eslint-plugin-security';
export default [
// ... altres configs
{
plugins: {
security,
},
rules: {
'security/detect-eval-with-expression': 'error',
'security/detect-non-literal-regexp': 'warn',
'security/detect-object-injection': 'warn',
'security/detect-possible-timing-attacks': 'warn',
},
},
];
4. Dependency Scanning
4.1. OWASP Dependency-Check
<!-- backend/pom.xml -->
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>9.0.7</version>
<configuration>
<failBuildOnCVSS>7</failBuildOnCVSS>
<formats>
<format>HTML</format>
<format>JSON</format>
</formats>
<suppressionFiles>
<suppressionFile>dependency-check-suppressions.xml</suppressionFile>
</suppressionFiles>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
4.2. Supressió de Falsos Positius
<!-- dependency-check-suppressions.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.3.xsd">
<!-- Exemple: fals positiu confirmat -->
<suppress>
<notes>
CVE-2024-XXXX no ens afecta perquè no usem la feature X.
Revisat per: @developer el 2024-12-15
</notes>
<packageUrl regex="true">^pkg:maven/org\.example/lib@.*$</packageUrl>
<cve>CVE-2024-XXXX</cve>
</suppress>
</suppressions>
4.3. npm audit (Frontend)
# Part del CI
- name: Check npm vulnerabilities
run: |
npm audit --audit-level=high
working-directory: frontend
4.4. Dependabot/Renovate
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "maven"
directory: "/backend"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
reviewers:
- "security-team"
labels:
- "dependencies"
- "security"
- package-ecosystem: "npm"
directory: "/frontend"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
5. Gestió de Secrets
5.1. Regla Fonamental
Mai Secrets al Codi
- ❌ No hardcodejar passwords, tokens, API keys
- ❌ No a application.properties (valors reals)
- ❌ No a docker-compose.yml
- ❌ No a comentaris ni logs
5.2. Fonts de Secrets per Entorn
| Entorn | Font de Secrets | Exemple |
|---|---|---|
| Local | .env (gitignored) | .env.local |
| CI | GitHub Secrets | ${{ secrets.DB_PASSWORD }} |
| Staging/Prod | Azure Key Vault / AWS Secrets Manager | Spring Cloud Azure |
5.3. Configuració Spring Boot
# application.yml - Valors per defecte o placeholders
spring:
datasource:
url: ${DB_URL:jdbc:postgresql://localhost:5432/linedance}
username: ${DB_USERNAME:linedance}
password: ${DB_PASSWORD} # Sense default!
jwt:
secret: ${JWT_SECRET} # Obligatori
access-token-expiration: ${JWT_ACCESS_EXPIRATION:900000} # 15 min default
refresh-token-expiration: ${JWT_REFRESH_EXPIRATION:604800000} # 7 dies default
# .env.local (gitignored)
DB_URL=jdbc:postgresql://localhost:5432/linedance_dev
DB_USERNAME=linedance
DB_PASSWORD=local_dev_password_123
JWT_SECRET=local-development-secret-key-min-32-chars!
5.4. Detecció de Secrets
# Gitleaks config
# .gitleaks.toml
[extend]
useDefault = true
[[rules]]
id = "jwt-secret"
description = "Potential JWT secret"
regex = '''(?i)(jwt|token).*[=:]\s*['"]?[a-zA-Z0-9+/=]{32,}['"]?'''
keywords = ["jwt", "token", "secret"]
[[rules]]
id = "spring-datasource-password"
description = "Spring datasource password"
regex = '''spring\.datasource\.password\s*=\s*[^\$\{]'''
keywords = ["datasource", "password"]
6. Entorns i Configuració
6.1. Matriu d'Entorns
| Entorn | Base de Dades | Secrets | Logs | Debug |
|---|---|---|---|---|
| Local | PostgreSQL local | .env | Console | ✅ |
| CI | H2 / Testcontainers | GitHub Secrets | File | ❌ |
| Staging | PostgreSQL (Azure) | Key Vault | CloudWatch | ⚠️ |
| Production | PostgreSQL (Azure) | Key Vault | CloudWatch | ❌ |
6.2. Profiles Spring Boot
# application-dev.yml
spring:
jpa:
show-sql: true
logging:
level:
com.linedance: DEBUG
---
# application-prod.yml
spring:
jpa:
show-sql: false
logging:
level:
com.linedance: INFO
org.springframework.security: WARN
6.3. Segregació de Configuració
backend/src/main/resources/
├── application.yml # Configuració comuna
├── application-dev.yml # Només desenvolupament
├── application-test.yml # Tests
├── application-staging.yml # Staging (gitignored si té secrets)
└── application-prod.yml # Producció (gitignored si té secrets)
7. Auditoria de Canvis de Codi
7.1. Branch Protection
# Configuració GitHub Branch Protection (via settings o API)
branches:
main:
required_pull_request_reviews:
required_approving_review_count: 1
dismiss_stale_reviews: true
require_code_owner_reviews: true
required_status_checks:
strict: true
contexts:
- security
- test
restrictions:
users: []
teams: ["maintainers"]
7.2. CODEOWNERS
# .github/CODEOWNERS
# Canvis de seguretat requereixen revisió específica
/backend/src/main/java/*/security/ @security-lead
/backend/src/main/java/*/config/Security* @security-lead
/docs-web/docs/security/ @security-lead
*.yml @devops-team
8. Compliance i Reporting
8.1. Reports Automàtics
# Part del workflow CI
- name: Generate security report
run: |
mkdir -p reports
# OWASP report
cp backend/target/dependency-check-report.html reports/
# SpotBugs report
cp backend/target/spotbugs/spotbugs.html reports/ || true
# CodeQL (via GitHub Security tab)
- name: Upload reports
uses: actions/upload-artifact@v4
with:
name: security-reports
path: reports/
retention-days: 30
8.2. Dashboard de Seguretat
GitHub Security tab mostra automàticament:
- Dependabot alerts
- Code scanning (CodeQL)
- Secret scanning
9. Resposta a Incidents
9.1. Procés CVE Nou
flowchart TD
A[CVE detectat] --> B{Afecta LDP?}
B -->|No| C[Suprimir amb justificació]
B -->|Sí| D{Severitat?}
D -->|Critical/High| E[Hotfix immediat]
D -->|Medium| F[Planificar sprint actual]
D -->|Low| G[Afegir a backlog]
E --> H[Actualitzar dependència]
H --> I[Tests]
I --> J[Deploy urgent]
9.2. Comunicació
| Severitat | Acció | SLA |
|---|---|---|
| CRITICAL | Notificar equip immediatament | 4h per mitigar |
| HIGH | Issue prioritari | 24h per planificar |
| MEDIUM | Issue normal | 1 setmana |
| LOW | Backlog | Proper sprint |
10. Checklist DevSecOps
Configuració Inicial
- [ ] Pre-commit hooks configurats
- [ ] CI pipeline amb security checks
- [ ] SAST (CodeQL/SpotBugs) configurat
- [ ] Dependency check configurat
- [ ] Secrets scanning actiu
- [ ] Branch protection activada
- [ ] CODEOWNERS definit
Per Cada PR
- [ ] Security checks passen
- [ ] No secrets detectats
- [ ] No CVEs HIGH/CRITICAL nous
- [ ] Revisat per CODEOWNER (si aplica)
Mensualment
- [ ] Revisar Dependabot alerts
- [ ] Actualitzar dependencies amb CVEs
- [ ] Revisar supprssions de CVEs
- [ ] Revisar logs d'accessos sospitosos
11. Referències
- OWASP DevSecOps Guidelines
- GitHub Security Features
- CodeQL Documentation
- Gitleaks
- OWASP Dependency-Check
Historial de Canvis
| Data | Versió | Canvis |
|---|---|---|
| 2024-12 | 1.0 | Document inicial |