This document outlines security best practices and guidelines for the InvernaderosAPI project.
CRITICAL: Never commit any of the following to version control:
- ❌ Passwords
- ❌ API keys
- ❌ Access tokens
- ❌ Private SSH keys
- ❌ Database credentials
- ❌ MQTT credentials
- ❌ Redis passwords
- ❌ Any other secrets
The following files are protected by .gitignore and should NEVER be committed:
.env.env.local.env.*.localapplication-local.yamldocker-compose.override.yaml*.key*.pem*.p12*.jkssecrets/credentials/
-
Copy the example environment file:
cp .env.example .env
-
Edit
.envand set your local credentials:# Generate secure passwords openssl rand -base64 32 -
Set all required variables in the
.envfile (see.env.examplefor template)
NEVER use plaintext environment variables in production!
Use a secure secret management solution:
Example Kubernetes secret configuration:
apiVersion: v1
kind: Secret
metadata:
name: invernaderos-api-secret
namespace: apptolast-invernadero-api-prod
type: Opaque
stringData:
TIMESCALE_PASSWORD: "your-secure-password"
METADATA_PASSWORD: "your-secure-password"
REDIS_PASSWORD: "your-secure-password"
MQTT_USERNAME: "your-username"
MQTT_PASSWORD: "your-secure-password"Apply the secret:
kubectl apply -f secret.yamlIMPORTANT: Do not commit secret.yaml to the repository. Manage it separately or use tools like Sealed Secrets.
Esta guía explica cómo gestionar de forma segura las credenciales y secretos en el proyecto Invernaderos API.
- ❌ Hardcodear credenciales en código fuente
- ❌ Subir archivos
.enval repositorio - ❌ Compartir contraseñas en issues, pull requests o comentarios
- ❌ Usar contraseñas débiles o por defecto
- ❌ Reutilizar contraseñas entre entornos
- ❌ Documentar credenciales reales en archivos README o DEPLOYMENT
- ✅ Usar variables de entorno para credenciales
- ✅ Mantener archivos
.enven.gitignore - ✅ Usar contraseñas seguras y únicas
- ✅ Rotar credenciales regularmente
- ✅ Usar gestores de secretos en producción
- ✅ Documentar el formato requerido, no los valores reales
-
Copiar archivos de ejemplo:
cp .env.example .env cp docker-compose.override.yaml.example docker-compose.override.yaml cp application-local.yaml.example application-local.yaml
-
Editar
.envcon tus credenciales:# Edita el archivo y establece contraseñas seguras nano .env # o tu editor preferido
-
Generar contraseñas seguras:
# Opción 1: usar openssl openssl rand -base64 32 # Opción 2: usar pwgen pwgen -s 32 1 # Opción 3: usar Python python3 -c "import secrets; print(secrets.token_urlsafe(32))"
-
Verificar que
.envestá en .gitignore:git status # .env NO debe aparecer en la lista
Usar Kubernetes Secrets para gestionar credenciales:
apiVersion: v1
kind: Secret
metadata:
name: invernaderos-api-secret
type: Opaque
data:
postgres-password: <base64-encoded-value>
redis-password: <base64-encoded-value>
mqtt-password: <base64-encoded-value>aws secretsmanager create-secret \
--name invernaderos-api/database \
--secret-string '{"password":"your-secure-password"}'vault kv put secret/invernaderos-api/database \
password="your-secure-password"az keyvault secret set \
--vault-name invernaderos-vault \
--name database-password \
--value "your-secure-password"For production environments, use passwords that meet these criteria:
- ✅ Minimum 16 characters
- ✅ Mix of uppercase, lowercase, numbers, and special characters
- ✅ Generated using cryptographically secure random generator
- ✅ Unique for each service/environment
- ✅ Rotated regularly (every 90 days recommended)
# Generate a 32-character base64 password
openssl rand -base64 32
# Generate a 24-character alphanumeric password
openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 24
# Generate using pwgen (install first: apt-get install pwgen)
pwgen -s 32 1- Schedule: Rotate credentials every 90 days minimum
- Process:
- Generate new credentials
- Update in secret manager
- Update application configuration
- Restart services
- Revoke old credentials
- Monitor for any failures
-
Use separate credentials for each environment
- Development:
greenhouse_timeseries_dev,greenhouse_metadata_dev - Production:
greenhouse_timeseries,greenhouse_metadata
- Development:
-
Principle of Least Privilege
- Grant only necessary permissions
- Use read-only users for analytics
- Create separate users for migrations
-
Connection Security
- Use SSL/TLS for database connections in production
- Configure
spring.datasource.hikari.connection-test-query - Set appropriate timeout values
-
Authentication:
- Use unique credentials per client
- Implement ACL (Access Control Lists)
- Use client certificates in production
-
Connection Security:
- Use TLS/SSL (port 8883) instead of plain TCP (port 1883)
- Use WSS (WebSocket Secure) for browser clients
- Configure proper cipher suites
-
EMQX Configuration:
# In production, enable authentication plugin authentication: - mechanism: password_based backend: postgresql # Enable ACL authorization: sources: - type: postgresql
-
Authentication:
- Always set a strong password
- Use ACL for fine-grained access control (Redis 6+)
-
Network Security:
- Bind to localhost or private network only
- Use TLS for connections
- Configure firewall rules
-
Configuration:
# redis.conf requirepass <strong-password> bind 127.0.0.1 ::1 protected-mode yes
-
Scan for secrets:
# Install git-secrets git secrets --scan # Install truffleHog trufflehog git file://. --only-verified
-
Check for exposed credentials:
grep -r "password\|secret\|key\|token" . --exclude-dir=.git --exclude-dir=node_modules
The project uses:
- CodeQL - Automated security scanning in CI/CD
- Dependabot - Dependency vulnerability scanning
- GitHub Secret Scanning - Detects committed secrets
If you accidentally commit credentials:
- Immediately rotate the exposed credentials
- Remove from git history:
# Use BFG Repo-Cleaner or git-filter-branch bfg --replace-text passwords.txt git reflog expire --expire=now --all git gc --prune=now --aggressive - Force push to remote (coordinate with team):
git push --force --all
- Notify the team
- Check logs for unauthorized access
- Document the incident
Before deploying:
- All credentials are stored in secret managers
- No plaintext passwords in code or configuration
-
.envfile is in.gitignore - Strong passwords are used (16+ characters)
- Credentials are unique per environment
- SSL/TLS is enabled for all connections
- Firewall rules are properly configured
- Security scanning is enabled
- Logs don't contain sensitive information
- Monitoring and alerting are configured
If you discover a security vulnerability:
- DO NOT create a public GitHub issue
- Report via GitHub Security Advisories
- Alternatively, email the security team at: [email protected]
- Provide detailed information about the vulnerability
- Allow time for the issue to be fixed before public disclosure
Last Updated: 2024-11-11 Version: 1.0.0
Para aplicaciones en AWS:
# Crear secret
aws secretsmanager create-secret \
--name invernaderos/production/database \
--secret-string '{"password":"tu-password-seguro"}'
# Leer secret en la aplicación
aws secretsmanager get-secret-value \
--secret-id invernaderos/production/databasePara aplicaciones en Azure:
# Crear secret
az keyvault secret set \
--vault-name invernaderos-keyvault \
--name database-password \
--value "tu-password-seguro"
# Leer secret
az keyvault secret show \
--vault-name invernaderos-keyvault \
--name database-password.env
.env.local
.env.*.local
application-local.yaml
docker-compose.override.yaml
*.key
*.pem
*.p12
*.jks
secrets/
credentials/
.env.example
application-local.yaml.example
docker-compose.override.yaml.example
Estos archivos contienen la estructura pero SIN valores reales.
-
Inmediatamente:
- Si se exponen en el repositorio
- Si se detecta un acceso no autorizado
- Si un empleado deja el equipo
-
Periódicamente:
- Cada 90 días para producción
- Cada 180 días para desarrollo
- Generar nuevas credenciales
- Actualizar en el gestor de secretos
- Reiniciar servicios que usan las credenciales
- Verificar que todo funciona
- Revocar credenciales antiguas
- Documentar el cambio (sin incluir las credenciales)
# Contraseña segura (mínimo 16 caracteres)
TIMESCALE_PASSWORD=$(openssl rand -base64 24)
METADATA_PASSWORD=$(openssl rand -base64 24)
# Diferentes contraseñas por entorno
# DEV: TIMESCALE_PASSWORD=dev_password_xxx
# PROD: TIMESCALE_PASSWORD=prod_password_yyy# Contraseña segura
REDIS_PASSWORD=$(openssl rand -base64 24)
# Configurar ACL para mayor seguridad
# redis-cli ACL SETUSER api_user on >password ~* +@all# Usuario y contraseña específicos
MQTT_USERNAME="api_user_$(date +%s)"
MQTT_PASSWORD=$(openssl rand -base64 24)
# Usar diferentes usuarios por servicio/componente-
git-secrets - Previene commits con secretos
git secrets --install git secrets --register-aws
-
truffleHog - Busca secretos en el historial
trufflehog git https://github.com/apptolast/InvernaderosAPI
-
gitleaks - Escaneo rápido de secretos
gitleaks detect --source . --verbose -
GitHub Secret Scanning - Automático en repositorios públicos
# Crear un pre-commit hook básico
# Nota: Este es un ejemplo simple. Para mayor seguridad, use herramientas como git-secrets o gitleaks.
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
# Obtiene la lista de archivos staged, excluyendo archivos .example
files=$(git diff --cached --name-only | grep -v '\.example$')
# Busca palabras clave en los archivos filtrados
if [ -n "$files" ]; then
if echo "$files" | xargs grep -IinE "password|secret|key|token" 2>/dev/null | grep -v "^[[:space:]]*#"; then
echo "⚠️ Posible credencial detectada en commit"
echo "Verifica que no estés subiendo información sensible"
exit 1
fi
fi
EOF
chmod +x .git/hooks/pre-commitNota: Este hook es solo un ejemplo básico que puede generar falsos positivos. Para una solución más robusta, considere usar herramientas especializadas como git-secrets, truffleHog o gitleaks que están diseñadas específicamente para detectar credenciales.
-
Inmediato (< 1 hora):
- ✅ Revocar/cambiar todas las credenciales expuestas
- ✅ Verificar accesos no autorizados
- ✅ Notificar al equipo
-
Corto plazo (< 24 horas):
- ✅ Eliminar credenciales del código
- ✅ Hacer commit y push de los cambios
- ✅ Revisar logs de acceso
- ✅ Documentar el incidente
-
Mediano plazo (< 1 semana):
- ✅ Limpiar historial de git (si es necesario)
- ✅ Implementar controles adicionales
- ✅ Actualizar documentación de seguridad
- ✅ Capacitar al equipo
# CUIDADO: Esto reescribe el historial
# Solo usar en coordinación con el equipo
# Usar BFG Repo-Cleaner
java -jar bfg.jar --replace-text passwords.txt
# O usar git filter-branch (más manual)
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch path/to/secret/file" \
--prune-empty --tag-name-filter cat -- --allAntes de hacer commit:
- No hay contraseñas hardcodeadas en el código
- Archivo
.envestá en.gitignorey no se sube - Variables de entorno usadas en lugar de valores literales
- Archivos
.exampleno contienen credenciales reales - Documentación no expone credenciales
- Pre-commit hooks instalados
Antes de desplegar:
- Credenciales rotadas desde último despliegue (si aplica)
- Contraseñas únicas por entorno
- Gestor de secretos configurado (producción)
- Logs no exponen credenciales
- Conexiones usan TLS/SSL
- Principio de menor privilegio aplicado
Si tienes dudas sobre gestión de credenciales:
- Consulta esta guía
- Revisa los archivos
.example - Pregunta en el canal de seguridad del equipo
- NO expongas credenciales reales al pedir ayuda
Última actualización: 2025-11-11
Revisión: v1.0