Перейти к содержимому

Безопасность и изоляция

Где и как исполняется ваш код — и как это проверить.

Ваш CI выполняется на нашей инфраструктуре, и каждый job — в собственной аппаратно-виртуализированной micro-VM. Эта страница описывает, как именно устроена изоляция, сколько живёт окружение job-а и как самостоятельно проверить образ, на котором исполняется ваш код — без звонка в отдел продаж и без NDA.

Обновлено: 2026-09-27 · v1.6

Модель изоляции

Недоверенный CI-код — ваши шаги сборки и всё, что они порождают, включая Docker-in-Docker — сдерживается несколькими независимыми слоями. Главная граница — micro-VM; остальные слои ограничивают, куда job может дотянуться, и делают попытку побега видимой. Это defense-in-depth, а не «доверьтесь контейнеру».

СлойМеханизмОт чего защищает
Аппаратная micro-VMКаждый раннер-под исполняется в собственной micro-VM со своим гостевым ядром, на Kata Containers. micro-VM — это лёгкая виртуальная машина, а не контейнер с общим ядром.Главная граница. CI-код — и его Docker-in-Docker — не достаёт до ядра хоста и до VM другого job-а.
Сеть по умолчанию закрытаСеть раннера работает deny-by-default, на уровне ядра через eBPF / Cilium. Раннер не может принимать входящие соединения и не дотягивается внутрь кластера: приватные IP-диапазоны, cloud-metadata endpoint, control plane и соседние поды заблокированы — кроме внутреннего pull-through кеша пакетов и образов. Исходящий трафик идёт в публичный интернет.Не даёт двигаться по сети вбок, красть cloud-metadata-токены или дотянуться до внутренних сервисов.
Нет кластерного токенаУ раннера нет токена к оркестратору (Kubernetes API).Эскалации привилегий не на что опереться: даже с root внутри VM у job-а нет кластерного токена, чтобы расширить доступ.
Привилегии нагрузкиКак на GitHub-hosted, job работает от не-root пользователя runner с беспарольным sudo, то есть имеет полный root внутри своей micro-VM — как и движок Docker-in-Docker. Эта привилегия заканчивается на границе VM: ни устройств, namespace’ов и монтирований хоста, ни кластерных учётных данных.Root остаётся внутри собственной VM job-а, вдали от хоста.
Разделение по нодамРаннеры работают на выделенных runner-хостах, физически отдельно от control plane, секретов и данных платформы.Ограничивает радиус поражения: скомпрометированный job — далеко от control plane и данных других клиентов.
Runtime-детекция угрозНа хостах работает runtime-детекция через eBPF / Tetragon: она отслеживает активность, которая указывала бы на выход из VM на хост.Попытка побега становится видимым, зафиксированным событием, а не проходит незаметно.

Мы называем примитивы и объясняем, зачем каждый, но не публикуем стоящие за ними политики, allowlist’ы, версии или топологию. Компоненты держим на актуальном security-floor — конкретные номера версий намеренно не публикуются, поскольку версия маппится на известный набор CVE.

Эфемерность как дизайн

Окружение job-а не переживает сам job.

Граница job-а — это граница доверия.

Supply chain, который можно проверить

Образ, на котором исполняется ваш код, собирается в публичном CI и проверяется независимо — и вам не нужно верить на слово, что внутри.

SLSA build provenance OpenSSF Scorecard Signed with cosign License Apache-2.0

Бейджи ведут на живые аттестации и Scorecard; подпись, provenance и SBOM проверяются командами ниже.

Неизменяемые образы. Неизменяем digest, а не тег: vYYYYMMDD и sha-<commit> могут переводиться пересборкой, а digest’ы без тега со временем удаляются — поэтому закрепляйте vYYYYMMDD@sha256:. На нашей стороне парк раннеров закреплён на конкретный digest, а его подпись и provenance проверяются перед каждой сменой пина.

Каждый образ, собранный из main, подписан cosign keyless (Sigstore — Fulcio + Rekor, через GitHub Actions OIDC) и несёт SLSA build provenance и CycloneDX SBOM-аттестацию. Подпись накладывается только после того, как опубликованный по digest артефакт прошёл trivy-гейт: сборка блокируется на устранимых HIGH/CRITICAL-уязвимостях в пакетах ОС — то есть валидная подпись означает, что образ прошёл CVE-гейт. Образ пересобирается еженедельно со свежими apt-патчами; базу и инструменты обновляет Renovate; раннеры переводятся на новый digest после проверки подписи.

