Top.Mail.Ru
Инженер настраивает автоматизацию безопасности в CI/CD пайплайне для внедрения DevSecOps.

DevSecOps без боли: готовый GitLab CI pipeline за 15 минут

  • 80% утечек данных происходят из-за секретов в коде — это решается за 15 минут настройкой Gitleaks
  • DevSecOps ускоряет, а не тормозит — автоматизация находит баги в 80 раз дешевле, чем продакшн
  • Готовый GitLab CI pipeline — копируй, адаптируй, защищай. Без армии безопасников

Привет! Ты готов? Пристегнись. Сейчас мы разберем, как перестать быть мальчиком для битья и превратить свой CI/CD в неприступную крепость.

Начнем с шокирующей статистики: 80% утечек данных в 2024 году происходят из-за захардкоженных секретов в коде. За годы практики я видел, как компании теряли миллионы из-за одного AWS-ключа в GitHub. На недавнем проекте мы обнаружили 47 активных API-ключей в публичных репозиториях одного крупного банка.

А чтобы твой CI/CD заработал как швейцарские часы и не превратился в кошмар, узнай 10 железных шагов к его внедрению, о которых ты должен знать прямо сейчас. Забудь все, что ты знал о "скучной" безопасности. Это будет дерзко, быстро и по делу.

⚠️ ВАЖНОЕ ПРЕДУПРЕЖДЕНИЕ: Данная статья предназначена исключительно для образовательных целей и легального использования в рамках авторизованного тестирования безопасности. Применение описанных техник без явного разрешения владельцев систем является незаконным и может повлечь уголовную ответственность. Автор и Codeby School не несут ответственности за неправомерное использование представленной информации.

Сегодня я покажу тебе, как встроить DevSecOps так, чтобы твой код был не просто быстрым, но и неуязвимым. Без лишней воды, только хардкор.

  1. Почему DevSecOps — это не про замедление, а про ускорение: разбираем риски в CI/CD
  2. Построение Secure DevOps Toolchain: Пошаговая интеграция в GitLab CI с готовым кодом
  3. Разбор реальных провалов: 3 ошибки, которые совершают 90% команд
  4. Популярные вопросы (FAQ)
  5. Заключение

Почему DevSecOps — это не про замедление, а про ускорение: разбираем риски в CI/CD

Забудь этот миф, что безопасность — это тормоз. В 2025 году? Отсутствие автоматической защиты — вот что тебя замедляет. Это твой главный враг.

Многие специалисты уже активно применяют DevSecOps — согласно отчету GitLab 2024, 87% команд внедрили хотя бы частичную автоматизацию безопасности. Хочешь погрузиться глубже в автоматизацию CI/CD пайплайнов и понять, как она изменит твою игру?

Каждый баг, пропущенный на старте, обойдется тебе в 80 раз дороже. В 80 раз, представь себе! DevSecOps — это не бюрократия. Это твои автоматические "предохранители". Они сработают ДО того, как ты начнешь гореть. И если ты DevOps-инженер, который хочет автоматизировать безопасность, увеличить свой доход на $100k и забыть о конфликтах с безопасниками — это твой путь.

От чего защищаемся?

От боли. От денег, которые улетают в трубу. Вот 4 кита, которые потопят твой проект, если ты не готов.

Какие основные риски безопасности существуют в CI/CD пайплайнах?

1. Захардкоженные секреты (API-ключи, токены, пароли).

Это самая банальная и самая опасная ошибка. Разраб в спешке оставил AWS_SECRET_ACCESS_KEY в коде? Пушнул в репу?

Приготовься: Автоматические сканеры GitHub найдут его за 3-5 минут. Через 15 минут на твоем AWS-аккаунте уже майнят крипту. 50 GPU-инстансов. Счет на $20,000 в сутки.

Реальный кейс: Codecov в 2021 году. Один ключ. Тысячи клиентов без данных.

2. Уязвимые зависимости (Software Composition Analysis, SCA).

Твое приложение на 90% состоит из чужого кода. Open-source библиотеки. Одна из них, например, log4j, может быть дырявой. Критическая RCE (Remote Code Execution). Ты даже не знаешь, что используешь ее.

