هرگز secret را در Git commit نکنید
چرا API key در مخزن خطرناک است، چطور با env و Secret Manager کار کنید، pre-commit و push protection گیتهاب برای پیشگیری.
بنیانگذار و مهندس محصول

یک خط `API_KEY=sk-...` داخل سورس، یا فایل `.env` که با `git add .` وارد stage شده، میتواند از یک اشتباه محلی به حادثهٔ امنیتی تبدیل شود. رباتها مخازن عمومی را پیوسته اسکن میکنند؛ در مخزن خصوصی هم دسترسی همکار، پیمانکار، یا نشت بعدی توکن CI کافی است. تاریخچهٔ Git فراموشکار نیست: حتی اگر commit بعدی فایل را پاک کند، شیء قدیمی تا بازنویسی تاریخچه و پاکسازی سمت سرور قابل بازیابی است.
این مقاله پیشگیری است. اگر الان secret لو رفته، مقالهٔ پاسخ به حادثه را بخوانید و اول credential را باطل کنید.

پاسخ کوتاه
Secret را در کد hardcode نکنید؛ از متغیر محیطی، secret store ابری، یا GitHub Actions secrets استفاده کنید. `.env` واقعی را ignore کنید و فقط example با مقدار جعلی commit کنید. قبل از push، `git diff --staged` را بخوانید. روی GitHub، secret scanning و push protection را جدی بگیرید تا push حاوی credential مسدود شود.
پاک کردن فایل در commit بعدی، secret را از تاریخچه پاک نمیکند.
secret چیست و چرا در Git خطرناک است
- کلید API، توکن دسترسی، رمز پایگاهداده، private key، اتصالرشتهٔ دارای رمز.
- توکنهای CI/CD و webhook secret.
- فایلهای گواهی و کلید SSH خصوصی.
Git برای همگامسازی و تاریخچه ساخته شده، نه برای گاوصندوق. هر کلون کپی کامل دارد. فورکها و کشها و لاگ Actions میتوانند دامنهٔ افشا را بزرگ کنند. طبق مستندات GitHub دربارهٔ حذف دادهٔ حساس، اگر مورد یک secret است، اولین کار revoke/rotate است؛ بازنویسی تاریخچه همیشه لازم یا کافی نیست.
الگوی درست: جدا کردن پیکربندی از راز
bash
# .env (محلی — ignore شود) DATABASE_URL=postgres://user:pass@localhost:5432/app STRIPE_KEY=sk_test_xxx # .env.example (قابل commit) DATABASE_URL=postgres://user:password@localhost:5432/app STRIPE_KEY=replace_me
در کد:
python
import os key = os.environ["STRIPE_KEY"] # بدون مقدار پیشفرض واقعی در سورس
در production از Secret Manager (AWS/GCP/Azure/HashiCorp) یا سازوکار پلتفرم استفاده کنید تا راز در زمان اجرا تزریق شود، نه از فایل داخل image عمومی.
عادات روزمرهٔ ضدنشت
- از `git add .` بیفکر پرهیز کنید؛ فایلها را انتخابی stage کنید.
- همیشه `git diff --staged` قبل از commit.
- قالب PR را طوری بگذارید که چکلیست «secret ندارم» دیده شود.
- در اسکرینشات و لاگ، توکن را ماسک کنید.
- توکن را با کمینهٔ دسترسی (least privilege) و تاریخ انقضا بسازید.
ابزار پیشگیری محلی
hookهای pre-commit و ابزارهایی مثل gitleaks یا git-secrets میتوانند قبل از ثبت، الگوهای کلید را پیدا کنند. اینها جایگزین آموزش نیستند ولی هزینهٔ اشتباه را کم میکنند. هر همکار باید hook را نصب کند؛ در CI هم اسکن جداگانه بگذارید تا کسی بدون hook عبور نکند.
bash
# مثال مفهومی — ابزار و پیکربندی تیم را استاندارد کنید gitleaks protect --staged
قابلیتهای GitHub: secret scanning و push protection
طبق مستندات رسمی GitHub، secret scanning تاریخچه و بخشهایی مثل issue و PR را برای credentialهای شناختهشده پویش میکند و برای مخازن عمومی بهصورت خودکار فعال است. هدف شناسایی نشت قبل از سوءاستفاده است.
push protection لایهٔ جلوتر است: بهجای هشدار بعد از واقعیت، push حاوی secret را مسدود میکند — از خط فرمان، UI، آپلود، و برخی مسیرهای API. دو شکل دارد: برای مخزن (قابل تنظیم در سطح repo/org/enterprise با Secret Protection) و برای کاربر (روی GitHub.com بهصورت پیشفرض برای جلوگیری از push secret به مخازن عمومی).
اگر کسی bypass کند، بسته به دلیل، هشدار امنیتی و ثبت audit ایجاد میشود. سازمانها میتوانند delegated bypass و الگوی سفارشی تعریف کنند.
- Secret scanning: https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning
- Push protection: https://docs.github.com/en/code-security/secret-scanning/introduction/about-push-protection
GitHub Actions و secretها
رازهای گردشکار را در Settings → Secrets and variables ذخیره کنید و در workflow با `${{ secrets.NAME }}` بخوانید. آنها را echo نکنید؛ GitHub تلاش میکند ماسک کند ولی باز هم در گامهای بیاحتیاط ممکن است لو بروند. Artifact و لاگ را قبل از عمومی کردن مخزن بررسی کنید.
yaml
# قطعهٔ مفهومی workflow env: API_KEY: ${{ secrets.API_KEY }}
اشتباههای رایج
- گذاشتن کلید تست واقعی در تستهای واحد داخل مخزن عمومی.
- commit کردن فایل سرویساکانت JSON گوگل.
- کپی توکن در پیام commit یا توضیح PR.
- فرض اینکه مخزن خصوصی یعنی بینیاز از انضباط secret.
- چرخاندن کلید بدون پیدا کردن همهٔ محلهای استفاده (اپ، CI، همکاران).
سیاست تیمی پیشنهادی
| قاعده | اجرا |
|---|---|
| هیچ secret در سورس | review + اسکن |
| .env فقط محلی | gitignore + مثال |
| توکن کوتاهعمر | تقویم چرخش |
| push protection | سازمان/مخزن |
| آموزش onboarding | نیمساعت اول هفته |
اگر شک دارید همین حالا چک کنید
bash
git grep -nE 'API_KEY|BEGIN RSA PRIVATE KEY|aws_secret_access_key' $(git rev-list --all) | head # یا اسکن اختصاصی ابزار تیم روی تاریخچه
اگر چیزی پیدا شد، وارد حالت حادثه شوید: revoke اول.
خلاصه
Secret در Git یعنی کپیهای فراوان از یک کلید در زمان. پیشگیری ترکیبی از طراحی (env/store)، عادت (diff staged)، ابزار محلی، و کنترلهای GitHub مثل secret scanning و push protection است. وقتی پیشگیری شکست خورد، چرخش کلید بر بازنویسی تاریخچه اولویت دارد.
سوالات متداول
کلید تست را میتوان commit کرد؟
فقط اگر واقعاً بیارزش، محدود، و جدا از production باشد و سیاست تیم اجازه دهد؛ بهتر است از secret CI تزریق شود.
مخزن خصوصی امن است؟
کمریسکتر از عمومی است، نه بدونریسک. دسترسیها عوض میشوند؛ نشت رخ میدهد.
آیا .gitignore کافی است؟
برای untracked بله؛ برای اشتباه انسانی و فایل trackشده خیر.
منابع و مراجع
- GitHub Docs — About secret scanning: https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning
- GitHub Docs — Push protection: https://docs.github.com/en/code-security/secret-scanning/introduction/about-push-protection
- GitHub Docs — Removing sensitive data from a repository: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository
- GitHub Docs — Best practices for preventing data leaks: https://docs.github.com/en/code-security/getting-started/best-practices-for-preventing-data-leaks-in-your-organization
- Git — gitignore: https://git-scm.com/docs/gitignore
نویسنده
سهیل ابراهیمپور بنیانگذار FutureForge است. روی طراحی محصول، معماری و استقرار نرمافزار سفارشی کار میکند.
یادداشتهای مرتبط
اگر در انتخاب معماری یا مسیر توسعه مطمئن نیستید، میتوانید درباره پروژه صحبت کنیم.
مسئله و محدودیت را بنویسید. اگر تطابق داشته باشیم، برای گفتگو هماهنگ میکنیم.




