UN NewsWHO releases first global guidelines on child obesity as cases surgeESPN📈 Ovechkin's retirement announcement sparks major ticket price hikePunchBarcelona hails Messi’s remarkable career with ArgentinaThe Jerusalem PostHamam al-Hammami hired by flydubai as part of airline's mass hiring push - reportBollywood HungamaGuneet Monga Kapoor-led Women in Film India and Google Flow join hands to enable AI-powered filmmaking for new creative possibilitiesInquirerDTI maps halal calamansi supply chain in Oriental MindoroCapital FMPharmacists told to be on alert as Kenya confirms imported Ebola caseZDF heuteAktuelle Pressemitteilungen des ZDFCollider‘Mistborn’ Movie Script Is Officially Finished as Brandon Sanderson Reveals Next Step [Exclusive]SDP EspectáculosReseña de Carrie: una buena actualización de Prime Video, pero ¿dónde quedó el horror?Daily MaverickDANCE REVIEW: Elysium — 4 dances of bliss and seduction, transcendence and joy from Cape Ballet AfricaGIGAZINEChatGPTが生成したマンガに「実在するマンガ家の署名」が含まれているとの指摘
The Daily Newsstand · Free, Always
Wednesday, October 7, 2026

Secrets management в Unity: как не хранить ключи сборки и деплоя в Git

Translate

Разбираем, что считать секретом, а что конфигурацией, и как настроить Infisical для Unity‑проекта так, чтобы новый разработчик получал доступ к сборке за пару минут.

Проблемы, которые решает эта статья:

  1. Как безопасно хранить секреты;

  2. Как автоматически собрать production без ручного ввода паролей;

  3. Где взять .env новому разработчику.

В этой статье разберём подход с Infisical, Unity.

В своем опыте стартап‑команд и аутсорса, несмотря на отделы контроля, я встречал хард‑код секретов, либо нежелание какой‑либо автоматизации процесса — ввод данных для подписи Android сборки при каждой сборке по стандартным механизмам Unity.

Вероятно, такое приходилось видеть, потому что в Unity нет штатной интеграции с .env, и разработчики, которые работали только с играми могут о таком понятии и не знать.

1. Как хранят секреты

Существует соглашение: хранить секреты в файле .env в корне проекта, добавляя его в .gitignore, чтобы он не попал в репозиторий git.

Чтобы .env не попадал в git добавьте в .gitignore:

.env
.env.*
!.env.example

Почему секреты не хранят в репозитории:

  • Компрометация при доступе. Передавая репозиторий третьим лицам (например, фрилансерам) или случайно сделав его публичным, вы мгновенно дарите злоумышленникам доступ к своей инфраструктуре.

  • История коммитов. Удаление секретов из кода свежим коммитом не поможет — они останутся в git history. Чтобы их вычистить, придется переписывать историю репозитория.

  • Нарушение безопасности (Least Privilege). Все, у кого есть доступ к коду (включая стажеров), автоматически получают доступ к боевым базам данных и платным API.

Пример .env на Unity проекте выглядит примерно так:

ANDROID_KEYSTORE_PASSWORD=secret
ANDROID_KEY_ALIAS=release
ANDROID_KEY_PASSWORD=secret

ADDRESSABLES_SSH_HOST=cdn.example.com
ADDRESSABLES_SSH_USER=deploy
ADDRESSABLES_SSH_PRIVATE_KEY=/Users/me/.ssh/game_deploy

TELEGRAM_BOT_TOKEN=123456:ABC...
TELEGRAM_CHAT_ID=123456789

И шаблон:

ANDROID_KEYSTORE_PASSWORD=
ANDROID_KEY_ALIAS=
ANDROID_KEY_PASSWORD=

ADDRESSABLES_SSH_HOST=
ADDRESSABLES_SSH_USER=
ADDRESSABLES_SSH_PRIVATE_KEY=

TELEGRAM_BOT_TOKEN=
TELEGRAM_CHAT_ID=

В Git хранится только .env.example, а .env игнорируется

В этом примере.env есть данные для подписи Unity Android сборки, данные SSH для подключения к серверу для загрузки Addressables сборки (догружаемых данных приложения), токен для оповещения в Telegram об окончании сборки.

В Unity не часто используют.env, потому что для того, чтобы хранить данные ключ‑значение — можно создать конфиг ScriptableObject, который можно будет смотреть и редактировать прямо из Unity. Это правда, и редактирование из Unity — плюс. В такие конфиги обычно пишут URL сервера и ключи для аналитики. Однако — не всякая конфигурация является секретом.

Что вообще считать секретом?

Перед тем как подключать secrets manager, стоит разобраться, какие данные туда действительно нужно помещать.

Пример конфигурации (не секрета):

ServerUrl = https://api.example.com
AddressablesUrl = https://cdn.example.com

Если Unity‑клиент обращается к серверу по этому адресу, пользователь всё равно сможет узнать его из приложения или сетевого трафика.

Поэтому production‑конфигурацию вполне нормально хранить в Git. В Unity для этого отлично подходят ScriptableObject.

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

Например:

Данные

Секрет?

Где хранить

ServerUrl

Нет

ScriptableObject

AddressablesUrl

Нет

ScriptableObject

Keystore password

Да

Infisical

Key alias password

Да

Infisical

SSH private key

Да

Infisical

Telegram bot token

Да

Infisical

CI access token

Да

Infisical

2. Как автоматически собрать production без ручного ввода паролей

Предлагаемая структура проекта:

UnityGame/
├── Assets/
│   └── Config/ // Конфигурация
│       ├── DevelopmentConfig.asset
│       ├── StagingConfig.asset
│       └── ProductionConfig.asset
│
├── .env (git-ignored) // Секреты
├── .env.example
└── .gitignore

