Licencje Open Source. To prostsze niż Ci się wydaje
Licencje Open Source. To tylko prawne wymysły, czy istotna dla nas sprawa? Dlaczego to nas w ogóle powinno interesować?
W każdym systemie IT, który tworzymy, korzystamy z ogromnej ilości zależności. Dość swobodnie dodajemy do aplikacji nowe biblioteki. Szczególnie, jak są dostępne publiczne i są darmowe. Zresztą to nic dziwnego, w końcu to bardzo wygodna i optymalna zasada architektoniczna. Biblioteki Open Source, szczególnie gdy są używane przez wiele osób, mają wiele zalet. Dzięki nim nie musimy implementować samodzielnie kolejnych mniej lub bardziej skomplikowanych funkcji w systemie. Co więcej, takie biblioteki, mają wielu użytkowników, więc są również przez te osoby dość dobrze przetestowane. Gdy ktoś z jej użytkowników znajdzie w niej błąd oraz zgłosi go, to prędzej czy później zostanie on naprawiony. Gdybyśmy pisali te funkcjonalności samodzielnie, to wszystko spoczywałoby na naszej głowie. Zarówno testy jak i weryfikacja wszelkich możliwych użyć takiej biblioteki jak i jej utrzymanie oraz poprawianie na bieżąco wszelkich znalezionych problemów. A jak wiemy w początkowych etapach życia systemów lub modułów tych błędów, lub niedoróbek może być dość dużo.
Jednak musimy pamiętać, że każda taka biblioteka posiada autora. Ten autor ma wobec tej biblioteki prawa autorskie. Użycza on nam ją do użytku zgodnie z pewnymi regułami. Tymi właśnie regułami są postanowienia licencji.
Istotność licencji
Czy to ważne?
Tak.
Dlaczego?
Wyobraź sobie, że to Ty tworzysz bibliotekę Open Source. Jesteś jej autorem i masz wobec tego prawo definiować zasady używania jej przez innych.
Masz wówczas różne możliwości.
Jeżeli upubliczniasz bibliotekę, która wykonuje jakieś ważne zadania w Twojej firmie, w Twojej dziedzinie, możesz bać się, że konkurencja wykorzysta ją i jej zasady działania do uzyskania przewagi (lub zmniejszenia Twojej przewagi konkurencyjnej). Równocześnie możesz chcieć dać dostęp do funkcji w tej bibliotece hobbystom w tej dziedzinie, żeby mogli rozwijać w ten sposób swoje małe projekty.
Jeżeli zaś tworzysz projekt prywatnie, to może nie chcesz żeby Twoja twórczość była wykorzystywana w żadnych wojskowych zastosowaniach, które mogłyby służyć skrzywdzeniu innych ludzi. Możesz więc zdefiniować licencję, która będzie pozwalała na wszystko pod warunkiem, że nie jest wykorzystywana w żadnej z zakazanych branż.
Zupełnie inaczej sprawa może wyglądać, gdy tworzysz bibliotekę, do której dostęp chcesz sprzedawać, a upublicznisz tylko jej część. Wtedy odpowiednia licencja może definiować warunki użycia darmowej wersji.
Jak widzisz motywacje do precyzyjnego zdefiniowania dozwolonych warunków wykorzystania Twojego dzieła mogą być różne. Dlatego właśnie jako twórca, który upublicznia swoje dzieło do dalszego wykorzystania, masz możliwość chronienia swoich interesów.
Korzystanie z bibliotek
W związku z tym, gdy jesteśmy po drugiej stronie, czyli to my wykorzystujemy biblioteki stworzone przez innych, musimy respektować te zasady. Taka sytuacja jest dużo częstsza, w końcu łatwiej jest dodać zależność w systemie niż tworzyć od nowa bibliotekę i utrzymywać ją.
To jeszcze powiedzmy sobie o tym, co nam może grozić w przypadku nierespektowania takich zasad.
Gdybyśmy korzystali z biblioteki niezgodnie z licencją (np. wykorzystując ją do celów komercyjnych, mimo, że licencja tego zabrania) narażamy się na prawne konsekwencje w postaci wytoczenia sporu wobec naszego nielegalnego użycia cudzego utworu. Tego typu sprawy sądowe są rzadkie, jednak występują i mogą mieć dotkliwe konsekwencje. Warto więc o tym pomyśleć przy tworzeniu oprogramowania.
Bo pamiętaj – im więcej bibliotek mamy dołączonych do naszego sytemu, tym więcej różnych licencji być może musimy wspierać. A jak wiadomo, nieznajomość prawa nie zwalania nas z jego stosowania, więc tym bardziej powinniśmy zadbać o naszą świadomość tego, na czym stoimy.
Licencje open source – istotne aspekty
Licencji może być bardzo wiele. Co więcej, każda osoba, która publikuje coś w Internecie, może wymyślić swoje własne zasady licencyjne. Później pokażę Ci ciekawe przykłady takich pokracznych licencji.
Praktyka pokazuje, że zdecydowana większość osób czy też bibliotek korzysta z najpopularniejszych licencji. To nam dość mocno ułatwia zadanie analizy licencji wszystkich paczek w naszym systemie.
Co więc zazwyczaj pokrywają najpopularniejsze licencje Open Source?
- użycie komercyjne – definiują, czy możemy wykorzystać daną bibliotekę w komercyjnym projekcie, czyli takim, na którym chcemy w jakiś sposób zarabiać. Jest to niezbędne, gdy chcemy wykorzystać daną bibliotekę w firmowym projekcie. Szczególnie w projekcie, który jest komercyjny i firma zabrania jego udostępnienia użytkownikom lub innym firmom.
- modyfikacja kodu – definiuje, czy dozwolone są jakiekolwiek modyfikacje kodu źródłowego biblioteki. Możliwość modyfikacji jest ciekawym tematem. Zazwyczaj w ogóle nas ona nie interesuje. Szczególnie na początku używania jej funkcji, ale wszystko się zmienia w momencie, gdy pierwotny autor porzuci swój projekt i już nigdy więcej nie będzie go rozwijał. Wtedy, gdy możemy modyfikować kod źródłowy, mamy możliwość wciągnięcia utrzymania i dbania o bibliotekę do firmy. Możemy nawet zdecydować o powiększeniu tej biblioteki o dodatkowe funkcjonalności, ściśle dopasowane do naszej branży. Wtedy też mówimy o prywatnej modyfikacji kodu.
- wskazanie modyfikacji – w momencie, gdy już zmodyfikujemy kod źródłowy bibliotek, musimy również wiedzieć, czy licencja nie nakazuje nam przypadkiem jasnego poinformowania o zmianach na poziomie kodu. Jest to istotne w przypadku, gdy chcemy ten kod dalej dystrybuować. W ten sposób nasze modyfikacje kodu nie będą przypisywane oryginalnemu autorowi biblioteki.
- tworzenie utworów pochodnych – jak już o tym wspomnieliśmy, istotnym aspektem jest to, czy możemy w ramach dozwolonego użycia tworzyć utwory pochodne i w jakim zakresie. Utworem pochodnym jest zarówno modyfikacja takiej biblioteki jak i samo jej wykorzystanie w naszym systemie. Jednak w przypadku bibliotek raczej nie spotkamy licencji, która zabrania tworzenia utworów pochodnych. To przeczyłoby idei tworzenia biblioteki, która z natury może być wykorzystywana przez inne systemy. Zabranianie tworzenia utworów pochodnych dotyczy raczej oprogramowania.
- dystrybucja podmiotu lub utworu pochodnego – zarówno gdy modyfikujemy kod samej biblioteki jak i wtedy, gdy po prostu używamy jej w naszym systemie, żebyśmy mogli później używać takich produktów pochodnych, licencja musi nam na to powalać. Ma to szczególnie znaczenie wtedy, gdy chcielibyśmy wziąć bibliotekę Open Source, coś w niej zmodyfikować, a następnie sprzedawać dostęp do niej.
- czy daje gwarancję – co się dzieje wtedy, gdy w naszej firmie wydarzy się coś złego z powodu błędu w zewnętrznych narzędziach, z których korzystamy? Możemy mieć pretensje do twórców zewnętrznego narzędzia. Możemy też rościć sobie prawo do odszkodowania za poniesione straty. Szczególnie, gdy jest to zewnętrzny komponent, z którego twórcami podpisujemy umowę o świadczenie konkretnych usług. Jednak większość bibliotek Open Source nie daje gwarancji działania swojego kodu. Jest to dla nich wygodne. Często jest więcej niż jeden twórca takiej biblioteki, a równocześnie twórca nie pobiera żadnego wynagrodzenia za swoją pracę. Nic więc dziwnego, że nie chcą oni dawać gwarancji na działanie swojego kodu.
- odpowiedzialność twórcy – to samo tyczy się odpowiedzialności twórcy za wszelkie szkody wyrządzone przed dane oprogramowanie Open Source. Dokładnie z tym samych powodów co powyżej. Brak wynagrodzenia i często brak możliwości ustalenia odpowiedzialności za konkretny fragment kodu sprawia, że łatwiej jest jasno zakomunikować wyłączenie odpowiedzialności twórców.
- zmiana licencji – gdy tworzymy utwory pochodne, możemy chcieć tak zmodyfikowaną bibliotekę dystrybuować pod własnym nazwiskiem. Może nawet na jakiejś płatnej licencji, już nie Open Source. Możemy to zrobić, tylko wtedy gdy licencja bazowa na to pozwala.
- załączenie oryginalnego podmiotu i jasne informowanie o tym – gdy już zmodyfikujemy lub chociaż użyjemy w naszym systemie danej biblioteki możemy być zobowiązani do umieszczenia takiej informacji razem z utworem pochodnym. Takie informacje powinny być dostępne do znalezienia w gotowym oprogramowaniu, nie tylko w kodzie źródłowym. Dobrym przykładem tu są różnego rodzaju sprzęty, które w głęboko ukrytych opcjach wyświetlają wszelkiego rodzaju informacje o wykorzystywanych bibliotekach czy też narzędziach wraz z informacją o licencji. Poniżej widać taki przykład w zegarkach Garmin i ekranie samochodowym VW.
https://daniel.haxx.se/blog/2016/10/03/screenshotted-curl-credits/
- co trzeba trzymać razem z dołączoną biblioteką (licencje Open Source, copyright, instrukcje budowania) – niektóre licencje Open Source z kolei wymagają od ich użytkowników/deweloperów umieszczenia określonych informacji w utworach pochodnych. Takich jak link do oryginalnej licencji, informacja o copyright, instrukcja budowania lub też niestandardowe zdefiniowane informacje.
- oznaczenie źródeł – gdy udostępniamy źródła utworu pochodnego, to niektóre licencje Open Source (np. MPL-1.1) wymuszają na nas oznaczenie w pewien określony sposób każdego pliku źródłowego, który korzysta z tej biblioteki. Nie jest to trudne, jednak trochę uciążliwe.
- upublicznienie źródeł – dodając biblioteki z niektórymi licencjami (np. z rodziny GPL) mamy obowiązek upublicznić źródła takiej biblioteki. Warto wziąć to pod uwagę, ponieważ nieraz takie zachowanie może być dla nas niekorzystne. Szczególnie jeżeli nasz kod źródłowy odzwierciedla pewną wiedzę biznesową, którą wcale nie chcemy dzielić się z osobami spoza naszej firmy.
Oczywiście to nie są wszystkie elementy, które mogą się znaleźć w licencji biblioteki Open Source. Jednak wybrałem tutaj części wspólne, które pojawiają się w wielu licencjach. Zawsze możemy znaleźć zarówno licencje Open Source, które będą zawierały nietypowe klauzule jak i te, które zawierają tylko minimalną ich ilość. Przykładem tu jest licencja “Fair License”. Jest ona najkrótszą licencją zatwierdzoną przez Open Source Initiative (o tym później).
Jakie więc możemy rozróżnić typy licencji?
To zależy od kategorii, według której będziemy je dzielili.
W zależności od możliwości na jakie pozwala licencja dzielimy je na:
- permissive – które pozawalają na bardzo wiele, użycie w zamkniętych, komercyjnych projektach, modyfikacje;
- copyleft – często mają dużo większe wymagania co do utworów pochodnych, np. wymuszają upublicznienie kodu źródłowego, wymuszają aby wszelkie modyfikacje lub utwory pochodne nadal były objęte licencją Open Source;
- weak copyleft – to podejście pośrednie, gdy tylko niektóre modyfikacje wymuszają upublicznienia kodu, Tak więc właściwość Open Source nie jest tu w pełni przechodnia.
Klasyfikacja licencji
Przejdźmy do następnego rodzaju klasyfikacji licencji.
Jak wyglądają różne licencje w praktyce?
- standardowe licencje – zdecydowana większość narzędzi czy też bibliotek posiada standardowe licencje uznane przez Open Source Initiative (OSI). Jest to organizacja pożytku publicznego, która działa w kierunku promocji i wsparcia Otwartego Oprogramowania (ang. Open Source). Dlatego właśnie zaakceptowanie przez OSI określonej licencji oznacza, że jest ona zgodna z duchem Open Source. W takim przypadku podczas analizowania treści danej licencji możemy się wesprzeć wieloma dostępnymi opracowaniami (np. https://www.tldrlegal.com). Tego typu strony pozwalają w szybki sposób rozeznać się w zasadach działania konkretnej licencji.
- licencje dedykowane – niektóre biblioteki lub programy, szczególnie te komercyjne mają zdefiniowane swoje własne licencje. W tym przypadku musimy niestety samodzielnie przeanalizować jej treść, ponieważ mogą one zawierać różne niestandardowe klauzule.
- brak licencji – to problematyczna sytuacja. W takim przypadku twórca biblioteki posiada pełne prawa autorskie (copyright) i dana biblioteka i jej kod nie są Open Source. Nawet mimo, że są dostępne publicznie. Jednak nawet strony opisujące licencjonowanie na GitHub jasno definiują takie sytuacje. Patrz przykład. Wobec tego nie mamy prawa korzystać z takiej biblioteki.
- istnieją również różnego rodzaju nietypowe licencje, które są używane w co najmniej jednym projekcie, jednak tak rzadko, że nie traktowałbym ich zbyt poważnie. Wymieniam je tutaj głównie w ramach anegdoty.
- Passive-Aggressive License – licencja pozwala na użycie i modyfikacje kodu, ale nie pozwala na jego uruchomienie,
- JSON License – licencja w stylu MIT (permissive), jednak z zastrzeżeniem, że utwory pochodne mogą być wykorzystywane tylko do czynienie dobra, nie zła
- I HATE AI LICENSE – licencja w stylu Creative Common (permissive), jednak z zakazem użycia we wszelkich rozwiązaniach AI.
Zmienność licencji
Ważnym spostrzeżeniem odnoście licencji jest fakt, że licencje przypisane do danej biblioteki mogą się zmieniać w czasie. Dlatego w momencie, gdy podbijamy wersję powinniśmy zawsze spojrzeć, czy licencja nowej wersji nadal nam pasuje. Dobra wiadomość jest taka, że licencje są przypisane do wersji biblioteki, więc jak nie podbijamy jej, to również nie musimy się martwić zmianami w licencji.
Metoda na radzenie sobie z licencjami
Widać, że w obszarze licencji mamy do czynienia z dość długą listą potencjalnych zasad. Jak sobie więc poradzić z taką pulą możliwości?
Najlepiej jest zacząć od zdefiniowania profilu użycia bibliotek przez naszą firmę (lub nasz system):
- czy chcemy z niej korzystać komercyjnie,
- czy możemy upublicznić kod źródłowy naszego systemu,
- czy chcemy wprowadzać modyfikacje do kodu źródłowego biblioteki (teraz lub w przyszłości, tak jak wspomniałem wcześniej – na przykład na wypadek zakończenia utrzymania jej przez twórców).
Odpowiedź na te trzy podstawowe pytania daje nam bardzo dobrą perspektywę na zbiór licencji, które akceptujemy. Pomoże nam w tym strona, o której również już wspominałem. Dzięki niej będziemy w stanie przefiltrować zbiór popularnych licencji i wylistować tylko te, które pasują do naszego zastosowania.
W ten sposób powinniśmy otrzymać listę dopuszczalnych licencji, którą można opublikować wewnątrz firmy. Dzięki temu każda osoba w firmie, która będzie chciała skorzystać z jakiejś biblioteki lub narzędzia, będzie wiedziała, bez większego zastanowienia, z jakich licencji może korzystać.
Problematyczne licencje
Warto w tym miejscu wspomnieć jeszcze o potencjalnie problematycznych licencjach. W momencie, gdy będziesz analizować licencje używane przez zależności Twojego systemu, warto wiedzieć, które z nich mogą być dla Ciebie problematyczne. Choć oczywiście tak jak poprzednio powiedzieliśmy, to wszystko zależy od oczekiwań odnośnie wykorzystania tych bibliotek w systemach.
Skupię się tutaj głównie na popularnych licencjach. Jest bardzo wiele dziwnych i nietypowych licencji, które jednak są używane bardzo jednostkowo. W praktyce nie warto ich znać. Ale jako ciekawostka, możesz spojrzeć na jedną z tych dwóch list.
https://github.com/ErikMcClure/bad-licenses
https://github.com/benlk/misc-licenses
- GPL 2.0 i GPL 3.0 – są to licencje, które wymuszają przechodniość licencji. To znaczy, że modyfikacje i produkty pochodne muszą mieć nadal licencję GPL. Samo to nie byłoby mocno problematyczne, gdyby nie fakt, że licencja GPL również wymusza upublicznienie źródeł. I tu zaczynają się schody w niektórych sytuacjach i systemach. Dobra wiadomość jest taka, że poza tym licencja ta pozwala na swobodną dystrybucję utworów pochodnych nawet w zastosowaniach komercyjnych. Jedyne wymaganie, to zakaz dyskryminacji jakichkolwiek sposobów wykorzystania w utworach pochodnych. Czyli na przykład, nie możemy wiec zabronić użycia jej w przemyśle zbrojeniowym.
- AGPL 3.0 – bardzo podobna do licencji GPL, także wymusza upublicznienie źródeł i przechodniość licencji. Jednak dodatkowo doprecyzowuje wykorzystanie w przypadku aplikacji i usług, nie tylko bibliotek.
- MPL 1.0 lub 2.0 – licencja ta wymusza, żeby w każdym pliku źródłowym w którym używamy danej biblioteki był umieszczony opis licencji (niewiele bibliotek jej używa np. **TimelineJS3).**
- MIT License – dość swobodna licencja i niezwykle popularna. Wymusza ona jedynie dodanie kopii oryginalnej licencji do finalnego utworu.
- Apache License 2.0 – wymusza zapisanie w kodzie informacji o licencji w określonej postaci.
Weryfikacja licencji Open Source
Na koniec część praktyczna. W jaki sposób sprawnie możemy weryfikować licencje zależności, z których korzystamy? Sprawdzanie każdej z nich jedna po drugiej to na pewno bardzo mozolne zajęcie.
Rozwiązaniem tutaj może być generowanie pliku SBOM (Software Bill Of Material). Jest sporo narzędzi, które potrafią automatycznie generować pliki SBOM dla różnych ekosystemów paczek. Sam standard SBOM zawiera informacje o licencjach.
Dodatkowo, jeżeli plik SBOM wstawimy do odpowiednich narzędzi (jak na przykład OWASP Dependency Track), to będziemy mieli wygodny interfejs do przeglądania faktycznej licencji każdej z zależności.
Wiele ekosystemów paczek ma również dedykowane narzędzia do weryfikacji licencji paczek, z których korzystamy.
- dla PIP jest to pip-licenses
- dla npm to https://github.com/brainhubeu/license-auditor lub https://github.com/davglass/license-checker
AI i licencje Open Source
Na zakończenie chciałbym jeszcze dodać jedną ważną przestrogę.
Pewnie nie raz już zdarzyło Ci się generować kod programu z użyciem jakiegoś modelu AI.
Tu warto zachować szczególną ostrożność. Prawo własności i AI to kontrowersyjne połączenie. Nie jest to jeszcze (stan na 10.2024) w pełni uregulowane. Generując kod z użyciem np. ChatGPT nie mamy pewności, czy wygenerowany kod nie jest kopią kodu objętego licencją. W takim przypadku musielibyśmy być tego świadomi i zastosować się do postanowień licencyjnych danego kodu.
Jednak problem w tym, że AI nigdy nam tego nie powie.