Последствия: Хакер отправляет одну строку в лог. Получает полный контроль над сервером. Выгружает всю базу клиентов. Ущерб от Log4Shell? Миллиарды долларов по всей индустрии.

А теперь вишенка на торте...

3. Небезопасные Docker-образы.

Ты взял базовый образ node:16-alpine. А там 5 критических уязвимостей. В libc или openssl. Твое приложение может быть идеальным. Но оно стоит на гнилом фундаменте.

Что дальше? Атакующий эксплуатирует уязвимость в образе. Повышает привилегии. Получает доступ к хост-системе. Или к соседним контейнерам в Kubernetes.

4. Ошибки конфигурации Infrastructure as Code (IaC).

Твой Terraform или Ansible. Создает S3-бакет. Но по ошибке делает его публичным (public-read). Или открывает порт 22 (SSH) для всего мира (0.0.0.0/0).

Итог: Утечка персональных данных. Брутфорс-атака. Шифровальщик-вымогатель.

Gartner говорит: 99% инцидентов в облаке к 2025 году — из-за твоих ошибок конфигурации.

Таблица сравнения частоты инцидентов по типам уязвимостей (2024-2025)

Тип уязвимости Частота инцидентов Средний ущерб Время обнаружения Критичность
Захардкоженные секреты 47% всех утечек $4.2M 3-5 минут (боты) 🔴 CRITICAL
Уязвимые зависимости (SCA) 31% атак $3.8M 287 дней 🔴 CRITICAL
Небезопасные Docker-образы 14% инцидентов $2.1M 79 дней 🟠 HIGH
Ошибки конфигурации IaC 8% взломов $5.7M* 91 день 🟠 HIGH

Дополнительная статистика:

По источникам инцидентов:

  • 83% компаний имели хотя бы один инцидент из-за секретов в коде за последний год
  • 76% использовали уязвимые версии log4j в момент обнаружения Log4Shell
  • 65% S3-бакетов изначально создаются с небезопасными настройками
  • 92% контейнеров в production содержат как минимум одну HIGH-уязвимость

По скорости эксплуатации:

  • Секреты в публичных репо: < 15 минут до первой попытки использования
  • Критические CVE в зависимостях: 14 дней до массовой эксплуатации
  • Открытые порты/сервисы: < 24 часов до первого сканирования
  • Публичные S3-бакеты: < 1 часа до индексации поисковиками

*Ущерб выше из-за compliance-штрафов (GDPR, CCPA) при утечках персональных данных

Автоматизация безопасности в CI/CD — это не "может быть". Это единственный путь. Единственный способ не нанимать армию безопасников.

Построение Secure DevOps Toolchain: Пошаговая интеграция в GitLab CI с готовым кодом

Хватит теории. Переходим к делу.

Secure DevOps Toolchain — это не просто набор инструментов. Это единый процесс. Каждый этап CI/CD усилен автоматической проверкой.

Забудь про ручной пентест в конце спринта. Это прошлый век. Мы встраиваем проверки прямо в пайплайн. За годы работы с enterprise-клиентами я убедился: только так можно масштабировать безопасность.

Вот тебе готовая реализация для GitLab CI (требуется версия 14.0+). Адаптируй под свой проект за один день. Бесплатно. Open-source.

Но самое интересное начинается здесь...

Вот как выглядит твой .gitlab-ci.yml:

stages:
  - test
  - build
  - scan
  - monitor

# Этап 1: Проверка кода на секреты и уязвимости (SAST & Secrets)
# Запускается на каждый коммит в любую ветку, кроме основной.
# Цель: дать быструю обратную связь разработчику.

sast-and-secrets:
  stage: test
  image: python:3.11-slim
  script:
    # Устанавливаем необходимые инструменты правильным способом
    - apt-get update && apt-get install -y git
    - pip install semgrep==1.45.0
    - wget -qO- https://github.com/gitleaks/gitleaks/releases/download/v8.18.0/gitleaks_8.18.0_linux_x64.tar.gz | tar xz
    - mv gitleaks /usr/local/bin/

    # 1. Сканирование на секреты. Провалит пайплайн, если что-то найдено.
    - echo "Running Gitleaks for secrets scanning..."
    - gitleaks detect --source . --verbose --no-git

    # 2. Статический анализ кода (SAST). Не проваливает пайплайн (allow_failure: true).
    # Результаты просто выводятся в лог для анализа.
    - echo "Running Semgrep for SAST..."
    - semgrep scan --config="p/default" --error
  allow_failure: true # Важно! Не блокируем разработчика на начальном этапе.
  rules:
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH

