Поставка софта Открытый код как способ поставки: что даёт и чего стоит
0%

Открытый код как способ поставки: что даёт и чего стоит

Открытый код как способ поставки: что даёт и чего стоит

Я поднял на своём сервере инстанс it-tools — набор инженерных утилит в браузере: генераторы токенов, конвертеры, калькуляторы подсетей. Форкнул, прикрутил свою тему, собрал, выложил на поддомен. Работы на вечер, пользы много, денег ноль.

Через некоторое время выяснилась деталь, которую я в этот вечер не заметил. it-tools лежит под GPL-3.0, а это клиентское приложение: сервер отдаёт браузеру собранный минифицированный бандл — объектный код, произведённый из GPL-исходников. GPL-3.0 привязывает обязанность отдавать исходники именно к передаче объектного кода: не к «использованию», не к «размещению» — к передаче. Каждый посетитель получал у меня объектный код и вместе с ним право получить соответствующий исходник. Ссылки в подвале не было.

Починка заняла пять минут: ссылка на форк и упоминание GPL-3.0 в футере. Но урок стоит того, чтобы его развернуть. Открытый код — не «бесплатно», а другая структура издержек и обязательств. Обязательства возникают в момент поставки, а не в момент, когда о них вспомнили, и зависят не только от текста лицензии, но и от архитектуры: тот же GPL-3.0 в серверном приложении, которое отдаёт браузеру только HTML, ведёт себя совершенно иначе.

Предыдущая глава — Лицензии как инженерное ограничение — разбирала, что лицензия разрешает и запрещает делать с кодом. Эта глава про уровень выше: открытый код как канал поставки наравне с коробкой, SaaS и self-hosted из главы о моделях — со своей ценой владения по обе стороны, своими способами брать деньги и своими режимами отказа.

Четыре разные вещи, которые называют одним словом

Разговор про «сделать проект опенсорсным» буксует, потому что участники обсуждают разные вещи. Их четыре, и они ортогональны.

Что это Решение о чём Можно ли поменять потом
Лицензия Какие права вы даёте получателю кода Только вперёд для новых версий; выданное не отзывается
Открытая разработка Видно ли историю, обсуждения, планы, а не только релизы Легко в обе стороны
Приём вклада Берёте ли вы чужие PR и на каких условиях Легко, но влияет на права: чужой код — чужой правообладатель
Модель денег Кто и за что платит Труднее всего: у людей уже сложились ожидания

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

Что получает потребитель — и чем он на самом деле платит

Со стороны покупателя открытая поставка выглядит как «то же самое, но бесплатно». Неверно в обе стороны: он получает больше, чем функциональность, и платит больше, чем ноль.

Что он получает сверх функциональности: право уйти (вендор поднимет цену или закроется — код останется, и форк тут рабочий сценарий, ниже разберём реальные); право посмотреть (служба безопасности читает код, а не верит на слово — для регулируемых отраслей иногда единственный способ пройти согласование); право починить критичный баг своим патчем сегодня; и отсутствие переговоров — инженер ставит и пробует, не проходя закупку. На последнем и строится вся модель «сначала бесплатно, потом договор».

Чем он платит:

Статья Что реально происходит
Интеграция Никто не настроит под вас: конфиги, схемы, миграции — ваша работа
Обновления Апгрейд между мажорными версиями делаете вы, ломающие изменения читаете в CHANGELOG
Уязвимости Отслеживать CVE в зависимостях — ваша обязанность, см. цепочку поставки
Эксплуатация Дежурство, бэкапы, мониторинг — весь SRE-контур на вас
Отсутствие SLA Мейнтейнер не обязан ответить. Никогда. Это прямо написано в лицензии заглавными буквами
Риск проекта Мейнтейнер выгорит, проект заархивируют — план на этот случай тоже ваш

Отсюда рабочее определение: открытая поставка перекладывает операционную стоимость с поставщика на потребителя, а взамен отдаёт ему контроль. Крупному банку это выгодно — инженеры есть, контроль критичен; команде из трёх человек часто нет — они переплатят временем больше, чем стоила бы подписка (модели поставки, стоимость платформы).

Что это стоит поставщику: счёт, которого нет в закрытой поставке

