Repository Yönetimi
Giriş — Bir Binanın Güvenlik Sistemi
Bir ofis binası düşünün. Binanın ana girişi var — herkese açık değil, kart ile girilir. İçeride farklı katlar var: zemin kat herkesin erişebildiği ortak alan, 3. kat sadece mühendislik ekibinin, 5. kat sadece yönetimin girebileceği alan, kasa dairesi ise sadece iki kişinin erişebildiği yer. Her katın ayrı yetkileri, ayrı kartları var.
GitHub'da da repository, branch ve organizasyon yönetimi tam olarak böyle çalışır. Kod güvenliği sadece "şifreni güçlü tut" demek değildir. Kimlerin neyi değiştirebileceği, hangi branch'lere kimlerin push yapabileceği, PR'ların kaç kişi tarafından onaylanması gerektiği — bunların hepsi organizasyonel güvenliğin parçasıdır.
Bu derste, GitHub'ın erişim kontrol mekanizmalarını baştan sona öğreneceğiz.
Branch Protection Rules — Kritik Branch'leri Koruma
Neden Gerekli?
Bir geliştirici yanlışlıkla main branch'e force push yaparsa ne olur? Veya test çalıştırmadan merge ederse? Ya da tek başına, kimseye danışmadan production kodu değiştirirse?
Bu senaryoların hepsi gerçek hayatta yaşanmıştır ve büyük hasarlara yol açmıştır. Branch protection rules, bu tür kazaları yapısal olarak imkânsız hale getirir.
Temel Koruma Ayarları
GitHub'da Settings → Branches → Branch protection rules → Add rule yolunu izleyerek koruma kuralı eklersiniz:
Repository Settings → Branches → Add branch protection rule
Branch name pattern: main
(veya pattern: release/*)1. Require a Pull Request Before Merging
☑ Require a pull request before merging
☑ Require approvals
Required number of approvals: 2
☑ Dismiss stale pull request approvals when new commits are pushed
☑ Require review from Code OwnersBu kuralın anlamı:
Kimse direkt `main`'e push yapamaz — PR açmak zorunlu
En az 2 kişi onaylamalı — tek kişinin gözünden kaçanı diğeri yakalar
Yeni commit gelince onay düşer — review sonrası değişiklik yapılırsa tekrar onay gerekir
Code Owners onayı zorunlu — ilgili ekibin onayı olmadan merge yapılamaz
# Bu kurallar aktifken:
git checkout main
git commit -m "feat: direct commit"
git push origin main
# HATA: Protected branch — push rejected!
# Doğru yol:
git checkout -b feature/my-change
git commit -m "feat: my change"
git push origin feature/my-change
# → GitHub'da PR aç → 2 review al → Merge2. Require Status Checks to Pass
☑ Require status checks to pass before merging
☑ Require branches to be up to date before merging
Status checks:
✓ ci / test
✓ ci / lint
✓ ci / buildBu kuralın anlamı:
CI testleri geçmeden merge yapılamaz — kırık kod main'e giremez
Branch güncel olmalı — merge'den önce main'deki son değişiklikleri almak zorunlu
PR Merge Akışı:
PR Açıldı
│
▼
CI Çalışır ──── Fail? ──► Merge butonu kilitli 🔒
│
Pass ✓
│
▼
Review Bekleniyor ──── Yetersiz? ──► Merge butonu kilitli 🔒
│
2 Approval ✓
│
▼
Branch güncel mi? ──── Hayır ──► "Update branch" butonu
│
Evet ✓
│
▼
✅ Merge Butonu Aktif3. Diğer Koruma Seçenekleri
☑ Require signed commits
→ Commit'ler GPG ile imzalanmış olmalı
☑ Require linear history
→ Merge commit'ler yasak, sadece squash veya rebase
☑ Include administrators
→ Admin'ler bile kuralları atlayamaz
☑ Restrict who can push to matching branches
→ Sadece belirli kişi/ekipler push yapabilir
☑ Allow force pushes → ASLA (main için)
☐ Allow deletions → ASLA (main için)⚠️ Dikkat: "Include administrators" seçeneği kritik öneme sahiptir. Bu seçenek kapalıysa, admin'ler tüm kuralları bypass edebilir. Production branch'lerinde bu mutlaka açık olmalıdır. Acil durumlar için "bypass" listesi tanımlayabilirsiniz.
Ruleset (Yeni Sistem — Önerilen)
GitHub, eski branch protection'ın yerini alan daha güçlü Rulesets sistemini sunuyor:
Repository Settings → Rules → Rulesets → New ruleset
Name: Production Protection
Enforcement: Active
Bypass list:
- Release Managers (with PR)
Target branches:
- Include: main
- Include: release/*
Rules:
☑ Restrict deletions
☑ Require linear history
☑ Require a pull request before merging
- Required approvals: 2
- Dismiss stale reviews: Yes
- Require Code Owner review: Yes
☑ Require status checks to pass
- ci/test
- ci/lint
- ci/build
☑ Block force pushes
☑ Require signed commitsRulesets'in avantajları:
Bypass listesi: Belirli kişiler kuralları geçebilir (ama PR ile)
Pattern matching:
release/*,hotfix/*gibi birden fazla branch'e uygulanabilirOrganization level: Tüm repo'lara tek seferde uygulanabilir
Import/Export: Kuralları JSON olarak paylaşabilirsiniz
CODEOWNERS — Kod Sahipliği
Ne İşe Yarar?
CODEOWNERS dosyası, hangi dosya/klasörün kimin sorumluluğunda olduğunu belirler. Bir PR bu dosyalara dokunduğunda, ilgili kişi/ekip otomatik olarak reviewer olarak atanır.
Dosya Konumu
# Üç geçerli konum (GitHub sırayla arar):
.github/CODEOWNERS # En yaygın
docs/CODEOWNERS
CODEOWNERS # Root'taSözdizimi (Syntax)
# .github/CODEOWNERS
# Varsayılan sahipler (hiçbir kural eşleşmezse)
* @default-team
# Klasör bazlı sahiplik
/src/frontend/ @frontend-team
/src/backend/ @backend-team
/src/mobile/ @mobile-team
/infrastructure/ @devops-team
# Dosya bazlı sahiplik
/src/auth/ @security-team @backend-team
package.json @tech-leads
Dockerfile @devops-team
*.sql @database-team
# Belirli dosya pattern'leri
docs/*.md @docs-team
*.test.js @qa-team
*.css @design-team
# Belirli bir kişi
/src/payment/ @ahmet-senior
/.github/ @repo-admin
# Negatif pattern (sahip yok — herkes değiştirebilir)
# /src/experiments/ (bu satırı yazmamak yeterli)Kurallar
CODEOWNERS Matching Kuralları:
1. Son eşleşen kural geçerlidir (dosyanın sonundaki satır önceliklidir)
2. Pattern'ler .gitignore syntax'ı kullanır
3. @ ile başlayanlar GitHub kullanıcısı veya takımıdır
4. Birden fazla sahip belirtilebilir (hepsinin review'u gerekir)CODEOWNERS + Branch Protection
CODEOWNERS gerçek gücünü branch protection ile birlikte gösterir:
Branch Protection:
☑ Require review from Code Owners
Bu aktifken:
- PR /src/frontend/ dosyalarına dokunuyorsa
→ @frontend-team'den EN AZ 1 kişi onaylamalı
- PR /src/auth/ dosyalarına dokunuyorsa
→ @security-team VE @backend-team'den onay gerekliPR Review Akışı (CODEOWNERS ile):
PR: "feat: update payment flow"
Değişen dosyalar:
- src/payment/handler.js → Owner: @ahmet-senior
- src/frontend/checkout.tsx → Owner: @frontend-team
- src/auth/tokens.js → Owner: @security-team
│
▼
Otomatik reviewer atama:
✓ @ahmet-senior
✓ @frontend-team (herhangi 1 üye)
✓ @security-team (herhangi 1 üye)
│
▼
Tüm owner'lar onaylayana kadar merge engelli 🔒💡 İpucu: CODEOWNERS dosyasını ekip yapınız değiştiğinde güncellemeyi unutmayın. Ekipten ayrılan birinin sahip olarak kalması, PR'ların onay bekleyerek sıkışmasına neden olur.
GitHub Organization ve Teams
Organization Nedir?
GitHub Organization, şirket veya topluluk düzeyinde repository ve üye yönetimi sağlar:
Organization: acme-corp
├── Teams
│ ├── engineering (parent team)
│ │ ├── frontend-team
│ │ ├── backend-team
│ │ └── mobile-team
│ ├── devops-team
│ ├── design-team
│ └── management
├── Repositories
│ ├── acme-app (private)
│ ├── acme-docs (public)
│ └── acme-infrastructure (private)
└── Members
├── Owner: ceo@acme.com
├── Member: dev1@acme.com
└── Member: dev2@acme.comOrganization Rolleri
Rol │ Yetkiler
─────────────┼─────────────────────────────────────────
Owner │ Her şeyi yapabilir — billing, members,
│ repo silme, org settings
Member │ Repo'lara erişim (team bazlı), PR, issue
Billing Mgr │ Sadece fatura yönetimi
Outside │ Belirli repo'lara davet edilmiş dış
Collaborator │ kişiler (freelancer, danışman)Team Yapısı ve İzinler
# Team oluşturma (GitHub UI veya API)
# Organization → Teams → New team
# Team izin seviyeleri:
# Read → Kodu görebilir, issue açabilir
# Triage → Issue/PR yönetebilir, push yapamaz
# Write → Push yapabilir, PR merge edebilir
# Maintain → Repo ayarlarını değiştirebilir (silme hariç)
# Admin → Her şey (repo silme dahil)Örnek İzin Matrisi:
Repository: acme-app
─────────────────────────────────────────────
Team │ İzin Seviyesi
─────────────────┼───────────────
frontend-team │ Write
backend-team │ Write
devops-team │ Maintain
design-team │ Read
management │ Read
qa-team │ Triage
tech-leads │ Admin
─────────────────┴───────────────Nested Teams (İç İçe Takımlar)
engineering (Parent)
├── frontend-team (Child)
├── backend-team (Child)
└── mobile-team (Child)Parent team'e verilen izin, otomatik olarak child team'lere de uygulanır. Child team'e ek izin verilebilir ama parent'tan düşük izin verilemez.
Örnek:
- engineering → acme-app: Read
- frontend-team → acme-app: Write
Sonuç:
- frontend-team üyesi → Write (kendi izni daha yüksek)
- backend-team üyesi → Read (parent'tan miras)Team Discussions ve @mention
# Team'i PR'da mention etme
# PR description veya comment'te:
@acme-corp/frontend-team bu PR'ı review eder misiniz?
# CODEOWNERS'da team kullanma
/src/frontend/ @acme-corp/frontend-team
/src/backend/ @acme-corp/backend-teamRepository Visibility ve İzinler
Visibility Seçenekleri
Public → Herkes görebilir, fork edebilir
(Open source projeler)
Private → Sadece izin verilenler görebilir
(Şirket projeleri)
Internal → Sadece organization üyeleri görebilir
(Enterprise plan — şirket içi paylaşım)Collaborator İzinleri (Org Dışı Repo'lar)
Kişisel repo'larda (organization dışında) doğrudan collaborator ekleyebilirsiniz:
# GitHub UI: Settings → Collaborators → Add people
# veya GitHub CLI ile:
gh api repos/{owner}/{repo}/collaborators/{username} \
-X PUT \
-f permission=pushFork ve PR İzinleri
Senaryo: Dış bir contributor fork edip PR açıyor
1. Dış contributor fork eder
2. Fork'unda değişiklik yapar
3. Original repo'ya PR açar
4. CI çalışır (ama secrets erişimi YOK — güvenlik)
5. Maintainer review eder
6. Approve → Merge# Fork'tan gelen PR'lar için önemli güvenlik ayarı:
# Settings → Actions → General
# "Fork pull request workflows from outside collaborators"
# ◉ Require approval for first-time contributors
# ○ Require approval for all outside collaborators⚠️ Dikkat: Fork'tan gelen PR'larda GitHub Actions
GITHUB_TOKENsınırlı yetkilerle çalışır ve secrets erişimi kapalıdır. Bu, kötü niyetli birinin PR ile secret'larınızı çalmasını önler.
Environments ve Deploy İzinleri
GitHub Environments, deployment süreçlerini kontrol etmenin güçlü bir yoludur:
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy-staging:
environment: staging
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: ./deploy.sh staging
deploy-production:
needs: deploy-staging
environment:
name: production
url: https://app.acme.com
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: ./deploy.sh productionEnvironment ayarları (GitHub UI):
Settings → Environments → production
Protection rules:
☑ Required reviewers: @tech-leads, @devops-team
(Deploy öncesi onay gerekli)
☑ Wait timer: 5 minutes
(Onay sonrası 5 dk bekleme — son şans iptal)
☑ Deployment branches:
Selected branches: main, release/*
(Sadece bu branch'lerden deploy edilebilir)
Environment secrets:
AWS_ACCESS_KEY_ID: ****
AWS_SECRET_ACCESS_KEY: ****
DATABASE_URL: ****Deploy Akışı (Protection ile):
Push to main
│
▼
Deploy to staging ──── Otomatik
│
▼
Deploy to production ──── 🔒 Onay gerekli
│
▼
@tech-leads notification
│
▼
✅ Approve ──── 5 dk bekleme ──── 🚀 Deploy
❌ Reject ──── İptalSecurity Best Practices Checklist
## 🔐 Repository Güvenlik Kontrol Listesi
### Branch Protection
- [ ] main branch korumalı
- [ ] PR zorunlu (direkt push yok)
- [ ] En az 2 reviewer onayı
- [ ] Stale review dismissal aktif
- [ ] Status checks zorunlu (CI geçmeli)
- [ ] Force push engelli
- [ ] Branch silme engelli
- [ ] Admin'ler de kurallara dahil
### Erişim Kontrolü
- [ ] Organization kullanılıyor
- [ ] Team bazlı izinler tanımlı
- [ ] CODEOWNERS dosyası var ve güncel
- [ ] Minimum yetki prensibi (least privilege)
- [ ] Dış collaborator'lar sınırlı izinli
- [ ] 2FA zorunlu (organization ayarı)
### Secret Yönetimi
- [ ] Secrets GitHub Secrets'ta (repo'da değil!)
- [ ] Environment secrets ayrılmış
- [ ] Secret scanning aktif
- [ ] .env dosyaları .gitignore'da
### CI/CD Güvenliği
- [ ] Fork PR'ları için approval gerekli
- [ ] Actions izinleri sınırlı
- [ ] Third-party action'lar pin'lenmiş (SHA ile)
- [ ] GITHUB_TOKEN minimum izinli
### Genel
- [ ] SSH key'ler güncel
- [ ] Inaktif collaborator'lar temizlenmiş
- [ ] Audit log düzenli kontrol ediliyor
- [ ] Dependency update otomatik (Dependabot)Gerçek Dünya: Organizasyon Kurulumu
Yeni bir startup kuruyorsunuz, 10 kişilik ekip. GitHub organizasyonunu sıfırdan kuralım:
# 1. Organization oluştur
# github.com/organizations/new → "acme-startup"
# 2. Takımları oluştur
# Teams:
# - engineering (parent)
# - frontend (child)
# - backend (child)
# - devops
# - design
# 3. Repo oluştur
gh repo create acme-startup/acme-app --private
# 4. Takımlara repo izni ver
# frontend → acme-app: Write
# backend → acme-app: Write
# devops → acme-app: Maintain
# design → acme-app: Read
# 5. Branch protection
# main:
# - PR zorunlu, 1 approval (küçük ekip)
# - CI checks zorunlu
# - Force push engelli
# - Stale review dismissal
# 6. CODEOWNERS
cat > .github/CODEOWNERS << 'EOF'
* @acme-startup/engineering
/src/frontend/ @acme-startup/frontend
/src/backend/ @acme-startup/backend
/infrastructure/ @acme-startup/devops
/docs/ @acme-startup/engineering
Dockerfile @acme-startup/devops
*.yml @acme-startup/devops
EOF
# 7. PR template
mkdir -p .github
cat > .github/pull_request_template.md << 'EOF'
## Ne değişti?
<!-- Kısa açıklama -->
## Neden?
<!-- Motivasyon -->
## Test
- [ ] Unit test eklendi
- [ ] Manuel test yapıldı
## Checklist
- [ ] Self-review yapıldı
- [ ] Dökümantasyon güncellendi
EOF
# 8. İlk commit
git add .github/
git commit -m "chore: add CODEOWNERS, PR template, and branch rules"
git push origin mainBüyüdükçe Ölçeklendirme
Ekip Büyüklüğü │ Önerilen Ayarlar
───────────────┼──────────────────────────────────
1-3 kişi │ 1 approval, basit CI, CODEOWNERS opsiyonel
4-10 kişi │ 1-2 approval, CI zorunlu, CODEOWNERS aktif
11-30 kişi │ 2 approval, CI + staging, team bazlı izinler
31-100 kişi │ 2+ approval, environment gates, audit log
100+ kişi │ Enterprise plan, SAML SSO, IP allow listAudit Log — Kim Ne Yaptı?
Organization owner'ları, audit log ile tüm aktiviteleri izleyebilir:
Organization → Settings → Audit log
Filtreleme örnekleri:
- action:repo.destroy (repo silme)
- action:team.add_member (takıma üye ekleme)
- action:protected_branch.* (branch protection değişiklikleri)
- actor:username (belirli kişinin işlemleri)# GitHub CLI ile audit log
gh api orgs/{org}/audit-log \
--jq '.[] | "\(.created_at) \(.actor) \(.action)"' \
| head -20
# Çıktı:
# 2024-01-15T10:30:00Z ahmet repo.create
# 2024-01-15T11:00:00Z mehmet protected_branch.create
# 2024-01-15T14:22:00Z ayse team.add_member💡 İpucu: Audit log'u düzenli olarak kontrol edin. Beklenmeyen izin değişiklikleri, repo silmeleri veya branch protection kaldırmaları güvenlik ihlali işareti olabilir.
Yaygın Hatalar
1. Admin'lerin Kuralları Bypass Etmesi
# ❌ "Include administrators" kapalı
# Admin main'e direkt push yapabilir — kaza riski!
# ✅ "Include administrators" açık
# Admin bile PR açmak zorunda
# Acil durum için "bypass list" kullanın (ruleset)2. CODEOWNERS Güncel Olmaması
# ❌ Ekipten ayrılan kişi hâlâ CODEOWNERS'da
/src/payment/ @eski-calisan # Bu kişi artık yok!
# PR'lar onay bekleyerek kalır
# ✅ Düzenli güncelleme
# Çeyrek dönemlik CODEOWNERS review'u yapın
# Offboarding sürecine "CODEOWNERS güncelle" ekleyin3. Aşırı İzin Verme
# ❌ Herkese Admin izni
# "Kolaylık olsun diye herkesi admin yapalım"
# ✅ Minimum yetki prensibi (Principle of Least Privilege)
# Developer → Write
# Tech Lead → Maintain
# CTO → Admin
# Stajyer → Read (başlangıçta)Özet
Bu derste GitHub'ın erişim kontrol ve güvenlik mekanizmalarını öğrendik:
🛡️ Branch protection — main'e direkt push engelle, PR ve review zorunlu kıl
👥 CODEOWNERS — dosya/klasör bazlı sahiplik, otomatik reviewer atama
🏢 Organization — merkezi üye ve repo yönetimi
👨👩👧👦 Teams — grup bazlı izinler, nested team desteği
🔒 Environments — deploy öncesi onay kapıları, ayrı secret'lar
📋 Rulesets — yeni nesil branch protection, bypass listesi, org-level kurallar
📊 Audit log — kim ne yaptı, güvenlik izleme
Bir sonraki bölümde GitHub ekosisteminin diğer güçlü araçlarını keşfedeceğiz: GitHub Pages, Packages, Copilot ve güvenlik özellikleri.
AI Asistan
Sorularını yanıtlamaya hazır