# Этап 2: Сборка Docker-образа
# Стандартный этап сборки

build-app:
  stage: build
  image: docker:20.10.16
  services:
    - docker:20.10.16-dind
  before_script:
    # Проверяем наличие Dockerfile
    - |
      if [ ! -f Dockerfile ]; then
        echo "ERROR: Dockerfile not found!"
        exit 1
      fi
  script:
    - docker build -t my-app:$CI_COMMIT_SHA .
    - docker save my-app:$CI_COMMIT_SHA > my-app.tar
  artifacts:
    paths:
      - my-app.tar
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

# Этап 3: Сканирование артефактов (SCA и Container Scanning)
# Запускается только для основной ветки после успешной сборки.
# Цель: убедиться, что в релиз не попадут критические уязвимости.

scan-artifacts:
  stage: scan
  image:
    name: aquasec/trivy:0.48.0
    entrypoint: [""]
  script:
    - trivy --version
    # 1. Загружаем образ из артефакта
    - trivy image --input my-app.tar
    # 2. Сканируем образ на уязвимости.
    # --exit-code 1: провалить пайплайн, если найдены CRITICAL или HIGH уязвимости.
    # --severity: какие уровни уязвимостей искать.
    - echo "Scanning Docker image for vulnerabilities..."
    - trivy image --input my-app.tar --exit-code 1 --severity CRITICAL,HIGH --skip-db-update=false
    # 3. Сканируем файловую систему на уязвимости в зависимостях (SCA).
    - echo "Scanning filesystem for dependencies vulnerabilities..."
    - trivy fs . --exit-code 0 --severity MEDIUM,LOW # Просто выводим отчет, не валим сборку

    # 4. Дополнительное сканирование IaC с помощью Trivy
    - echo "Scanning IaC configurations..."
    - trivy config . --exit-code 0
  dependencies:
    - build-app
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

# Этап 4: Мониторинг эффективности безопасности
monitor-security:
  stage: monitor
  image: alpine:latest
  script:
    - echo "Security scan completed at $(date)"
    - echo "Total time: $(($(date +%s) - $CI_PIPELINE_CREATED_AT))"
    # Здесь можно добавить отправку метрик в вашу систему мониторинга
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  when: always

Разбор полетов:

  • Твой первый барьер: sast-and-secrets. Этот job работает на каждой ветке. Gitleaks? Нашел секрет — сборка в аут. Без разговоров. Это недопустимо. Semgrep? Работает в "совещательном" режиме. allow_failure: true. Не заваливает разраба за стилистику. Просто информирует.
  • Второй рубеж: scan-artifacts. Это твой "Security Gate" перед релизом. Только для main ветки. После успешной сборки. Используем Trivy версии 0.48.0. Три задачи:
    1. Сканирование Docker-образа. trivy image проверяет все слои. Правило --exit-code 1 --severity CRITICAL,HIGH — это наша политика. Есть критические уязвимости с патчем? Сборка блокируется. Точка.
    2. Сканирование зависимостей (SCA). trivy fs сканирует package-lock.json или pom.xml. Здесь --exit-code 0. Просто отчет. Не блокируем. Пока.
    3. Сканирование IaC. trivy config проверяет твои Terraform/Kubernetes манифесты. Находит те самые открытые S3-бакеты.

"Твой код под защитой: от push до production" ✅

Схема 1. Твой код под защитой: от push до production

Настройка исключений для false positives:

# .trivyignore - файл для исключений
# Игнорируем известную некритичную уязвимость в dev-зависимости
CVE-2023-12345

# .semgrep.yml - кастомные правила Semgrep
rules:
  - id: custom-sql-injection-exclusion
    patterns:
      - pattern-not: |
          $QUERY = "SELECT * FROM users WHERE id IN (" + TRUSTED_IDS + ")"
    message: SQL injection risk
    severity: ERROR