Считают, что открытие кода — «просто нажать Public». Нажать просто; дальше начинается работа, которой в закрытом проекте физически нет.

Обращения

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

$$L = U \cdot r \cdot t$$

где $U$ — активные установки, $r$ — доля установок, порождающих обращение за месяц, $t$ — среднее время на обращение вместе с воспроизведением. Порядок величин из практики: $r$ для инфраструктурного инструмента живёт в диапазоне одного–пяти процентов в месяц, $t$ — от пятнадцати минут (дубль, закрыть ссылкой) до нескольких часов (воспроизвести на чужой платформе). Тысяча установок превращается в десятки часов в месяц — четверть инженера, которую никто не закладывал. Асимметрия в том, что обращения приходят от всех, а деньги — от немногих: в закрытой поставке поддержка масштабируется вместе с выручкой, потому что и то, и другое привязано к договору, в открытой они расходятся с первого дня.

Обратная совместимость

Как только код опубликован, каждая экспортированная функция, каждый ключ конфига и каждое имя поля в JSON становятся публичным контрактом. Внутри закрытого продукта переименование поля — задача на полчаса и один pull request; в открытом это ломающее изменение, мажорная версия, раздел в миграционном гайде и полгода вопросов «а как теперь» (обновления и версии).

Публичная безопасность

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

Практически это значит: нужен SECURITY.md с адресом и обещанным сроком ответа, приватный канал для фикса (в GitHub — private security advisory с приватным форком), список поддерживаемых веток и готовность выпустить патч сразу в несколько из них. Если процесса нет, исследователь опубликует находку через положенные девяносто дней, и это будет ваша проблема, а не его (цепочка поставки).

Сборки под чужие условия

Пользователи придут с ARM, с musl вместо glibc, со старым ядром, с корпоративным прокси и самоподписанным сертификатом. В закрытой поставке вы объявляете список поддерживаемых конфигураций и всё; в открытой список объявить можно, но issue придут всё равно — и матрица CI растёт, а с ней время сборки и счёт за раннеры (упаковка, реестры). Взамен вы получаете дистрибуцию, доверие, найм и обратную связь, которой в закрытой поставке не бывает.

Пять способов брать деньги — каждый со своей ценой владения

Модель Что покупает клиент Чем платит поставщик Где ломается
Пожертвования Ничего, это подарок Почти ничем Не превращается в доход
Поддержка и сборки Ответ и подпись под SLA Людьми: рост линейный Маржа сервисного бизнеса
Двойное лицензирование Освобождение от копилефта Правами: вклады только через CLA Не работает для сервисов
Open core Корпоративные функции Двумя сборками и границей Границу не сдвинуть вверх
Управляемый хостинг Отсутствие эксплуатации Инфраструктурой и дежурством Конкуренция с гиперскейлером

1. Пожертвования и спонсорство

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

Механизм комиссий (проверяйте на дату — они меняются). GitHub Sponsors на момент 2026 года не берёт собственной платформенной комиссии с получателей-физлиц в поддерживаемых регионах, но платёжный процессинг вычитается — порядок двух-трёх процентов плюс фиксированная часть с платежа. Open Collective работает через фискального хоста, и долю берёт хост: типичный порядок пять–пятнадцать процентов. Liberapay комиссии не берёт вовсе. Суммы честно: распределение с очень длинным хвостом — медианный проект собирает единицы долларов в месяц, известный проект с десятками тысяч звёзд сотни или тысячи, единицы проектов доходят до десятков тысяч. Цифры публичные: посмотрите три-четыре проекта вашего размера, прежде чем строить планы. Как источник дохода пожертвования работают для считанных проектов, как компенсация расходов на инфраструктуру — для многих. История сопровождающего core-js, получавшего при миллиардах загрузок в год низкие тысячи долларов в месяц, — норма распределения, а не исключение.

2. Поддержка, сертифицированные сборки, обучение