Образ: ghcr.io/tempusbuild/runner-ubuntu-24.04 — теги по дате, без плавающего :latest. На каком образе прошёл job, видно в его логе: Set up job → Runner Image → Version: vYYYYMMDD. Работайте по @sha256:-digest, а не по тегу:

IMAGE=ghcr.io/tempusbuild/runner-ubuntu-24.04
DIGEST=$(docker buildx imagetools inspect "${IMAGE}:vYYYYMMDD" --format '{{.Manifest.Digest}}')

1. Подпись — привязывает образ к нашему build-workflow и к OIDC-issuer’у GitHub. Любая другая identity — не наша сборка:

cosign verify \
  --certificate-identity-regexp '^https://github\.com/tempusbuild/runner-images/\.github/workflows/build\.yml@refs/heads/main$' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  "${IMAGE}@${DIGEST}"

2. Build provenance — Sigstore-подписанная SLSA-аттестация, проверяется через gh CLI:

gh attestation verify "oci://${IMAGE}@${DIGEST}" --owner tempusbuild

3. SBOM (CycloneDX) — cosign-аттестация на тот же digest. SBOM слишком велик для transparency-log, поэтому таймстемпится TSA (RFC3161), а не логируется в Rekor; поэтому проверка пропускает Rekor-lookup, но всё равно проверяет identity, подпись и доверенный таймстемп:

cosign verify-attestation \
  --type cyclonedx \
  --insecure-ignore-tlog \
  --use-signed-timestamps \
  --certificate-identity-regexp '^https://github\.com/tempusbuild/runner-images/\.github/workflows/build\.yml@refs/heads/main$' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  "${IMAGE}@${DIGEST}"

--insecure-ignore-tlog отключает только Rekor-lookup; подпись, identity подписи и RFC3161-таймстемп по-прежнему проверяются. Подпись из шага 1 — криптографический якорь; provenance и SBOM привязаны к тому же digest.

Подпись и provenance записываются в публичный transparency-log Rekor (открывается в новой вкладке). Полный разбор и нашу CVE-политику (открывается в новой вкладке) см. в SECURITY.md репозитория runner-images; build-workflow (открывается в новой вкладке) и весь репозиторий открыты на github.com/tempusbuild/runner-images (открывается в новой вкладке).

Данные и tenancy

Compliance и аудиты

Мы указываем, что есть сегодня и что в роадмапе, — и ничего, чего не заслужили.

Доступно сейчас

В роадмапе

Мы не сертифицированы по SOC 2 или эквиваленту на сегодня. Claim’ы на этой странице — те, что вы можете проверить напрямую уже сейчас. Отчёты об аудитах, когда появятся, предоставляются под NDA:

Запросить security-отчёт — на этой странице нет lead-capture формы.

Ответственное раскрытие

Нашли уязвимость в платформе, образах раннеров или supply-chain-пайплайне? Сообщите ответственно:

Пожалуйста, не открывайте публичный issue по неисправленной уязвимости. Мы подтвердим получение и будем держать вас в курсе триажа и фикса.

Субпроцессоры

Мы используем небольшое число сторонних обработчиков для работы сервиса. Персональные данные обрабатываются только в объёме, нужном для его предоставления.

СубпроцессорНазначениеРасположение
HetznerCompute и бэкапыЕС
GitHubИсходный код, identity (OAuth / GitHub App), доставка CI-секретовСША
MailgunТранзакционная почта и уведомленияЕС
DodoPaymentsОбработка платежей (merchant of record)США
GoogleАналитика сайта (Google Analytics): до вашего выбора — агрегированные сигналы без cookie; cookie — только с согласияСША
YandexАналитика сайта (Yandex Metrica), только с вашего согласияРоссия
SentryМониторинг ошибок: стек ошибок и GitHub id/login; без email и IPЕС (Германия)
OpenRouter (→ Anthropic)LLM-инференс для AI-советника по расходам (включён для всех) — получает агрегированные метрики расходов, имена репозиториев/workflow и текст вопроса, если вы его задаёте; без исходного кода, секретов и данных пользователейСША

Список версионируется; существенные изменения отражаются здесь с датой ревизии выше.