← Назад к вопросам

Как хранить чувствительные данные в проекте?

1.3 Junior🔥 271 комментариев
#DevOps и инфраструктура#Безопасность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Хранение чувствительных данных в проекте

Чувствительные данные (пароли, API ключи, токены, строки подключения БД) должны быть тщательно защищены. Их никогда не коммитят в репозиторий, не сохраняют в коде и не логируют.

1. Environment переменные (основной подход)

Хранить секреты в переменных окружения — стандарт индустрии:

import os
from dotenv import load_dotenv

load_dotenv()

DATABASE_URL = os.getenv("DATABASE_URL")
API_KEY = os.getenv("API_KEY")
SECRET_KEY = os.getenv("SECRET_KEY")

if not API_KEY:
    raise ValueError("API_KEY не установлена в окружении!")

.env файл:

DATABASE_URL=postgresql://user:pass@localhost/db
API_KEY=sk_live_abc123xyz
SECRET_KEY=dev-secret-key
DEBUG=true

2. Pydantic Settings (рекомендуется)

from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    database_url: str
    api_key: str
    api_secret: str
    debug: bool = False
    secret_key: str
    
    class Config:
        env_file = ".env"
        case_sensitive = False

settings = Settings()
print(settings.database_url)

3. Vault для production

AWS Secrets Manager:

import boto3
import json

def get_secret(secret_name: str) -> dict:
    client = boto3.client("secretsmanager", region_name="us-east-1")
    response = client.get_secret_value(SecretId=secret_name)
    return json.loads(response["SecretString"])

secrets = get_secret("prod/database")
db_url = secrets["connection_string"]

HashiCorp Vault:

import hvac

client = hvac.Client(url="https://vault.example.com", token="s.token")
secrets = client.secrets.kv.read_secret_version(path="secret/database")
db_url = secrets["data"]["data"]["url"]

4. Защита в коде

Никогда не логируй секреты:

# ПЛОХО
logger.info(f"Подключаюсь к БД: {db_url}")

# ХОРОШО
logger.info("Подключаюсь к БД")

Маскируй чувствительные данные:

import re

def mask_secrets(text: str) -> str:
    text = re.sub(r"api[_-]?key[=:]\\s*[^\\s]+", "api_key=[MASKED]", text, flags=re.I)
    text = re.sub(r"://([^:]+):([^@]+)@", r"://\\1:[MASKED]@", text)
    return text

error_msg = mask_secrets(f"DB error: {db_url}")
logger.error(error_msg)

5. Хеширование паролей

import bcrypt
from passlib.context import CryptContext

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
hashed = pwd_context.hash("password123")

if pwd_context.verify("password123", hashed):
    print("Пароль верный!")

6. Структура проекта

my_project/
├── .env                 # НЕ коммитить!
├── .env.example         # Коммитить (шаблон)
├── .gitignore
├── config.py
└── app/

.gitignore:

.env
.env.local
.env.*.local
*.key
*.pem

7. Чеклист безопасности

Перед production:

  • Все секреты в переменных окружения
  • .env и *.key в .gitignore
  • Нет hardcoded паролей в коде
  • Логирование не содержит секретов
  • HTTPS для всех запросов
  • Пароли пользователей хешированы (bcrypt/argon2)
  • Разные ключи для разработки и production
  • Ротация ключей регулярно
  • Аудит доступа
  • Шифрование данных если необходимо

Это один из критических аспектов безопасности приложения!