چگونه از Secretها و API Keyها در GitHub محافظت کنیم؟
راهنمای عملی جلوگیری از نشت API Key روی GitHub بر اساس مستندات رسمی: secret scanning، push protection، .gitignore، env و عادتهای تیم.
Founder & product engineer

بیشتر نشتهای دردناک با نیت بد شروع نمیشوند؛ با یک Commit عجلهای، یک فایل .env که gitignore نشده، یا Paste کلید در Issue شروع میشوند. وقتی API Key وارد تاریخچهٔ Git شد، Clone، Fork، Mirror و Cache میتوانند آن را نگه دارند — حتی اگر بعداً فایل را پاک کنید.
GitHub برای این ریسک دو لایهٔ اصلی در مستندات Secret Scanning توصیف میکند: شناسایی نشت (secret scanning) و جلوگیری از ورود (push protection). این مقاله روی پیشگیری تمرکز دارد؛ واکنش بعد از حادثه در مقالهٔ ۰۸۲ است.
هیچ ابزاری جای انضباط انسان را نمیگیرد. هدف این است که مسیر اشتباه سخت، و مسیر درست (Environment Variable، Secret store، .env.example) آسان باشد.

پاسخ کوتاه
Secret و API Key را داخل سورس، تست با کلید زنده، README، Issue و کامنت PR نگذارید. مقدار را از محیط اجرا یا Secret store بخوانید؛ نام کلیدها را در .env.example بدون مقدار واقعی مستند کنید؛ .env را gitignore کنید. روی GitHub، secret scanning نشت را در تاریخچه و سطوح متنی دیگر پیدا میکند؛ push protection سعی میکند Push حاوی Secret شناختهشده را قبل از رسیدن به مخزن مسدود کند.
برای مخازن Public، scanning خودکار رایگان است و push protection سطح کاربر بهصورت پیشفرض کمک میکند Secret به Public نرود. برای مخازن Private سازمانی معمولاً باید Secret Protection / تنظیمات ادمین را بررسی کنید. اگر چیزی نشت کرد، اول Rotate کنید — پاک کردن تاریخچه مرحلهٔ بعدی است.
ابزار نشت را کم میکند؛ چرخش کلید خسارت را قطع میکند؛ طراحی بدون hard-code هر دو را ارزانتر میکند.
Secret Scanning چیست؟
طبق About secret scanning، وقتی credentialهایی مثل API Key و رمز بهصورت hard-coded در مخزن Commit شوند، هدف سوءاستفاده میشوند. Secret scanning تاریخچهٔ کامل Git روی همهٔ Branchها را برای الگوهای شناختهشده میگردد و به شناسایی secret sprawl کمک میکند. GitHub بهصورت دورهای با افزودن نوعهای جدید هم دوباره اسکن میکند.
علاوه بر کد، این موارد هم اسکن میشوند: توضیح و کامنت Issueها (باز و بستهٔ تاریخی)، عنوان/توضیح/کامنت Pull Request، Discussions، Wikiها و Secret Gistها. وقتی نشتی پیدا شود، در تب Security (در مستندات جدیدتر: Security and quality) هشدار ساخته میشود. توصیهٔ رسمی: فوراً credential را Rotate کنید. حذف از تاریخچه زمانبر است و اگر کلید هنوز زنده باشد کافی نیست.
برنامهٔ Partner: برای برخی Secretهای شناختهشده، GitHub به ارائهدهنده اطلاع میدهد تا اقداماتی مثل ابطال انجام دهد. این هشدارها ممکن است در UI مخزن شما مثل هشدار کاربری دیده نشوند.
دسترسپذیری
- مخازن Public: secret scanning بهصورت خودکار و رایگان اجرا میشود.
- مخازن Private/Internal سازمانی: معمولاً با GitHub Secret Protection روی طرحهای Team/Enterprise.
- قابلیتهای افزودنی: الگوی عمومی، الگوی سفارشی، validity check، تشخیص با AI برای موارد بدون ساختار — بسته به طرح.
Push Protection چیست؟
طبق مستندات Push protection، این قابلیت بهجای هشدار بعد از واقعه، Pushهایی که Secret دارند را قبل از ورود به مخزن مسدود میکند. پوشش رایج: Push از CLI، Commit در UI گیتهاب، آپلود فایل، درخواستهای REST API، و در مخازن Public تعامل با GitHub MCP.
وقتی مسدود میشوید، پیام علت را میبینید؛ باید اطلاعات حساس را حذف و دوباره تلاش کنید.
دو نوع
| نوع | ویژگی کلیدی طبق Docs |
|---|---|
| برای مخزن/سازمان/اینترپرایز | نیاز به Secret Protection؛ پیشفرض خاموش تا ادمین روشن کند؛ هشدار Bypass |
| برای کاربر (GitHub.com) | پیشفرض روشن؛ جلوی Push Secret به مخازن Public را میگیرد |
Bypass با دلیل ممکن است (مثلاً false positive، used in tests، I'll fix it later) و رفتار هشدار فرق میکند. برای کنترل سختتر، delegated bypass تعریف میشود تا فقط نقشهای مشخص بتوانند عبور کنند یا درخواست را تأیید کنند.
لایههای پیشگیری که خودتان میسازید
۱) جدا کردن Config از کد
همان اصل مقالهٔ ۰۴۷: Environment Variable و Secret manager. در GitHub Actions، از Secrets رمزگذاریشدهٔ مخزن/محیط استفاده کنید و آنها را echo نکنید. در اپلیکیشن، کلید را از env بخوانید نه از ثابت.
۲) gitignore و مثال خالی
طبق Ignoring files، فایل .gitignore در ریشه میگوید Git چه چیزهایی را Commit نکند؛ برای اشتراک قانون با تیم باید خودِ gitignore را Commit کنید. .env، فایلهای کلید، و dumpها را اضافه کنید. اگر فایلی قبلاً Track شده، فقط اضافه کردن به gitignore کافی نیست؛ باید با git rm --cached از ایندکس خارج شود.
gitignore
# نمونهٔ حداقلی — کامل نیست .env .env.* !.env.example *.pem *.p12 id_rsa credentials.json
۳) عادت Commit
مستندات حذف دادهٔ حساس، برای جلوگیری از تکرار پیشنهاد میکند: از git add . و commit -a کورکورانه پرهیز کنید؛ فایلها را تکتک Stage کنید؛ با git diff --cached مرور کنید؛ از ابزار بصری برای دیدن فایلهای در حال Commit استفاده کنید؛ pre-commit hookهایی مثل gitleaks/git-secrets را در تیم پخش کنید.
۴) کنترل سازمان
از Best practices: 2FA اجباری، محدود کردن Fork و تغییر Visibility، محدود کردن ساخت مخزن Public، scope حداقلی برای PAT، و فعال بودن push protection کاربران.
چکلیست پیادهسازی یکروزه
- همهٔ .envها را از Track خارج و به gitignore اضافه کنید؛ .env.example بسازید.
- Secretهای Production را در پنل Host/CI جابهجا کنید؛ از سورس پاک کنید.
- وضعیت secret scanning مخزن را در Settings → Security بررسی کنید.
- Push protection مخزن را در صورت دسترسی روشن کنید؛ به تیم بگویید Bypass بیدلیل ممنوع است.
- یک کلید جعلی با الگوی شبیه واقعی در Branch آزمایشی Push کنید تا واکنش ابزار را ببینید — نه کلید زنده.
- CODEOWNERS یا قاعدهٔ Review اجباری برای مسیرهای config حساس بگذارید.
چه چیزهایی را مردم هنوز در Git میگذارند؟
- Connection string دیتابیس در فایل config فریمورک.
- کلید Firebase یا Stripe در اپ موبایل «چون client-side است» — محدودیت و پروکسی را جدا حساب کنید.
- توکن bot در workflow بهصورت متن ساده.
- اسکرین تنظیمات با QR و Secret دوعاملی.
- فایل جابهجایی از همکار داخل /tmp که اشتباهاً Add شده.
هر کدام را در آموزش onboarding مثال بزنید. ترس مبهم کمتر از مثال واقعی بازدارنده است.
محدودیت ابزار را صادقانه ببینید
Secret scanning روی الگوهای شناختهشده و تنظیمات شما قوی است؛ هر رشتهٔ تصادفی یا کلید داخلی ناشناس را تضمینی نمیگیرد. Push protection هم ممکن است false positive بدهد یا با Bypass دور زده شود. بنابراین طراحی «Secret در سورس نباشد» همچنان ستون اصلی است.
همچنین scanning مخزن، جایگزین پایش لاگ اپلیکیشن، تیکت پشتیبانی و چت تیمی نیست. Secretی که در Slack Paste شود مسیر دیگری است.
جمعبندی برای تصمیم
محافظت از Secret روی GitHub ترکیبی است از: جداسازی Config، gitignore، عادت Review روی diff، secret scanning برای کشف، و push protection برای پیشگیری. docs رسمی میگویند بعد از نشت اول Rotate کنید؛ پس پیشگیری ارزانتر از پاکسازی تاریخچه است.
اگر این هفته فقط دو کار میکنید: push protection را جدی بگیرید و همهٔ کلیدهای مشکوک داخل مخزن را عوض کنید.
GitHub Actions و Secretها
Workflowها جای رایجی برای نشتاند: echo کردن Secret برای دیباگ، چاپ context کامل، یا نوشتن Secret در Artifact. مقدار را از Secrets مخزن یا Environment بگیرید، در لاگ آشکار نکنید، و برای Production از Environment با قاعدهٔ Approval استفاده کنید. Secret سطح Environment را با Secret سطح مخزن قاطی نکنید تا Staging به Production نشت نکند.
اگر Workflow از مخازن دیگر Checkout میکند یا به Registry خصوصی میرود، توکن را حداقل Scope بدهید و عمر کوتاه نگه دارید. PAT با دسترسی وسیع که در Actions ذخیره شده، با یک نشت Workflow کل سازمان را در معرض میگذارد.
الگوهای سفارشی و Validity
سازمانهایی که فرمت کلید داخلی دارند میتوانند طبق Docs الگوی سفارشی برای scanning تعریف کنند. Validity check کمک میکند هشدارهای کلید مرده را از کلید زنده جدا کنید تا اولویتبندی واقعی شود. این قابلیتها جایگزین طراحی بدون hard-code نیستند؛ صف رسیدگی را هوشمندتر میکنند.
آموزش onboarding در سی دقیقه
- نشان دادن یک Push مسدودشده با کلید جعلی.
- ساختن .env.example و خواندن از env در یک تابع نمونه.
- مرور gitignore و خطر git add نقطه.
- مسیر اعلام حادثه اگر کسی کلید Push کرد.
- محل Secrets در CI و ممنوعیت Paste در چت.
این آموزش را برای پیمانکار هم تکرار کنید؛ بیشتر نشتها از افراد تازهوارد با عجله میآید نه از مهاجم پیشرفته.
شاخصهای سلامت Secret
- تعداد هشدار باز secret scanning و عمرشان.
- تعداد Bypassهای push protection در ماه و دلیلها.
- زمان میانه از کشف تا Rotate.
- درصد مخازن با push protection روشن.
اگر Bypass با دلیل I'll fix it later زیاد است، فرهنگ دور زدن ساختهاید نه امنیت.
جمعبندی لایهای
لایهٔ یک: Secret در سورس نباشد. لایهٔ دو: gitignore و Review. لایهٔ سه: push protection. لایهٔ چهار: secret scanning و پاسخ سریع. لایهٔ پنج: کنترل سازمان مثل 2FA و محدودیت Visibility. هر لایه شکست لایهٔ قبلی را گرانتر میکند برای مهاجم و ارزانتر برای شما.
منابع و مراجع
- GitHub Docs — About secret scanning — https://docs.github.com/en/code-security/secret-scanning/introduction/about-secret-scanning
- GitHub Docs — Push protection — https://docs.github.com/en/code-security/concepts/secret-security/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 in your organization — https://docs.github.com/en/code-security/getting-started/best-practices-for-preventing-data-leaks-in-your-organization
- GitHub Docs — Ignoring files — https://docs.github.com/en/get-started/git-basics/ignoring-files
برای مراحل بعد از Push اشتباه، مقالهٔ ۰۸۲ را بهعنوان runbook بخوانید.
Author
Soheil Ebrahimpour is the founder of FutureForge. He works on product design, architecture, and getting custom software into production.
Related notes
If you are unsure about architecture or the build path, we can talk about the project.
Describe the problem and the constraints. If there is a fit, we will schedule a conversation.




