Безопасность и изоляция
Где и как исполняется ваш код — и как это проверить.
Ваш CI выполняется на нашей инфраструктуре, и каждый job — в собственной аппаратно-виртуализированной micro-VM. Эта страница описывает, как именно устроена изоляция, сколько живёт окружение job-а и как самостоятельно проверить образ, на котором исполняется ваш код — без звонка в отдел продаж и без NDA.
Обновлено: 2026-07-24 · v1.1
Модель изоляции
Ни один слой не является единственной границей. Недоверенный CI-код — ваши шаги сборки и всё, что они порождают, включая Docker-in-Docker — сдерживается несколькими независимыми слоями. Если один обойдён, держит следующий. Это 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). | Эскалации привилегий не на что опереться: даже вырвавшись из контейнера, job не найдёт токена, чтобы расширить доступ. |
| Hardening нагрузки | Внутри VM job-контейнер исполняется со сброшенными Linux capabilities, запретом эскалации привилегий (no-new-privileges) и seccomp-профилем. Единственный привилегированный компонент — движок Docker-in-Docker (нужен для сборки образов); его привилегия существует только внутри micro-VM, никогда на хосте (см. Слой 1). | Сужает возможности job-а ещё до границы VM. |
| Разделение по нодам | Раннеры работают на выделенных нодах, физически отдельно от control plane, секретов и данных платформы. | Ограничивает радиус поражения: скомпрометированный job — далеко от control plane и данных других клиентов. |
| Runtime-детекция угроз | На хостах работает runtime-детекция через eBPF / Tetragon — попытки выхода из контейнера и эскалации привилегий. | Попытка побега становится видимым, зафиксированным событием, а не проходит незаметно. |
Мы называем примитивы и объясняем, зачем каждый, но не публикуем стоящие за ними политики, allowlist’ы, версии или топологию. Компоненты держим на актуальном security-floor — конкретные номера версий намеренно не публикуются, поскольку версия маппится на известный набор CVE.
Эфемерность как дизайн
Окружение job-а не переживает сам job.
- Один job — одна свежая VM. Каждый job получает только что созданную micro-VM. Эфемерность означает, что она существует только для этого job-а.
- Уничтожается по завершении. Когда job завершается, VM и всё её содержимое — чекаут кода, окружение, любые секреты, которые в неё попали — уничтожаются.
- Без переиспользования между клиентами. VM никогда не передаётся от одного job-а к следующему. Нет «тёплого» окружения, из которого следующий job мог бы унаследовать остаточный код, кеши или секреты.
Граница job-а — это граница доверия.
Supply chain, который можно проверить
Образ, на котором исполняется ваш код, собирается в публичном CI и проверяется независимо — и вам не нужно верить на слово, что внутри.
Каждый бейдж ведёт на действующую запись — подпись, provenance и SBOM проверяются командами ниже.
Неизменяемые образы. Образы раннеров привязаны по digest (@sha256:), не по плавающему тегу — исполняется ровно тот образ, что вы проверили.
Каждый образ, собранный из main, подписан cosign keyless (Sigstore — Fulcio + Rekor, через GitHub Actions OIDC) и несёт SLSA build provenance и CycloneDX SBOM-аттестацию. Подпись накладывается только после зелёного trivy-скана на HIGH/CRITICAL-CVE для опубликованного-по-digest артефакта — то есть валидная подпись означает, что образ прошёл CVE-гейт.
Образ: ghcr.io/tempusbuild/runner-ubuntu-24.04 — неизменяемые digest-теги, без плавающего :latest. Работайте по @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
- Расположение. Compute и бэкапы — в ЕС (Hetzner).
- Секреты зашифрованы. Секреты Kubernetes зашифрованы at rest в хранилище кластера, операционные учётные данные — через age (sops); в открытом виде не хранятся нигде — ни в Git, ни где-либо ещё.
- В транзите. Дашборд и API отдаются по TLS (Let’s Encrypt), с HSTS. Внутренние endpoint’ы метрик и health недоступны из публичного интернета.
- Секретам вашего CI неоткуда у нас утечь. Мы их не видим и не храним: GitHub доставляет их напрямую в micro-VM вашего job-а, которая уничтожается по его завершении.
- Just-in-time-токены job-а. Раннер получает только короткоживущий per-job registration-токен. Постоянного платформенного токена на раннере нет.
- Данные арендаторов. Данные платформы — история job-ов, балансы, ledger — изолированы по арендаторам, так что данные одного клиента недоступны из контекста другого.
- Хранение и удаление. Метаданные job-ов и security-логи хранятся ровно столько, сколько нужно для метеринга, безопасности и разбора споров, затем удаляются или анонимизируются; биллинговые записи хранятся установленный законом срок. Вы можете запросить удаление аккаунта и персональных данных.
- Восстанавливаемые бэкапы. База непрерывно бэкапится с point-in-time recovery и окном хранения 30 дней.
Compliance и аудиты
Мы указываем, что есть сегодня и что в роадмапе, — и ничего, чего не заслужили.
Доступно сейчас
- Проверяемый supply chain — подписанные образы, SLSA provenance и SBOM, которые можно проверить самостоятельно (выше).
- Открытые образы раннеров — окружение исполнения публично и читаемо.
- Опубликованная политика раскрытия уязвимостей (ниже).
- Публичная статус-страница — аптайм и история инцидентов на status.tempus.build.
В роадмапе
- Независимый аудит изоляции — сторонний пентест модели изоляции.
- SOC 2 — работаем над ним.
Мы не сертифицированы по SOC 2 или эквиваленту на сегодня. Claim’ы на этой странице — те, что вы можете проверить напрямую уже сейчас. Отчёты об аудитах, когда появятся, предоставляются под NDA:
Запросить security-отчёт — на этой странице нет lead-capture формы.
Ответственное раскрытие
Нашли уязвимость в платформе, образах раннеров или supply-chain-пайплайне? Сообщите ответственно:
- Email: security@tempus.build
- security.txt: tempus.build/.well-known/security.txt (RFC 9116)
- Образы раннеров: приватно через GitHub Security Advisories в tempusbuild/runner-images (открывается в новой вкладке)
Пожалуйста, не открывайте публичный issue по неисправленной уязвимости. Мы подтвердим получение и будем держать вас в курсе триажа и фикса.
Субпроцессоры
Мы используем небольшое число сторонних обработчиков для работы сервиса. Персональные данные обрабатываются только в объёме, нужном для его предоставления.
| Субпроцессор | Назначение | Расположение |
|---|---|---|
| Hetzner | Compute и бэкапы | ЕС |
| GitHub | Исходный код, identity (OAuth / GitHub App), доставка CI-секретов | США |
| Mailgun | Транзакционная почта и уведомления | ЕС |
| Dodo Payments | Обработка платежей (merchant of record) | США |
| OpenRouter | LLM-инференс для опциональной функции Advisor — получает агрегированные cost-метрики и структурные метки (например, имена репозиториев и workflow); исходный код и секреты не отправляются, а действующий пользователь псевдонимизирован (хеш) | США |
Список версионируется; существенные изменения отражаются здесь с датой ревизии выше.