← [Раздел 06](README.md) · [Главная](../README.md)

# Quality gates в CI

## Цель

Научиться проектировать **quality gates** (контрольные точки) в CI/CD: когда pipeline должен падать, как балансировать скорость и безопасность, и как оформить exceptions без обхода всех правил.

## Предварительно

- [sast.md](sast.md), [sca-zavisimosti.md](sca-zavisimosti.md), [secrets-scanning.md](secrets-scanning.md).
- CI stages: lint, test, build, deploy.

## Время

~25 минут чтения + 30 минут проектирования gate matrix

---

## Что такое quality gate

**Quality gate** — набор **pass/fail критериев** перед продвижением артефакта:

```
Code → Build → Unit tests → Security scans → Gate ✅/❌ → Deploy staging
```

Gate **автоматический** — не «человек забыл проверить».

## Зачем gates в DevSecOps

| Без gate | С gate |
|----------|--------|
| «Merge, потом починим CVE» | Critical CVE не попадает в main |
| Security optional step | Red pipeline = no merge |
| Tribal knowledge | Policy as code |

## Типичная матрица gates

| Check | Stage | Fail on | Warn on |
|-------|-------|---------|---------|
| Secrets scan | PR | Any verified secret | — |
| SCA | PR | Critical + High | Medium |
| SAST | PR | Critical | High |
| Unit tests | PR | Any failure | — |
| Container scan | Pre-deploy | Critical in image | High |
| DAST | Staging | Critical | High (SLA fix) |

Настройте под risk appetite организации.

## Fail vs warn vs audit

| Mode | Когда использовать |
|------|-------------------|
| **Fail (block)** | Exploitable, secrets, broken tests |
| **Warn** | Medium findings, новый tool rollout |
| **Audit only** | Baseline collection first 2 weeks |

Rollout pattern: audit → warn → fail (постепенное ужесточение).

## Policy as code

Храните пороги в repo:

```yaml
# security-gates.yaml (концепт)
secrets:
  block: true
sca:
  block_severity: [CRITICAL, HIGH]
  max_age_days: 30  # для known unfixed — exception ticket
sast:
  block_severity: [CRITICAL]
  new_issues_only: true  # baseline mode
```

Pipeline читает файл — изменения policy через PR + review.

## Baseline mode (legacy repos)

Problem: 10 000 historical SAST findings.

Solution:

1. Snapshot current = baseline
2. Gate: **block only new** findings in diff
3. Burn down backlog по sprint

Иначе gate никогда не включат.

## Exception process

Без процесса exceptions → `// skip security` everywhere.

| Поле exception ticket | Пример |
|-----------------------|--------|
| Finding ID / CVE | CVE-2024-XXXX |
| Risk justification | Not reachable, internal only |
| Compensating control | Network policy deny egress |
| Expiry date | 2026-09-01 |
| Approver | AppSec lead |

Auto-fail pipeline if exception expired.

## Speed vs security

| Проблема | Mitigation |
|----------|------------|
| SAST 40 min | Incremental scan on diff only |
| Flaky DAST | Staging stability, retry limits |
| Parallel jobs | secrets + sca + sast parallel |
| Caching | Dependency cache, scan cache |

Target: PR feedback < 15 min для fast checks; heavy DAST nightly.

## Branch protection integration

Platform settings (GitHub/GitLab):

- Require status checks: `security/secrets`, `security/sca`
- Require review from CODEOWNERS for `/security-gates.yaml`
- No direct push to `main`

Gate бессмыслен без branch protection.

## Metrics dashboard

| KPI | Purpose |
|-----|---------|
| Merge blocked count | Too strict? |
| Mean time to remediate | Process health |
| Exception count trend | Policy drift |
| Scan coverage % repos | Adoption |

## Anti-patterns

| Anti-pattern | Result |
|--------------|--------|
| Gate exists, admin bypass always | Theater |
| 50 required checks, all flaky | Developers ignore red |
| No ownership of failures | Blame security team |
| Different rules per team silently | Audit nightmare |

## Пример end-to-end PR flow

1. Dev opens PR → secrets ✅ (30s)
2. SCA finds High CVE in `axios` → ❌ block
3. Dev bumps axios → SCA ✅
4. SAST new medium → ⚠️ warn, ticket auto-created
5. Reviewer + checklist → approve
6. Merge → staging deploy → nightly DAST

---

## Самопроверка

1. Чем quality gate отличается от «запуска scan без fail»?
2. Зачем baseline mode?
3. Какие 3 поля обязательны в exception ticket?
4. Почему branch protection критичен для gates?

## Дальше

[DAST и pentest (lite)](dast-i-pentest-lite.md)