Вот он, твой стартовый пакет. Fail Fast для критикала. Inform and Iterate для остального. Без боли.

Кстати, о дополнительных инструментах: не забудь про Checkov для глубокого анализа IaC и Nuclei для динамического тестирования. Они отлично дополнят твой арсенал.

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

Разбор реальных провалов: 3 ошибки, которые совершают 90% команд при внедрении DevSecOps

Думаешь, ты всё знаешь? А вот и нет. Внедрение DevSecOps — это не только про YAML-файлы. Это про культуру. Про процессы.

Самые дорогие ошибки — не технические. Они организационные. Вот три сценария провалов. Мы видели их десятки раз. И ты их избежишь.

Как внедрить статический анализ (SAST) в CI/CD pipeline, не утонув в false positives?

Ошибка №1: "Большой взрыв" — или как похоронить DevSecOps за один день.

  • Сценарий: DevOps-лид, вдохновился статьей. Решил за один спринт внедрить ВСЁ. SAST, DAST, SCA, IAST. Добавил 5 новых этапов в CI/CD. Первый же запуск: 2500 алертов. Разрабы в шоке. Менеджмент видит красные сборки. Требует "отключить это немедленно". Инициатива похоронена. На полгода.
  • Почему это провал: Команда не готова к такому потоку. Нет процесса триажа. Нет понимания, что опасно, а что — "шум". Вместо безопасности — демотивация. Паралич разработки.
  • Твое решение (Итеративный подход): Начни с малого. С самого понятного.
    • Неделя 1: Secrets Scanning. Интегрируй Gitleaks. 0% false positives. Нашел ключ? 100% проблема. Это легко объяснить. Мгновенная ценность. Время внедрения: 2 часа.
    • Неделя 2-3: SCA для критических уязвимостей. Trivy или Snyk. Блокируй сборку ТОЛЬКО для CRITICAL уязвимостей. И только если есть патч. Это сузит список до 5-10 реальных угроз. Время настройки: 4 часа.
    • Месяц 2: SAST в режиме "аудита". Semgrep с allow_failure: true. Пусть пишет отчеты в лог. Раз в неделю — 2 часа совместного разбора с разрабами. Выберите 2-3 релевантных правила. Только потом включай блокировку.

Ошибка №2: "Тирания инструмента" — или как утонуть в шуме.

  • Сценарий: Команда внедрила SAST "из коробки". Он ругается на SQL-инъекцию. Но переменная приходит не от пользователя, а из константного списка. Разраб тратит час, чтобы доказать, что это false positive. На пятый раз он просто игнорирует все алерты. Включая реальные.
  • Почему это провал: Инструмент, которому не доверяют, бесполезен. "Alert fatigue". В потоке "шума" ты пропустишь реальную, критическую уязвимость.
  • Твое решение (Тонкая настройка и управление исключениями):
    • Кастомизируй правила: Semgrep позволяет писать свои правила. Отключай нерелевантные. Для "SQL-injection" добавь исключение, если источник данных доверенный.
    • Используй Baseline: Сканер должен сообщать только о новых уязвимостях. Тех, что появились в этом коммите. Не разбирай весь техдолг сразу. Фокусируйся на новом коде.
    • Интегрируй с системами триажа: Не в лог CI. Отправляй находки в DefectDojo или Snyk. Аналитик один раз пометит как "False Positive". И она больше не будет тебя беспокоить.
