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

# Безопасность в GitHub Actions

## Цель

Собрать безопасный workflow в GitHub Actions: минимальные права (`permissions`), сканирование кода и образов, безопасная передача секретов через OIDC вместо долгоживущих ключей.

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

- Репозиторий на GitHub.
- Папка `.github/workflows/` и синтаксис YAML.

## Время

~55 минут.

## Угрозы, специфичные для Actions

| Угроза | Описание |
|--------|----------|
| Poisoned pipeline | Злоумышленный PR меняет workflow и крадёт `GITHUB_TOKEN` |
| Excessive permissions | `contents: write` + `pull_request_target` → RCE с секретами |
| Third-party actions | Компрометация `actions/checkout@v3` → supply chain |
| Log leakage | Секрет попадает в stdout → виден в Actions log |

Правило: **минимальные права**, **pin по SHA**, **не запускать недоверенный код с секретами**.

## Базовый secure workflow

```yaml
name: security-ci

on:
  pull_request:
  push:
    branches: [main]

permissions:
  contents: read
  security-events: write

jobs:
  gitleaks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  semgrep:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: returntocorp/semgrep-action@v1
        with:
          config: p/ci

  trivy-fs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: aquasecurity/trivy-action@0.20.0
        with:
          scan-type: fs
          scan-ref: .
          severity: HIGH,CRITICAL
          exit-code: 1
```

## Pin actions по commit SHA

Тег `v4` удобен, для prod лучше SHA:

```yaml
- uses: actions/checkout@b4ffde65f46336ab88eb53be708477a393ebcf0b # v4.1.1
```

Dependabot может предлагать обновления SHA автоматически.

## OIDC вместо static AWS keys

```yaml
permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/github-oidc-role
          aws-region: eu-central-1
```

Роль в AWS доверяет только `repo:your-org/your-repo:ref:refs/heads/main`. Ключи в Secrets **не нужны**.

## Секреты GitHub

| Тип | Когда |
|-----|-------|
| Repository secret | Один проект |
| Environment secret | Staging/prod + approval gates |
| Organization secret | Много репозиториев |

Никогда не echo секреты. GitHub маскирует, но обходы бывают (base64 в лог).

## `pull_request` vs `pull_request_target`

**Опасно:** `pull_request_target` запускает workflow из **base** ветки, но с контекстом PR — секреты доступны для кода из fork.

Безопаснее:

- на fork — только `pull_request` **без** секретов;
- label `safe-to-test` от maintainer для полного CI.

## Code scanning и SARIF

Semgrep/Trivy могут загружать SARIF в Security tab:

```yaml
- uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: semgrep.sarif
```

Это даёт единую панель находок и [audit evidence](../09-compliance/audit-evidence.md).

## Branch protection

Settings → Branches → `main`:

- Require status checks: `gitleaks`, `semgrep`, `trivy-fs`
- Require pull request reviews
- Do not allow bypassing

## Supply chain: Dependabot

`.github/dependabot.yml`:

```yaml
version: 2
updates:
  - package-ecosystem: github-actions
    directory: /
    schedule:
      interval: weekly
  - package-ecosystem: docker
    directory: /
    schedule:
      interval: weekly
```

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

1. Зачем `permissions: contents: read` на уровне workflow?
2. Чем OIDC лучше `AWS_ACCESS_KEY_ID` в Secrets?
3. Почему `pull_request_target` опасен для публичных репозиториев?
4. Что даёт загрузка SARIF в GitHub?

## Дальше

[Trivy, Semgrep, Gitleaks](trivy-semgrep-gitleaks.md) — углубление по каждому сканеру.