Покупателю это даёт телефон, по которому ответят, подпись под сроком реакции, юрлицо для закупки и сборку, которую кто-то протестировал и обязуется патчить N лет. Поставщику — это сервисный бизнес, масштабируемый людьми, а не копиями: дежурство, эскалации, LTS-ветки с бэкпортами, база знаний; маржа ниже, чем у софта, рост линейный, экономика как у консалтинга из юнит-экономики. Обязательство: SLA — это то, за что можно судиться; прежде чем писать «ответ в течение четырёх часов», посчитайте, сколько людей нужно для круглосуточного покрытия (арифметика дежурства).

3. Двойное лицензирование

Ядро под сильным копилефтом (GPL/AGPL) плюс возможность купить у правообладателя ту же вещь под коммерческой лицензией без копилефтных обязательств. Классика — Qt, MySQL, iText.

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

Как считается цена. Якорь — не себестоимость, а то, чего покупатель избегает: раскрытия своего кода. Поэтому цена привязана к рабочему месту разработчика в год или к продукту в год; порядок величин для инфраструктурной библиотеки — тысячи долларов США за разработчика в год, для нишевой узкоспециальной — десятки тысяч за продукт. Точных цифр здесь не будет: они у каждого поставщика свои и меняются.

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

4. Open core

Открытое ядро плюс закрытые модули. Самая распространённая и самая коварная модель.

Граница open core в кодовой базе

Инженерное решение здесь одно: где провести границу — и принимается оно в коде, а не на слайде. Рабочий признак: в открытой части всё, что нужно одному человеку или одной команде; в платной — всё, что нужно организации. SSO, аудит-лог, RBAC, политики хранения, отчёты для аудитора, multi-region — признаки организации, а не нагрузки. Увести за границу то, что нужно одиночке, — получить форк; увести то, что нужно только компании с внутренним регламентом, — получить покупателя, который и так шёл через закупку. Спор про «налог на SSO» существует ровно потому, что многие считают безопасность аутентификации базовой функцией, и цена этого решения репутационная. Технически граница держится точками расширения: ядро знает интерфейс, но не знает реализаций, а сборки различаются тегом.

// core/auth/provider.go — открытая часть, Apache-2.0.
// Ядро объявляет контракт и не знает, кто его реализует.
package auth

// Provider проверяет учётные данные и возвращает субъект.
type Provider interface {
    Name() string
    Authenticate(ctx context.Context, creds Credentials) (*Subject, error)
}

var registry = map[string]Provider{}

// Register вызывается из init() любого модуля — открытого или закрытого.
// Коммерческий ee/saml собирается с тегом enterprise; в открытой сборке
// файл с тегом !enterprise регистрирует заглушку, которая объясняет, что
// модуль платный, и напоминает: интерфейс открыт, свою реализацию SAML
// написать можно — это нормальный сценарий, а не обход защиты.
func Register(p Provider) { registry[p.Name()] = p }

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

5. Управляемый хостинг

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

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

Перелицензирование и форк: механика, а не мораль

Почему уходят. Компания вкладывает в разработку и хочет, чтобы деньги за хостинг её кода шли ей; открытая лицензия этому не мешает никак — гиперскейлер имеет полное право поднять сервис на её коде. Ответ: сменить лицензию на такую, которая это запрещает. SSPL требует открыть весь код обвязки сервиса; BUSL прямо запрещает конкурирующее предложение, но через несколько лет сам превращается в открытую лицензию. Ни SSPL, ни BUSL не являются open source в определении OSI, и это не придирка терминологии: от этого зависит, попадёт ли пакет в дистрибутивы, пройдёт ли закупку с требованием открытости и пустят ли его в чужой продукт.

Что происходит дальше — предсказуемо.

Три вывода. Права, выданные ранее, не отзываются — смена лицензии действует только на будущие версии, поэтому форк всегда возможен, вопрос лишь в том, найдутся ли люди, готовые его тянуть. Форк побеждает не по коду, а по мейнтейнерам и упаковке: OpenTofu и Valkey выжили, потому что за ними встали фонд и несколько компаний с оплаченными инженерами, а проект, форкнутый тремя энтузиастами, обычно затухает за год. Возврат к открытой лицензии форк не отменяет — Elastic вернул AGPL, но OpenSearch никуда не делся, и доверие тратится быстрее, чем восстанавливается.