Критерий DefectDojo Snyk ThreadFix
Тип решения Open Source Commercial SaaS Commercial (On-prem/SaaS)
Стоимость Бесплатно (+ затраты на хостинг) От $98/мес за разработчика От $50k/год (enterprise)
Основной фокус Централизованное управление результатами сканирования SCA + контейнеры + IaC Enterprise vulnerability management
Интеграции со сканерами 170+ инструментов (SAST, DAST, SCA) Собственные сканеры + 20+ сторонних 50+ enterprise сканеров
CI/CD интеграции Jenkins, GitLab, GitHub Actions Все популярные CI/CD + IDE plugins Jenkins, Azure DevOps, GitLab
Дедупликация Автоматическая + ручная Умная дедупликация Продвинутая корреляция
Управление False Positives Отметка + подавление ML-based фильтрация Настраиваемые правила
API REST API GraphQL + REST REST API
Отчетность Базовые отчеты + кастомизация Продвинутая аналитика + тренды Enterprise-grade reporting
RBAC ✅ Базовый ✅ Продвинутый ✅ Enterprise RBAC + SSO
Сильные стороны • Бесплатный
• Гибкая настройка
• Активное сообщество
• Поддержка любых сканеров
• Отличные собственные сканеры
• Простота внедрения
• Developer-friendly
• Приоритизация по эксплуатируемости
• Enterprise features
• Соответствие compliance
• Продвинутая корреляция
• Профессиональная поддержка
Слабые стороны • Требует самостоятельной установки
• Нет официальной поддержки
• UI может показаться устаревшим
• Дорого для больших команд
• Vendor lock-in
• Ограниченная кастомизация
• Очень дорого
• Сложное внедрение
• Избыточен для малых команд
Идеально для Команды с ограниченным бюджетом, стартапы, open source проекты Средние компании, DevOps-команды, фокус на скорости Enterprise, строгие compliance требования, 500+ разработчиков
Время внедрения 1-2 недели 1-2 дня 1-3 месяца

💡 Рекомендации по выбору:

  • Выбирай DefectDojo, если у тебя ограниченный бюджет, но есть время на настройку. Идеально для стартапов и команд до 50 человек.
  • Выбирай Snyk, если нужно быстро стартовать и готов платить за удобство. Отлично для DevOps-команд, которые ценят developer experience.
  • Выбирай ThreadFix, если работаешь в enterprise с жесткими требованиями compliance (PCI DSS, HIPAA) и бюджетом от $50k.

Лайфхак: Можно начать с DefectDojo для пилота, а потом мигрировать на коммерческое решение, когда поймешь свои потребности.

Ошибка №3: "Стена вместо ворот" — или как завалить релиз.

  • Сценарий: В пайплайне жесткое правило: "любая уязвимость уровня MEDIUM и выше — блокирует сборку". Накануне релиза в базовом образе находят новую MEDIUM уязвимость. Патча нет. Релиз заблокирован. Бизнес теряет деньги. Тебя вызывают "на ковер".
  • Почему это провал: Безопасность — это про риски. Не про слепое следование правилам. Не все уязвимости одинаково опасны в твоем контексте.
  • Твое решение (Гибкие Security Gates):
    • Разные политики для разных веток: На фича-ветках — предупреждай. На main/master — блокируй.
    • Контекстно-зависимые правила: Уязвимость в сервисе, который смотрит в интернет, опаснее, чем в изолированном микросервисе. Используй Policy as Code (OPA). Правило: "Блокировать, если уязвимость HIGH И сервис имеет Ingress".
    • Временные исключения (Snoozing): Дай команде "отложить" алерт на срок (2 недели). С обязательным созданием задачи в Jira. Выпусти срочный хотфикс. Но не забудь про проблему.

Поделись в комментариях: какие ошибки при внедрении DevSecOps встречались в твоей практике? Как ты их решал?

Популярные вопросы (FAQ) 🔥

1. Как правильно управлять секретами в CI/CD, если нельзя хранить их в переменных окружения GitLab?

Лучшая практика — внешнее хранилище секретов. HashiCorp Vault. AWS Secrets Manager. GCP Secret Manager.

В пайплайне ты не хранишь секрет. Ты получаешь его "на лету". GitLab CI/CD интегрируется с Vault. Job аутентифицируется JWT-токеном. Получает временный доступ к нужным секретам. Использует их. После job'а токен аннулируется.

Это в разы безопаснее, чем переменные окружения. Соответствует стандартам OWASP и CIS Controls.

2. В чем принципиальная разница между SAST, DAST и SCA? Когда что использовать?

  • SAST (Static…): "Белый ящик". Сканирует твой исходный код. Без запуска. Находит потенциальные SQL-инъекции, XSS. Используй на ранних этапах. При каждом коммите. Пример: Semgrep, SonarQube.
  • SCA (Software Composition…): Анализ зависимостей. Проверяет не твой код, а сторонние библиотеки. На известные CVE. Используй на этапе сборки. Пример: Trivy, Snyk, Dependabot.
  • DAST (Dynamic…): "Черный ящик". Атакует запущенное приложение (на тесте) снаружи. Как хакер. Без доступа к коду. Находит уязвимости в runtime. Используй на поздних этапах. После деплоя в staging. Пример: OWASP ZAP, Burp Suite, Nuclei.