Конфигурация открыто хранится в Git:

DevelopmentConfig.asset
    ServerUrl = <https://dev-api.example.com>

StagingConfig.asset
    ServerUrl = <https://staging-api.example.com>

ProductionConfig.asset
    ServerUrl = <https://api.example.com>

Чтение.env из Unity

Можно сделать Editor‑only loader: Github Gist

using System;
using System.Collections.Generic;
using System.IO;

public static class EnvironmentLoader
{
    public static Dictionary<string, string> Load(string path)
    {
        if (!File.Exists(path))
            throw new FileNotFoundException(
                $".env not found: {path}");

        var result = new Dictionary<string, string>(
            StringComparer.OrdinalIgnoreCase);

        foreach (var line in File.ReadAllLines(path))
        {
            var trimmed = line.Trim();

            if (string.IsNullOrEmpty(trimmed))
                continue;

            if (trimmed.StartsWith("#"))
                continue;

            var separator = trimmed.IndexOf('=');

            if (separator <= 0)
                continue;

            var key = trimmed[..separator].Trim();
            var value = trimmed[(separator + 1)..].Trim();

            if (value.StartsWith("\"") &&
                value.EndsWith("\""))
            {
                value = value[1..^1];
            }

            result[key] = value;
        }

        return result;
    }

    public static string Required(
        Dictionary<string, string> env,
        string key)
    {
        if (!env.TryGetValue(key, out var value) ||
            string.IsNullOrWhiteSpace(value))
        {
            throw new InvalidOperationException(
                $"Required environment variable is missing: {key}");
        }

        return value;
    }
}

Теперь можно программно настроить Android signing: Github Gist

using UnityEditor;
using UnityEngine;

public static class AndroidSigningConfig
{
    [MenuItem("Build/Load Signing Credentials")]
    public static void Load()
    {
        var env = EnvironmentLoader.Load(".env");

        PlayerSettings.Android.keystorePass =
            EnvironmentLoader.Required(
                env,
                "ANDROID_KEYSTORE_PASSWORD");

        PlayerSettings.Android.keyaliasName =
            EnvironmentLoader.Required(
                env,
                "ANDROID_KEY_ALIAS");

        PlayerSettings.Android.keyaliasPass =
            EnvironmentLoader.Required(
                env,
                "ANDROID_KEY_PASSWORD");

        Debug.Log("Android signing configuration loaded.");
    }
}

Теперь пароль не нужно каждый раз вводить руками через Unity UI. При желании можно добавить [InitializeOnLoad] к классу, чтобы креды вбивались при запуске проекта.

А остальные секреты (при наличии) имплементировать в приложение самому.

На проекте может быть больше использований.env чем заполнить Android signing — например, подключение к серверу для загрузки Asset Bundles, Addressables, Content Directory, правки/просмотра своих реализаций Remote Config, быстрого lookup в аналитику на бекенде, чтобы проверить жив ли какой‑то ивент.

Все эти доступы не должны лежать хардкодом в репозитории.

3. Централизованное хранение секретов

Последняя проблема — файл нужно передавать новым разработчикам, синхронизировать между машинами и CI, ротировать при компрометации. Для таких задач существуют secrets manager. Себе я выбрал Infisical, хотя на рынке популярных вариантов как минимум три.

Настройка

Для начала нужно регнуть учетку infisical, создать компанию, создать проект и секретов в него. Ссылка на US сервер‑ https://app.infisical.com/.

Проблема с которой можно столкнуться

У сервиса несколько субдоменов — на 10.2026 есть как минимум как минимум app. (US server), eu. (EU server). Аккаунты и проекты у них раздельные. Выбирайте одинаковый сервер при работе в веб интерфейсе и интеграции в CLI.

Установка (windows):

winget install infisical
infisical login

Установит пакет, и запустит логин, который откроет браузер для входа. для CI/CD процесс иной, в команду вписываются данные специальной учетки Machine Identity. Для других платформ пакет называется идентично и поддерживает установку через пакетные менеджеры.

Настройка проекта:

cd myProjectPath
infisical init

Это запустит интерактивное создание / привязку к проекту, по итогу в директории появится .infisical.json. Он содержит такое:

{
    "workspaceId": "7a10de5f-ed66-43ff-838d-c88b6926d59a",
    "defaultEnvironment": "",
    "gitBranchToEnvironmentMapping": null
}

Указанные поля по необходимости можно настроить — сопоставление среды к ветки git и среду по стандарту. А workspaceId при необходимости можно посмотреть в настройках проекта в веб интерфейсе и выставить в конфиге.

.infisical.jsonможно коммитить в репозиторий, секретов в нём нет. Далее разработчик может создать секреты в .env файл через команду:

infisical export --format dotenv --output-file=.env

После этого можно Build/Load Signing Credentials в Unity, чтобы вписать данные подписи автоматически.

Что не нужно делать

Не надо складывать в Infisical вообще всё

SERVER_URL, ADDRESSABLES_URL не становятся секретами только потому, что они находятся в .env.

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

Не надо считать client‑side API key настоящим секретом

Если приложение должно содержать:

SENTRY_DSN
FIREBASE_APP_ID
PUBLIC_CLIENT_ID

то secrets manager не сделает их недоступными пользователю.

После сборки они всё равно окажутся внутри приложения.

Не надо сохранять secrets в Unity Assets

Плохо: Прочитал.env, сложил результат в ScriptableObject.

Так секреты попадут в git.

Главная идея

В результате получается довольно простое правило:

Конфигурация приложения хранится вместе с приложением. Credentials для действий от имени команды — отдельно.

Именно такое разделение начинает иметь смысл, когда Unity‑проект перестаёт быть одним локальным проектом разработчика и превращается в production pipeline команды.

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.