// Engineering Log
Secure Development: Part 2 — Secrets in Code
Published on 2026-09-22
// Fast route
This article belongs to the topic Security and protection.
A secret is any data that grants access to a resource: a database password, a payment system or cloud API key, a bot token, a private SSH key. If such a secret ends up in Git, removing it in the next commit does not fix anything: Git stores the entire history, and the old version of the file is available to anyone who has a copy of the repository. Automated scanners continuously scan public repositories, so a key committed to a public commit should be considered compromised immediately.
If a secret has already leaked
Order of actions is more important than tools:
- Revoke or rotate the secret with the provider: create a new key, deactivate the old one, change the database password. This is the only step that truly closes access.
- Check the service access logs related to the key: whether someone unauthorized has used it.
- Rotate related credentials. If a password that was used in multiple places leaked, change it everywhere.
- Only after that, clean the repository history. The Git project recommends using git filter-repo for this instead of the deprecated
git filter-branch:
# remove file from entire history
git filter-repo --path config/secrets.yml --invert-paths
# replace strings from replacements.txt across all commits
git filter-repo --replace-text replacements.txtAfter rewriting history you need to force-push to the remote repository, and all contributors must re-clone the project. Copies that have already spread — forks, local clones, CI caches — are not affected by the cleanup. Therefore it does not replace the first step; it only removes traces.
Where to store secrets
- In development — in a
.envfile that is listed in.gitignore. Put a.env.examplein the repository with variable names and empty values so colleagues know what to fill in. - In CI/CD — in the project’s protected variables: masked and protected in GitLab, secrets in GitHub Actions.
- On servers — in the service environment or in a separate secrets store, but not in code and not in the Docker image.
If .env has already been committed to the repository, simply adding it to .gitignore is not enough: the file must be removed from the index with git rm --cached .env — and, of course, change everything that was in it.
Gitleaks
Gitleaks searches repositories and directories for passwords, keys, and tokens using a set of regular expressions for hundreds of formats. License MIT, current version as of September 2026 — 8.30.1. The author declared the tool completed: new features are no longer added, only security fixes are released, and development continues in a new project, Betterleaks.
Main modes of operation:
gitleaks git -v # scan the entire history of the current repository
gitleaks dir . # scan files in the directory without historyThe detect and protect commands from older versions are deprecated, although they still work for now.
Check before every commit: pre-commit
The pre-commit framework runs checks automatically on every git commit. Install and hook up Gitleaks:
pip install pre-commit.pre-commit-config.yaml at the project root:
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.30.1
hooks:
- id: gitleakspre-commit install # install the hook into the repository
pre-commit run --all-files # check all files right after installation
pre-commit autoupdate # update hook versionsIf Gitleaks finds a secret, the commit will not proceed. The check can be skipped with the variable SKIP=gitleaks, so the local hook is a convenience for the developer, not a guarantee.
TruffleHog
TruffleHog addresses the same task but can verify findings: for many key types it queries the provider’s API and reports whether the key is active. License AGPL-3.0, current version — 3.97.5.
trufflehog git https://git.example.ru/team/project.git --results=verifiedThe --results=verified flag leaves only keys confirmed as active in the report. Such findings require immediate key rotation.
Server-side scanning
Since local checks can be disabled, they should be repeated in the pipeline — as the first job, before build and tests. For GitHub Actions, Gitleaks provides a ready-made gitleaks-action; in GitLab CI and Gitea Actions it’s enough to have a job that runs gitleaks git in the project directory. Such a job should stop the pipeline on any finding.
GitHub also has its own protection — push protection. For personal accounts it is enabled by default and prevents pushing a secret to a public repository. Repository-level protection, which works for private projects as well, requires the paid GitHub Secret Protection feature and must be enabled by an administrator.
Common mistakes
- Deleting the file in a new commit and thinking the problem is solved. The secret remains in the history.
- Cleaning history instead of rotating the key. Copies of the repository already exist.
- Printing secrets to CI logs. The command
echo $TOKENfor debugging prints the key into the build log; protected variables are masked, but you shouldn’t rely only on that. - Passing secrets into a Docker image via
ARGorENV. They are stored in image layers; the correct way is BuildKit secrets. - Using the same key for development and production. A leak in the test environment opens access to production.
// Similar task
If you are dealing with something similar
This article belongs to one of the main working topics. You can keep reading on the topic, go to the homepage to understand what I do, or open the service pages directly.
Article topic
Security and protection
SSL, hardening, access control, service protection, and secure configurations.
Typical tasks behind this topic
- Set up SSL, certificates, and secure connections
- Restrict access and close unnecessary entry points
- Harden server and service configuration
// Next step
If you need help with this topic, not just another article, it is better to go straight to the service page. The homepage and topic collection stay available as secondary routes.
Open services// Reviews
Related reviews
I came with an expensive request to configure a VPS server, but during the consultation Mikhail suggested a much simpler, more affordable solution. In the end I saved time and money. Mikhail — a true expert who works for the client's result, not for the fee. I recommend him!
I came with an expensive request to configure a VPS server, but during the consultation Mikhail suggested a much simpler and more cost-effective solution. In the end I saved budget and time. Mikhail — a true expert who …
VPS setup, server setup
2026-05-12 · ★ 5/5
Excellent work! Set up the server very quickly, installed the control panel, and configured the IP. Definitely recommend!
Excellent work! Very quickly set up the server, installed the panel, configured the IP I can definitely recommend it!
Everything was excellent; helped promptly and professionally. Thank you — I recommend them to the community.
Everything's great, helped promptly and professionally, thank you, I recommend it to the community
VPS setup, server setup
2026-04-16 · ★ 5/5
There were several issues concerning both the technical side and overall understanding. Mikhail responded quickly, resolved the technical problems, and helped me understand them — many thanks. I'm satisfied with the result.
There were several issues concerning both the technical side and overall understanding. Mikhail responded quickly to the request, helped sort things out and resolved the technical problems and helped clarify …
VPS setup, server setup
2026-02-18 · ★ 5/5
Everything was done quickly and efficiently. I recommend.
Everything was done quickly and efficiently. I recommend.
VPS setup, server setup
2026-01-17 · ★ 5/5
Everything went well; the contractor responded quickly to questions and helped resolve the issue. Thanks!
Everything went well, the contractor responded quickly to questions and helped resolve the issue. Thank you!
VPS setup, server setup
2025-12-16 · ★ 5/5
// Contact
Need help?
Get in touch with me and I'll help solve the problem
I reply within one business day (03:00-13:00 GMT)
Или оставьте заявку здесь:
// Related