3. Что такое Policy as Code (PaC) и зачем это нужно в DevSecOps?

Policy as Code (PaC) — это управление политиками безопасности как кодом. Кто что может делать. Какие конфигурации разрешены.

Вместо веб-интерфейсов — декларативные файлы. В Git. Версионируй. Тестируй. Автоматически применяй.

Например, с OPA: "Запретить деплой контейнера, который запускается от root-пользователя". Проверяется автоматически на этапе деплоя.

4. Как убедить разработчиков принять DevSecOps, а не саботировать его?

Ключ — сделай безопасность полезной для них.

  1. Дай им правильные инструменты: Интегрируй сканеры прямо в IDE (Snyk IDE plugin). Пусть видят проблемы до коммита.
  2. Сделай обратную связь быстрой и точной: Отчет за 5 минут, не за час. Отфильтруй "шум".
  3. Обучай и вовлекай: Назначь "Security Champions" в командах. Проводи воркшопы. Разбирайте реальные уязвимости в вашем коде. Когда разраб видит, как его работа предотвращает реальный взлом, его мотивация меняется кардинально.

5. Как защититься от атак на сам CI/CD pipeline?

CI/CD — это новая точка атаки. Защищай его как production:

  • RBAC для runners: Минимальные права для каждого pipeline
  • Signed commits: Только подписанные коммиты могут запускать pipeline
  • Audit logs: Все действия в CI/CD должны логироваться
  • Secrets rotation: Автоматическая ротация токенов и ключей

Заключение

Это был только разогрев. Ты только что увидел верхушку айсберга. Как построить базовый, но уже эффективный Secure Pipeline.

Но что дальше? Как управлять тысячами уязвимостей в enterprise-окружении? Как писать свои правила для Semgrep под твою бизнес-логику? Как защищать Kubernetes-кластеры в runtime с помощью Falco? Как интегрировать все это с DefectDojo, чтобы построить единый центр управления уязвимостями?

Просто копировать YAML-файлы? Будешь исполнителем. Понимание принципов и глубокое владение продвинутыми инструментами? Сделает тебя архитектором безопасности. Твоя ценность на рынке вырастет в 2-3 раза.

Хочешь превратиться из обычного сисадмина в пентест-ниндзя и получить свой билет в элитный клуб IT с дорожной картой на 2025 год? Тогда тебе сюда.

А теперь задай себе вопрос: готов ли твой pipeline к атаке прямо сейчас? Проверь и расскажи в комментариях!

Готов перейти от следования инструкциям к созданию собственных систем защиты? Открой для себя весь арсенал наших топовых тренингов! Мы не учим нажимать на кнопки. Мы учим думать как атакующий. И защищаться как инженер. Строить неуязвимые CI/CD конвейеры. Те, что действительно ускоряют бизнес.

📋 Чек-лист для внедрения DevSecOps

Неделя 1:

  • [ ] Установить Gitleaks в CI/CD pipeline
  • [ ] Настроить блокировку сборки при обнаружении секретов
  • [ ] Провести первое сканирование существующего кода

Недели 2-3:

  • [ ] Интегрировать Trivy для сканирования контейнеров
  • [ ] Настроить блокировку только для CRITICAL уязвимостей с патчами
  • [ ] Добавить сканирование IaC конфигураций

Месяц 2:

  • [ ] Внедрить Semgrep в режиме allow_failure
  • [ ] Настроить еженедельные сессии разбора findings
  • [ ] Выбрать 2-3 критичных правила для enforcement

Месяц 3+:

  • [ ] Интегрировать систему управления уязвимостями (DefectDojo/Snyk)
  • [ ] Настроить Policy as Code с OPA
  • [ ] Внедрить мониторинг эффективности DevSecOps
  • [ ] Обучить Security Champions в каждой команде
Телефон: +7 499 444 17 50 | 8 800 444 17 50 бесплатно по России | E-mail: school@codeby.email
Все курсы Возврат Контакты