The post has been translated automatically. Original language: Russian
Technical debt is discussed either as a disaster or as something that will be thought about later. Both are incorrect. Debt is a normal tool: you take speed now in exchange for additional work later. The problem starts where no one counts the percentages. Debt can be different, and decisions are also different. A conscious duty. We know that the solution is temporary, we know why, and we know when we will return. This is the healthiest option.An unconscious duty. We did our best, and then we found out what was better. He learns by experience, but is not treated by discipline.Debt from changed requirements. The code was correct for the previous task. It's not anyone's fault, but you'll have to rewrite it anyway.Debt from negligence. They knew how to do it, they did it differently, they didn't write it down. The only type who is not justified by anything.It is useless to mix them in one conversation: the first type is planned, the second trains the team, the third is inevitable, and the fourth needs to be stopped by the process. How to understand that debt has become expensive The evaluation of simple tasks began to grow. A change in one place requires edits in the other three. There are sections of the code that no one but one person wants to touch. Bugfixes regularly lead to new bugs.Onboarding a new developer takes weeks instead of days. The team increasingly responds, "it's easier to rewrite than to fix." The third and fifth signs are the most significant. They mean that no one has the whole system in their head anymore. What really worksWrite down the debt in the same place where the tasks live, and not in a separate forgotten document. An unfixed debt becomes folklore after six months. Link refactoring to tasks that are already included in this code. A separate "sprint for technical debt" almost always loses the fight against priorities. Formulate the cost in the language of business. Not "bad architecture", but "each new integration takes three weeks instead of three days". Distinguish between debt in hot and dead areas. The perfect code in a module that no one has touched for two years is not needed by anyone. To agree that part of the debt remains forever. Giving it all back is also a form of perfectionism. The main idea It is not the duty itself that is dangerous, but its invisibility. A team that knows where its corners are cut and how much it costs manages the situation. The team that finds out about this at the moment of production failure only reacts. And how do you record the technical debt: in the backlog, in the comments to the code, or is it based on the memory of the team?
Ключ от базы в репозитории появляется не от безалаберности. Он появляется, когда нужно быстро проверить гипотезу, а настроить хранилище секретов дольше, чем вставить строку в файл. Потом это уезжает в коммит, а через полгода репозиторий открывают подрядчику.
Почему удалить коммит недостаточно
Секрет остаётся в истории git. Даже если убрать строку следующим коммитом, значение достаётся из предыдущего одной командой. Более того, если репозиторий был публичным хотя бы недолго, он мог попасть в чужие клоны и в поисковые индексы. Правильная реакция другая: сначала считать секрет скомпрометированным и отозвать его, потом уже чистить историю. Порядок именно такой, потому что чистка занимает часы, а отзыв минуты.
Порядок действий при утечке
Отозвать и перевыпустить ключ. Старое значение должно перестать работать.Посмотреть логи доступа на предмет обращений с чужих адресов за период, пока ключ был доступен. Убрать значение из истории репозитория и переписать её, предупредив команду о необходимости заново склонировать проект. Разобраться, как секрет туда попал, и закрыть именно этот путь.
Что предотвращает повторение
Файл конфигурации с секретами в gitignore с первого дня проекта, до первого коммита. Добавить его позже уже сложнее. Шаблон конфигурации в репозитории: тот же набор полей, но с пустыми или заведомо фальшивыми значениями. Новый разработчик копирует его и заполняет локально. Хук перед коммитом, который ищет характерные шаблоны: длинные случайные строки, префиксы известных сервисов, приватные ключи. Автоматика ловит то, что человек не заметит в дифе на триста строк. Сканирование репозитория в пайплайне, а не только локально. Хук легко обойти флагом no-verify. Разные ключи для разных сред. Утечка тестового ключа тогда остаётся неприятностью, а не инцидентом. Короткое время жизни у токенов и регулярная ротация. Секрет, который меняется каждые тридцать дней, обесценивается сам собой.
Про хранение
Переменные окружения это минимальный рабочий вариант, но у них есть особенности: значения видны в описании процесса, попадают в дампы и иногда в логи ошибок. Для чего-то серьёзнее хватает готовых менеджеров секретов, где есть версионирование, аудит доступа и автоматическая ротация. Выбор конкретного инструмента вторичен, важнее, чтобы секрет доставался приложению во время запуска, а не лежал в файле рядом с кодом.
Мысль на выходе
Безопасность здесь строится не на дисциплине, а на том, что случайно закоммитить секрет должно быть технически трудно. Пока это проще, чем сделать правильно, это будет происходить. А у вас в пайплайне стоит проверка на секреты или это пока держится на внимательности ревьюера?