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

Быстрое решение: обычные настройки храните в переменных среды, чувствительные значения помечайте как Secret и назначайте только тем рабочим процессам, которым они действительно нужны; если вам необходимы сохраняемое состояние или интерактивная диагностика, отдельно оцените удалённую среду Mac.

Эта статья для вас, если вы запускаете сборки или тесты в Xcode Cloud и передаёте настройки в собственные скрипты. Она пригодится небольшой команде, которой нужно повторно использовать переменные между рабочими процессами, и ответственному за выпуск, который хочет ограничить риск утечки учётных данных.

01

До настройки: отделите параметры от секретов и файлов

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

До создания переменных разделите данные на три группы.

  • Обычные параметры — например, название конфигурации или флаг, переключающий необязательный этап. Их можно передавать как пользовательские переменные среды, если само значение не раскрывает конфиденциальную информацию.
  • Секреты — токены доступа, пароли и другие данные, по которым можно обратиться к внешнему сервису или учётной записи. Для них используйте настройку Secret, а не обычную переменную.
  • Файлы и состояние проекта — конфигурационные файлы, сертификаты и другие ресурсы, которые скрипту нужно открыть как файл. Не считайте, что переменная среды автоматически создаёт файл или помещает его в каталог проекта. Продумайте безопасный способ получить и использовать такой ресурс отдельно.

В справочнике Apple по переменным среды Xcode Cloud перечислены переменные, доступные во время сборки. Используйте его, чтобы отличать предопределённые значения платформы от переменных, которые вы создаёте сами. Не переопределяйте предопределённое значение только потому, что имя кажется удобным: сначала проверьте его назначение и область действия.

У переменной есть как минимум два вопроса, не связанных с её названием: кто может её изменить и какие сборки могут её использовать. Secret помогает защитить значение от вывода в журнал, но сам по себе не заменяет проверку прав, источника запуска и логики скрипта. Если сборке не требуется доступ к внешней системе, не передавайте ей соответствующее учётное значение.

02

Настройка пользовательских переменных Xcode Cloud и ограничение области доступа

Для одного рабочего процесса обычно достаточно переменной, назначенной этому рабочему процессу. Общую переменную имеет смысл использовать, когда несколько рабочих процессов действительно нуждаются в одном значении. Совместное использование не означает, что доступ следует выдавать всем рабочим процессам проекта.

В настройках рабочего процесса добавьте пользовательскую переменную и проверьте её тип. Для несекретного значения оставьте обычный режим. Для чувствительного включите режим Secret. Затем убедитесь, что переменная назначена целевому рабочему процессу, а право редактировать настройки есть у тех участников команды, которым оно необходимо. Точные названия элементов интерфейса и доступные действия сверяйте с текущей официальной документацией Apple по рабочим процессам Xcode Cloud.

Если один и тот же параметр нужен нескольким рабочим процессам, рассмотрите общую переменную. Создайте её, назначьте только нужным рабочим процессам и отдельно проверьте, что каждый из них действительно должен получать это значение. Apple описывает такой порядок в инструкции о том, как делиться переменными среды между рабочими процессами Xcode Cloud.

Вариант Где уместен Что проверить перед сохранением
Пользовательская переменная одного рабочего процесса Значение требуется конкретной сборке или тестовому процессу Переменная назначена именно этому рабочему процессу, а значение не содержит секрета
Общая переменная Одно значение нужно нескольким выбранным рабочим процессам Каждому назначенному процессу действительно нужен доступ; права на редактирование соответствуют обязанностям команды
Переменная с настройкой Secret Значение даёт доступ к сервису или учётной записи Секрет не печатается скриптом, а сценарии запуска с таким доступом проверены отдельно
Предопределённая переменная Скрипту нужны сведения о текущем запуске или окружении Имя и назначение сверены с официальным справочником; переменная не подменена пользовательской

Чтобы решить, какую область выбрать, пройдите по цепочке «значение — потребитель — право». Если значение используется одним процессом, оставьте его локальным для этого процесса. Если его читают несколько, разрешите доступ только им. Если оно позволяет обращаться к внешнему ресурсу, пометьте его как Secret и проверьте, кому разрешено менять настройки. В документации Apple о стратегии рабочих процессов и правах редактирования отдельно рассмотрены планирование процесса и управление доступом к его настройкам.

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

