- Add complete agent harness structure with 8 roles (leader, triager, architect, implementer, reviewer, security, qa, documenter) - Implement strict workflow with 9 stages and mandatory gates - Add comprehensive verification script and runtime status tracking - Create artifact-based evidence system with contracts and schemas - Add agent policy matrix with permissions and anti-cheat rules - Include test suite (44 tests passing) and CI-ready structure - Add documentation: README, HOWTO, CHECKPOINTS, templates - Configure model routing policies and token-aware task assignment - Add BDD/SDD specification guides and feature templates - Include starter pack for quick project onboarding All verification checks pass. Framework ready for production use.
83 lines
2.5 KiB
Markdown
83 lines
2.5 KiB
Markdown
# ADR-003: Hashing de Contraseñas
|
||
|
||
## Estado
|
||
Aceptado
|
||
|
||
## Fecha
|
||
2026-05-06
|
||
|
||
## Contexto
|
||
Necesitamos guardar contraseñas de usuarios de forma segura. La decisión debe considerar:
|
||
- Resistencia a ataques de fuerza bruta y rainbow tables
|
||
- Performance (se ejecuta en cada login y cambio de password)
|
||
- Compatibilidad con estándares de la industria
|
||
|
||
## Decisión
|
||
Usar **bcrypt** con cost factor 12 para hashing de contraseñas.
|
||
|
||
## Justificación
|
||
1. **bcrypt** es diseñado específicamente para password hashing lento
|
||
2. **Cost factor configurable**: permite aumentar resistencia en el futuro
|
||
3. **Resistente a GPU/rainbow attacks**: diseñado para ser lento intencionalmente
|
||
4. **Incorpora salt**: cada password tiene salt único, evitando rainbow tables
|
||
5. **Estándar de industria**: ampliamente usado (Django, Rails, bcrypt)
|
||
|
||
## Consecuencias
|
||
|
||
### ✅ Positivas
|
||
- Resistente a ataques de fuerza bruta
|
||
- Salt automático evitar rainbow tables
|
||
- Configurable (cost factor)
|
||
- Librerías maduras en todos los lenguajes
|
||
|
||
### ❌ Negativas
|
||
- Más lento que MD5/SHA (es el punto, pero afecta latency)
|
||
- Enorme payload si se guarda en cookies/token
|
||
|
||
### 🔄 Neutrales
|
||
- Requiere Python 3.11+ para bcrypt moderno
|
||
|
||
## Implementación
|
||
|
||
```python
|
||
import bcrypt
|
||
|
||
def hash_password(password: str) -> str:
|
||
"""Hash password with bcrypt, cost 12."""
|
||
return bcrypt.hashpw(
|
||
password.encode('utf-8'),
|
||
bcrypt.gensalt(rounds=12)
|
||
).decode('utf-8')
|
||
|
||
def verify_password(password: str, hashed: str) -> bool:
|
||
"""Verify password using constant-time comparison."""
|
||
return bcrypt.checkpw(
|
||
password.encode('utf-8'),
|
||
hashed.encode('utf-8')
|
||
)
|
||
```
|
||
|
||
## Alternativas Consideradas
|
||
|
||
### Opción A: SHA-256 (con salt)
|
||
- **Pros**: Rápido, simple
|
||
- **Contras**: No es lento, vulnerable a GPU attacks, diseñado para speed no security
|
||
- **Razón de descarte**: No es resistente a hardware moderno
|
||
|
||
### Opción B: Argon2
|
||
- **Pros**: Ganador PHC 2015, configurable memory/CPU
|
||
- **Contras**: Más complejo de implementar, menos soporte de librerías
|
||
- **Razón de descarte**: bcrypt es más simple y suficiente para nuestro caso de uso
|
||
|
||
### Opción C: scrypt
|
||
- **Pros**: Diseñado para ser memory-hard
|
||
- **Contras**: Más lento de configurar, configuración compleja
|
||
- **Razón de descarte**: bcrypt es más simple y ampliamente soportado
|
||
|
||
## Notas
|
||
- Si en el futuro,我们需要 mayor seguridad, migrar a Argon2
|
||
- No guardar passwords en logs bajo ninguna circunstancia
|
||
|
||
## Relacionado con
|
||
- Feature F-003
|
||
- Componente: PasswordService |