Wstęp#

Ostatnio przyglądałem się tematowi bezpiecznego uruchamiania narzędzi AI bezpośrednio w naszym lokalnym środowisku. Narzędzia typu OpenCode są świetne, ale dają algorytmom dużą swobodę w operowaniu na naszych plikach. Zwykle kieruje się zasadą ograniczonego zaufania co skłoniło mnie do podjęcia próby zamknięcia opencode w kontenerze z dostępem do niezbędnych plików i katalogów.

Dlaczego izolacja ma znaczenie?#

Kiedy pozwalamy modelom AI generować i uruchamiać kod, de facto oddajemy im częściową kontrolę nad terminalem. Nawet jeśli ufamy dostawcy, błąd w wygenerowanym skrypcie może narobić bałaganu w systemie plików. Rozwiązanie? Konteneryzacja.

Dzięki temu OpenCode widzi tylko to, co mu udostępnimy, a po zakończeniu pracy kontener znika, nie zostawiając po sobie śmieci.

Budowa obrazu: Dockerfile pod lupą#

Zależało mi na tym, aby obraz był jak najlżejszy i bezpieczny. Wybrałem Alpine Linux jako bazę. Zobaczcie, jak wygląda konstrukcja tego środowiska:

FROM alpine:3.19

ARG UID=1000
ARG GID=1000

RUN apk add --no-cache curl ca-certificates bash libstdc++ libgcc \
    && curl -fsSL https://opencode.ai/install | bash \
    && ls -R /root/ \
    && mv /root/.opencode/bin/opencode /usr/local/bin/opencode || echo "File not found!" \
    && apk del curl

RUN addgroup -g $GID coder 2>/dev/null; \
	GROUP_NAME=$(getent group $GID | cut -d: -f1); \
	adduser -D -s /bin/sh -u $UID -G "$GROUP_NAME" coder \
    && mkdir -p /home/coder/.config/opencode \
    && chown -R coder:"$GROUP_NAME" /home/coder

USER coder
WORKDIR /workspace
CMD ["opencode"]

Cały proces zaczynamy od wybrania Alpine jako bazy, co pozwala nam utrzymać obraz w kategorii piórkowej. Waży on zaledwie kilka megabajtów. W kolejnym kroku przechodzimy do instalacji samego narzędzia. Używamy do tego curla, ale dbamy o higienę środowiska, więc zaraz po pobraniu i przeniesieniu binarki do folderu systemowego, całkowicie usuwamy ten pakiet. Dzięki temu ograniczamy liczbę niepotrzebnych narzędzi.

Przy pomocy argumentów UID i GID mapujemy Twoją tożsamość z hosta bezpośrednio do kontenera. Zastosowałem tu mały trik: jeśli grupa o danym ID już istnieje w Alpine (co często zdarza się na macOS), skrypt nie rzuci błędem, tylko dynamicznie pobierze jej nazwę i przypisze do niej użytkownika coder. Dzięki temu OpenCode działa na Twoich uprawnieniach. Pliki, które stworzy AI, należą do Ciebie, a nie do roota, więc możesz je swobodnie edytować bez sudo.

Podczas budowania obrazu musimy przekazać lokalne parametry przy pomocy flag --build-org:

docker build --build-arg UID=$(shell id -u) --build-arg GID=$(shell id -g) --no-cache -t safe-opencode .

Konfiguracja dla maksymalnego bezpieczeństwa#

Sama izolacja w Dockerze to pierwsza warstwa. Drugą jest wewnętrzna konfiguracja OpenCode. Zauważyłem, że domyślne ustawienia bywają zbyt liberalne. Rekomenduję wymuszenie potwierdzeń dla każdej krytycznej akcji.

W pliku ~/.config/opencode/opencode.json warto ustawić następujące flagi:

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "edit": "ask",
    "bash": "ask"
  }
}

Dzięki temu, nawet jeśli AI uzna, że chce coś wyedytować lub odpalić skrypt w bashu, najpierw zobaczycie prośbę o akceptację. To prosta bariera, która daje nam czas na refleksję nad tym, co właściwie się dzieje.

Alias dla wygody#

Aby korzystanie z tego rozwiązania było tak naturalne, jak wpisanie zwykłej komendy, dodajcie alias do swojego pliku ~/.bashrc lub ~/.zshrc:

alias safe-opencode='docker run --rm -it \
  -v "$HOME/.config/opencode/opencode.json:/home/coder/.config/opencode/opencode.json:ro" \
  -v "$(pwd):/workspace:rw" \
  safe-opencode'

Po przeładowaniu terminala (source ~/.zshrc), wystarczy wpisać safe-opencode w dowolnym folderze z projektem. Narzędzie uruchomi się w izolacji, z dostępem tylko do plików w tym konkretnym katalogu.

Zauważcie jedną ważną rzecz poleceniem run montujemy plik konfiguracyjny w trybie tylko do odczytu (:ro). Dzięki temu OpenCode może korzystać z naszych ustawień, ale nie może ich samodzielnie zmienić bez naszej wiedzy.

Podsumowanie#

Wprowadzenie tej warstwy izolacji zajęło mi kilka minut, a daje ogromny komfort psychiczny podczas eksperymentowania z nowymi modelami. Mamy lekkie, przenośne i przede wszystkim bezpieczne środowisko pracy.