Для потребителя отсюда следует, что лицензия зависимости — переменная с риском изменения: для критичных зависимостей стоит заранее знать, кто правообладатель и есть ли CLA (то есть может ли один субъект сменить лицензию в одиночку). Проект под управлением фонда предсказуемее.

Обязательства, которые возникают в момент первой публикации

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

Права на чужой вклад. Приняв первый чужой PR, вы получили в кодовую базу код чужого правообладателя. Развилка: DCO (строчка Signed-off-by) — контрибьютор утверждает, что вправе отдать код под лицензией проекта, права остаются у него; дёшево, принято в ядре Linux, но сменить лицензию в одиночку вы уже не сможете. CLA — контрибьютор передаёт вам права или даёт широкую лицензию; открывает двойное лицензирование и смену лицензии, но стоит трения при первом вкладе. Выбор определяет, какие модели денег будут доступны через три года. Формулировки CLA — вопрос к юристу; задача для него: «нужен документ, позволяющий нам выпускать вклады участников под другой лицензией, включая коммерческую, с сохранением у автора права использовать свой код».

Поддерживаемые версии. Опубликовав релиз, вы неявно пообещали, что он работает; явное обещание лучше — таблица версий с датами конца поддержки, политика бэкпорта фиксов безопасности, правило депрекации (обновления, безопасные релизы).

Воспроизводимость и подпись. Открытый исходник ничего не стоит, если бинарь собран неизвестно из чего: минимум — подписанные теги и релизы, контрольные суммы, SBOM с артефактом, желательно воспроизводимая сборка и attestation о происхождении. Это и есть отличие «код открыт» от «поставке можно доверять» (упаковка, пайплайн).

Раскрытие исходников там, где это требует лицензия

Именно на этом я и споткнулся с it-tools. Практическая механика GPL-3.0 в вебе:

Архитектура Что передаётся пользователю Что из этого следует
Серверный рендеринг, браузер получает только HTML Объектный код не передаётся GPL-3.0 обязанности раскрытия не порождает; AGPL — порождает
SPA, браузер получает собранный JS-бандл Передаётся объектный код Возникает обязанность предоставить соответствующий исходник
Дистрибутив контейнера с GPL-компонентами Передаётся объектный код То же, плюс вопрос про совокупность и связывание

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

Это не юридическая консультация. Если вопрос стоит денег — идите к юристу с конкретной формулировкой, а не с вопросом «можно ли нам GPL». Хорошая звучит так: «мы отдаём браузеру минифицированный бандл, собранный из исходников под GPL-3.0 с нашими правками; считается ли это передачей объектного кода в смысле пункта 6 и что именно мы обязаны предоставить».

Вы как потребитель открытого кода: гейт в конвейере

Каждая зависимость приносит свою лицензию, и вопрос «что мы кому обязаны» решается проверкой в конвейере, а не разговором.

