Открытый код как способ поставки: что даёт и чего стоит
Я поднял на своём сервере инстанс it-tools — набор инженерных утилит в браузере: генераторы токенов, конвертеры, калькуляторы подсетей. Форкнул, прикрутил свою тему, собрал, выложил на поддомен. Работы на вечер, пользы много, денег ноль.
Через некоторое время выяснилась деталь, которую я в этот вечер не заметил. it-tools лежит под GPL-3.0, а это клиентское приложение: сервер отдаёт браузеру собранный минифицированный бандл — объектный код, произведённый из GPL-исходников. GPL-3.0 привязывает обязанность отдавать исходники именно к передаче объектного кода: не к «использованию», не к «размещению» — к передаче. Каждый посетитель получал у меня объектный код и вместе с ним право получить соответствующий исходник. Ссылки в подвале не было.
Починка заняла пять минут: ссылка на форк и упоминание GPL-3.0 в футере. Но урок стоит того, чтобы его развернуть. Открытый код — не «бесплатно», а другая структура издержек и обязательств. Обязательства возникают в момент поставки, а не в момент, когда о них вспомнили, и зависят не только от текста лицензии, но и от архитектуры: тот же GPL-3.0 в серверном приложении, которое отдаёт браузеру только HTML, ведёт себя совершенно иначе.
Предыдущая глава — Лицензии как инженерное ограничение — разбирала, что лицензия разрешает и запрещает делать с кодом. Эта глава про уровень выше: открытый код как канал поставки наравне с коробкой, SaaS и self-hosted из главы о моделях — со своей ценой владения по обе стороны, своими способами брать деньги и своими режимами отказа.
Четыре разные вещи, которые называют одним словом
Разговор про «сделать проект опенсорсным» буксует, потому что участники обсуждают разные вещи. Их четыре, и они ортогональны.
| Что это | Решение о чём | Можно ли поменять потом |
|---|---|---|
| Лицензия | Какие права вы даёте получателю кода | Только вперёд для новых версий; выданное не отзывается |
| Открытая разработка | Видно ли историю, обсуждения, планы, а не только релизы | Легко в обе стороны |
| Приём вклада | Берёте ли вы чужие PR и на каких условиях | Легко, но влияет на права: чужой код — чужой правообладатель |
| Модель денег | Кто и за что платит | Труднее всего: у людей уже сложились ожидания |
Практическое следствие: если вы открываете код ради дистрибуции, вам нужна лицензия и публичный репозиторий, но не обязательна открытая разработка. Приём вкладов — отдельное решение с отдельным ценником, и его можно принять позже, когда станет понятно, тянете ли вы ревью.
получить, открывая код?"} B -->|"Дистрибуцию и доверие"| C["Разрешительная лицензия,
публичный репозиторий,
вклады не обязательны"] B -->|"Защиту от бесплатного
хостинга конкурентом"| D["Копилефт или source-available,
см. главу о лицензиях"] B -->|"Чужой труд в проекте"| E["Открытая разработка, CLA или DCO,
ревью как постоянная работа"] C --> G["Счёт: сопровождение,
обратная совместимость,
публичные уязвимости"] D --> G E --> H["Счёт: ревью, документация,
права на чужой код"] G --> J["Деньги приходят не из кода,
а из того, что рядом с кодом"] H --> J
Что получает потребитель — и чем он на самом деле платит
Со стороны покупателя открытая поставка выглядит как «то же самое, но бесплатно». Неверно в обе стороны: он получает больше, чем функциональность, и платит больше, чем ноль.
Что он получает сверх функциональности: право уйти (вендор поднимет цену или закроется — код останется, и форк тут рабочий сценарий, ниже разберём реальные); право посмотреть (служба безопасности читает код, а не верит на слово — для регулируемых отраслей иногда единственный способ пройти согласование); право починить критичный баг своим патчем сегодня; и отсутствие переговоров — инженер ставит и пробует, не проходя закупку. На последнем и строится вся модель «сначала бесплатно, потом договор».
Чем он платит:
| Статья | Что реально происходит |
|---|---|
| Интеграция | Никто не настроит под вас: конфиги, схемы, миграции — ваша работа |
| Обновления | Апгрейд между мажорными версиями делаете вы, ломающие изменения читаете в 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
Открытое ядро плюс закрытые модули. Самая распространённая и самая коварная модель.
Инженерное решение здесь одно: где провести границу — и принимается оно в коде, а не на слайде. Рабочий признак: в открытой части всё, что нужно одному человеку или одной команде; в платной — всё, что нужно организации. 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 — инженерное решение, реализуемое точками расширения и сборками, и двигать её можно практически только в сторону открытия.
- Публикация необратима: выданные права не отзываются, форк всегда возможен, обязательства возникают в момент передачи артефакта, а архитектура значит не меньше текста лицензии.
Чек-лист перед публикацией репозитория:
LICENSEна месте, идентификатор SPDX проставлен, лицензия выбрана осознанно.- Понятно, кто правообладатель и как принимаются вклады (DCO или CLA), — это определяет доступные модели денег на годы вперёд.
- Есть
SECURITY.mdс адресом и сроком ответа и приватный канал для фиксов. - Объявлено, какие версии поддерживаются и как долго; релизы подписаны, SBOM приложен.
- Если поставляется собранный артефакт из чужого копилефтного кода — исходники доступны, а ссылка видна там, где пользователь получает артефакт.
- Посчитано, сколько часов в месяц команда тратит на обращения при десятикратном росте установок.
Источники
- Определение открытого ПО и одобренные лицензии — Open Source Initiative
- Тексты и разъяснения FSF — GNU Licenses FAQ
- Идентификаторы и маркировка — SPDX License List, REUSE
- Модели поддержки и управления — Open Source Guides, GitHub
- Nadia Eghbal. Working in Public — про экономику внимания мейнтейнера; Karl Fogel. Producing Open Source Software — producingoss.com
- Перечень компонентов — CycloneDX, SPDX; живые форки — OpenTofu, Valkey, OpenSearch
Что дальше
Все разобранные способы брать деньги упираются в один вопрос — сколько именно и по какому основанию выставлять счёт. Об этом следующая глава: Ценообразование: подписка, потребление, места, freemium.