Initial commit: VoIdeaAI - voice-first AI idea assistant
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
# Безопасность
|
||||
|
||||
## Базовые требования
|
||||
|
||||
- `.env` — всегда в `.gitignore`. Никогда не коммитить.
|
||||
- JWT: алгоритм HS256, access_token = 60 минут, refresh_token = 30 дней
|
||||
- Пароли: bcrypt через passlib
|
||||
- Pydantic валидация на всех входах
|
||||
- RBAC: роли user, admin
|
||||
|
||||
---
|
||||
|
||||
## Аутентификация
|
||||
|
||||
### JWT
|
||||
|
||||
```python
|
||||
# app/core/security.py
|
||||
|
||||
def create_access_token(data: dict, expires_delta: timedelta | None = None) -> str:
|
||||
to_encode = data.copy()
|
||||
expire = datetime.now(timezone.utc) + (expires_delta or timedelta(minutes=60))
|
||||
to_encode.update({"exp": expire, "type": "access"})
|
||||
return jwt.encode(to_encode, settings.jwt_secret_key, algorithm=settings.jwt_algorithm)
|
||||
|
||||
def decode_token(token: str) -> dict[str, Any] | None:
|
||||
try:
|
||||
return jwt.decode(token, settings.jwt_secret_key, algorithms=[settings.jwt_algorithm])
|
||||
except JWTError:
|
||||
return None
|
||||
```
|
||||
|
||||
### Password hashing
|
||||
|
||||
```python
|
||||
from passlib.context import CryptContext
|
||||
|
||||
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
||||
|
||||
def hash_password(password: str) -> str:
|
||||
return pwd_context.hash(password)
|
||||
|
||||
def verify_password(plain: str, hashed: str) -> bool:
|
||||
return pwd_context.verify(plain, hashed)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## RBAC
|
||||
|
||||
| Роль | Права |
|
||||
|------|-------|
|
||||
| user | Базовые: CRUD своих данных, запуск анализа |
|
||||
| admin (is_superuser) | Управление пользователями, просмотр логов, системные настройки |
|
||||
|
||||
Проверка прав:
|
||||
```python
|
||||
async def require_admin(user: Annotated[User, Depends(get_current_user)]) -> User:
|
||||
if not user.is_superuser:
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Admin access required")
|
||||
return user
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Sensitive Data
|
||||
|
||||
**Никогда не логировать:**
|
||||
- Пароли (даже хэш)
|
||||
- JWT токены
|
||||
- API keys и секреты
|
||||
- Email в открытом виде (только user_id)
|
||||
|
||||
**Маскировать в логах:**
|
||||
- Email: u***@mail.ru
|
||||
- IP: 195.208.*.*
|
||||
|
||||
---
|
||||
|
||||
## [ASK] Вопросы по безопасности
|
||||
|
||||
- Нужен ли audit log? (рекомендуется для production)
|
||||
- Нужно ли шифрование данных в покое? (да, если хранятся персональные данные)
|
||||
- Нужен ли rate limiting? (да, для production)
|
||||
- Нужен ли CORS? (да, если фронтенд на другом домене)
|
||||
- Нужен ли CSRF? (нет, если используем JWT в Bearer header)
|
||||
Reference in New Issue
Block a user