Как добавить собственную переменную среды в Xcode Cloud?

Откройте настройки нужного рабочего процесса, добавьте переменную с понятным именем, задайте значение и проверьте, требуется ли режим Secret. После этого сохраните настройки и убедитесь, что переменная назначена именно тому процессу, который запускает скрипт. Путь в интерфейсе со временем может меняться, поэтому ориентируйтесь на актуальное описание Apple, а не на старый снимок экрана или инструкцию для другой версии интерфейса.

Называйте пользовательские переменные так, чтобы их назначение было очевидно команде, но не включайте в имя само секретное значение, пароль или токен. Не вставляйте учётные данные в скрипт, репозиторий или диагностическое сообщение. Если переменная относится к конкретной задаче выпуска, не переносите её в общую область «на всякий случай».

Могут ли несколько рабочих процессов использовать одну переменную?

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

03

Как пользовательский скрипт читает переменные на разных этапах?

Пользовательские скрипты Xcode Cloud выполняются на разных этапах рабочего процесса. Apple документирует три точки, с которыми часто работают команды: post-clone, pre-xcodebuild и post-xcodebuild. Их назначение и доступный контекст могут отличаться, поэтому нельзя предполагать, что переменная, ресурс или уже созданный артефакт одинаково доступны в каждом скрипте. Сверьте свой сценарий с документацией Apple по пользовательским скриптам сборки и описанием этапов рабочего процесса.

Выбирайте этап по тому, когда результат нужен:

  • post-clone подходит для действий после получения проекта, например подготовки зависимостей. Не размещайте здесь логику, которой нужен готовый результат сборки.
  • pre-xcodebuild предназначен для обработки непосредственно перед запуском Xcode. Используйте его, если проверка или подготовка должны завершиться до компиляции.
  • post-xcodebuild запускается после этапа Xcode. Здесь могут выполняться действия с результатом сборки, если нужные файлы действительно доступны в контексте этого этапа.

Уточняйте формат скрипта и расположение файлов по документации Apple. Не полагайтесь на переменную, путь или инструмент только потому, что они присутствовали в локальном терминале: среда облачной сборки может отличаться. В частности, проверьте, где находится скрипт, как проект получает его ресурсы и какие переменные доступны в выбранном контексте. В документации Apple также описаны вспомогательные инструменты и причины ошибок в среде Xcode Cloud; это полезно, если скрипт рассчитывает на утилиту или состояние, которого нет в среде сборки.

Внутри shell-скрипта переменную обычно читают через синтаксис оболочки, например $SERVICE_TOKEN. Но сначала решите, какое поведение нужно при её отсутствии. Для обязательного секрета безопаснее завершить задачу с понятной ошибкой, чем продолжить с пустым значением или подставить тестовые учётные данные. Для необязательного параметра можно явно задать безопасное значение по умолчанию, если оно не меняет политику доступа и не маскирует ошибку конфигурации.

Пример проверки без вывода секрета:

if [ -z "${SERVICE_TOKEN:-}" ]; then
  echo "Не задан обязательный токен сервиса"
  exit 1
fi

./upload-artifact.sh

Здесь сообщение сообщает о проблеме, но не печатает значение переменной. До запуска скрипта отдельно проверьте, что upload-artifact.sh не выводит токен в диагностике и не включает его в командную строку или сформированный отчёт.

Почему пользовательский скрипт не видит переменную Xcode Cloud?

Сначала проверьте назначение переменной целевому рабочему процессу и этап, на котором запускается скрипт. Затем сверьте точное имя, регистр символов и способ чтения в используемой оболочке. Если переменная общая, проверьте, что её назначили именно нужному процессу. Если скрипт ожидает файл, а вы передали только текстовое значение, проблема не в доступе к переменной: скрипту требуется отдельный способ получить файл.

Не выводите секрет целиком ради диагностики. Временно проверьте наличие значения условием и печатайте только нейтральный статус: «переменная задана» или «переменная отсутствует». Если ошибка сохраняется, добавьте безопасную диагностику этапа и ожидаемого имени. Сверьте вывод скрипта с официальным справочником переменных Xcode Cloud, а затем проверьте отчёт запуска и код завершения процесса.