# .github/workflows/licenses.yml — гейт по лицензиям зависимостей.
name: licenses
on: [pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: syft dir:. -o cyclonedx-json=sbom.json   # SBOM в формате CycloneDX
      - name: Проверить по политике проекта
        run: |
          # Разрешительные — можно; сильный копилефт в поставляемом
          # артефакте — нельзя; всё неопознанное — на ревью человеку.
          if grep -Eo '"(id|name)": "[^"]+"' sbom.json \
             | grep -E 'GPL-2.0-only|GPL-3.0-only|AGPL-3.0|SSPL-1.0'; then
            echo "Найдена зависимость с запрещённой лицензией" >&2
            exit 1
          fi          
  • Гейт ловит очевидное, а не всё. Составные и нераспознанные лицензии (Apache-2.0 OR MIT, «MIT with commons clause») требуют глаз: автоматика снимает объём, но не заменяет решение.
  • Правило зависит от того, что вы поставляете. Копилефтная зависимость во внутреннем сервисе, который никому не передаётся, и она же в SDK для клиентов — два разных мира: политика пишется от способа поставки, а не от лицензии.
  • Атрибуция тоже обязательство. MIT и BSD требуют сохранять уведомление об авторстве в поставляемом артефакте: для мобильного приложения это экран «Лицензии» (магазины). А требования к SBOM появляются и в регулировании, и в закупках (ограничения, комплаенс).

Деньги конкретно: чем открытая воронка отличается от закрытой

Про биллинг подробно — в отдельной главе, про модели цены — в следующей; здесь только специфика открытого кода.

Пробный период у вас бесконечный. Открытая версия — это trial, который не кончается и который нельзя отозвать, поэтому триггером покупки не может быть время. Триггером должно быть событие роста: появился второй отдел, пришёл аудитор, потребовался SSO, выросло число узлов. Считайте не «сколько дней прошло», а «в какой момент у клиента меняется задача» — и кладите платную функцию ровно на этот момент.

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

Возврат. Клиент уже развернул софт у себя, «отключить» его вы не можете — только не продлевать. Поэтому возврат в self-hosted привязывают к сроку в начале периода и к отзыву ключа, а не к прекращению работы. Как это выглядит в документах, видно на живом примере — раздел /legal этого портала: оферта, условия возврата, политика обработки персональных данных. Правила пишутся до первой продажи, а не после первого спора.

Налоги и валюты — два разных мира. Пожертвования от иностранной платформы физическому и юридическому лицу облагаются по-разному; продажа лицензии — уже реализация прав на ПО со своими правилами по НДС и месту оказания. Не выводите это из общих соображений: сформулируйте бухгалтеру вопрос как «мы продаём неисключительную лицензию на ПО покупателю из такой-то страны, платёж приходит через такого-то посредника; как это квалифицируется и какие документы нужны».

Типичные ошибки

  • «Откроем код — придут контрибьюторы». Не придут: медиана внешних вкладов в новом проекте за первый год — ноль. Открывают ради дистрибуции и доверия, а не ради бесплатных рук: ревью чужого PR часто дороже, чем написать самому.
  • Граница open core проведена по нагрузке, а не по типу пользователя. «Больше десяти запросов в секунду — платите» бьёт по одиночке и не бьёт по компании; через полгода появится форк с убранным лимитом.
  • Забыли про атрибуцию в бинаре. Экран лицензий в мобильном приложении, файл NOTICE в дистрибутиве — самая дешёвая обязанность из всех и самая часто забываемая.
  • Проект без файла с лицензией. Код на GitHub без LICENSE — не открытый: по умолчанию действует полное авторское право, и юрист покупателя это увидит.

Мини-итог

Открытый код — это канал поставки со своим счётом, а не позиция в списке ценностей.

  • Он переносит операционную стоимость на пользователя, отдавая взамен контроль, право уйти и право посмотреть; выгода зависит от того, чей инженерный час дороже.
  • Он создаёт нагрузку, пропорциональную установкам, при доходе, пропорциональном договорам. Эти два числа расходятся с первого дня, и модель денег должна закрывать разрыв.
  • Деньги приходят не из кода, а из того, что рядом: обязательства (поддержка, SLA), освобождение от обязательств (двойное лицензирование), корпоративные функции (open core), снятая операционная работа (хостинг).
  • Граница open core — инженерное решение, реализуемое точками расширения и сборками, и двигать её можно практически только в сторону открытия.
  • Публикация необратима: выданные права не отзываются, форк всегда возможен, обязательства возникают в момент передачи артефакта, а архитектура значит не меньше текста лицензии.

Чек-лист перед публикацией репозитория:

  1. LICENSE на месте, идентификатор SPDX проставлен, лицензия выбрана осознанно.
  2. Понятно, кто правообладатель и как принимаются вклады (DCO или CLA), — это определяет доступные модели денег на годы вперёд.
  3. Есть SECURITY.md с адресом и сроком ответа и приватный канал для фиксов.
  4. Объявлено, какие версии поддерживаются и как долго; релизы подписаны, SBOM приложен.
  5. Если поставляется собранный артефакт из чужого копилефтного кода — исходники доступны, а ссылка видна там, где пользователь получает артефакт.
  6. Посчитано, сколько часов в месяц команда тратит на обращения при десятикратном росте установок.

Источники

Что дальше

Все разобранные способы брать деньги упираются в один вопрос — сколько именно и по какому основанию выставлять счёт. Об этом следующая глава: Ценообразование: подписка, потребление, места, freemium.

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

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

Доска запросов