04

Как проверить Secret, журналы и границы доступа до выпуска?

Проведите проверку сначала на тестовом рабочем процессе, не используя действительные учётные данные. Для обычной пользовательской переменной задайте заметное, но безвредное значение и убедитесь, что скрипт получает его в ожидаемом месте. Для проверки обработки Secret используйте тестовую строку, которую не жалко раскрыть, и проверьте, как именно она отображается в журнале. Не проводите такой эксперимент с действующим токеном.

Проверяйте не только строку журнала, но и весь путь данных:

  • нет ли значения в echo, отладочном выводе или сообщении об ошибке;
  • не сохраняет ли скрипт переменную в файл, который попадёт в артефакт;
  • не включает ли внешний инструмент переданные аргументы в собственный журнал;
  • завершает ли сценарий работу, когда обязательная переменная отсутствует;
  • можно ли понять причину сбоя по отчёту без раскрытия секрета.

Настройка Secret не должна превращаться в единственный барьер защиты. Скрытие значения в журнале и право скрипта использовать значение — разные задачи. Если процесс получил доступ к токену, его код может отправить запрос с этим токеном; значит, нужно ограничить круг рабочих процессов и запусков, которым он назначен, а не только рассчитывать на маскирование текста. Apple даёт рекомендации по содержимому журналов пользовательских скриптов в материале о том, как сообщать об ошибках Xcode Cloud и передавать сведения для диагностики.

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

05

Перед выпуском: какие запуски должны получать секрет?

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

Не делайте вывод о безопасности только по тому, что переменная помечена Secret. Проверьте источник запуска, конфигурацию рабочего процесса, назначенные значения и последствия пользовательского кода. Если команда использует разные процессы для проверки изменений и выпуска, не объединяйте их только ради сокращения настроек. Разделение позволяет назначать секрет лишь процессу, где он нужен, и проще проверять, почему конкретный запуск получил доступ.

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

06

Критерии перехода от Xcode Cloud к отдельной среде Mac

Оставляйте сборку в Xcode Cloud, если рабочий процесс укладывается в предоставленные этапы, настройки и доступный контекст, а собственным скриптам достаточно передать конфигурацию и выполнить ограниченные действия. Меняйте скрипт, если проблема вызвана небезопасным выводом, неверным этапом запуска или чрезмерно широкой областью доступа. Рассматривайте отдельную среду Mac, если проверенная задача требует постоянно сохраняемого состояния, интерактивной отладки или особого управления системой, которого не хватает существующему процессу.

Не исходите из того, что любая облачная сборка обязательно ограничена для вашего сценария или, наоборот, подходит без проверки. Зафиксируйте конкретное требование, воспроизведите его в рабочем процессе и сравните результат с возможностями среды. Для задач, где нужно самостоятельно исследовать состояние сборки и управлять macOS-средой, можно изучить описание удалённого Mac от KVMNODE. Это дополнительный вариант, а не обязательная замена Xcode Cloud.

У удалённого Mac тоже есть компромиссы. Вам нужно организовать доступ, обновление и обслуживание среды, а также отдельно выстроить безопасную работу с сертификатами и токенами. Для краткого эксперимента без потребности в сохраняемой среде такие действия могут быть лишними. Если же вы сравниваете варианты аренды, проверьте условия заказа Mac у KVMNODE и соотнесите их со своими требованиями к доступу и сроку работы; не переносите секреты в новую среду без той же проверки прав и журналов.

Перед тем как оставить конфигурацию в работе, сохраните для команды короткую запись: какие переменные являются секретами, каким рабочим процессам они назначены, на каком этапе читаются и как выглядит безопасный сбой при отсутствии значения. Так вы сможете менять скрипт или состав процессов без угадывания, кто ещё использует учётные данные.

Если Xcode Cloud закрывает ваши задачи и не требует сохраняемого состояния или интерактивного управления, оставьте сборку там и сузьте доступ к секретам. Если же тестирование регулярно упирается в необходимость управлять постоянной macOS-средой или разбирать сборку интерактивно, сравните этот сценарий с удалённым Mac от KVMNODE — после проверки требуемого доступа, обслуживания и процесса хранения учётных данных.