Przegląd
300-liniowy serwer HTTP, który wydaje prywatne klucze SSH i tokeny
API autoryzowanym maszynom i agentom. Lista dozwolonych IP,
opcjonalny header X-API-Key, każde zapytanie zapisane
w logu audytu. Zero zależności runtime — bez
Express, bez klienta Redis, tylko biblioteka standardowa Node.
Zaprojektowany jako sidecar dla Consciousness Server i Cortex. Działa standalone dla każdego systemu, który potrzebuje małego zaufanego vaulta bez stawiania HashiCorp Vaulta lub chmurowego KMS.
Po co to istnieje
Jeśli prowadzisz zespół agentów AI, każdy z nich w końcu potrzebuje credentials — kluczy SSH do pushowania kodu, tokenów API do wywoływania usług, bearer tokenów do autoryzacji w Twojej infrastrukturze. Trzy wzorce, których warto unikać:
- Pliki
.envrozsiane wszędzie — duplikowane między hostami, wyciekające przezgit add -A, nigdy nie rotowane. - Zaszyte sekrety w configu — nawet w prywatnych repo wyciekają w momencie, gdy fork pójdzie public.
- Pełny vault (Vault / KMS / Secret Manager) — overkill dla małego zespołu; przynosi własny operacyjny ciężar.
Consciousness Key Server to nudna ścieżka pośrednia: jeden plik, który możesz przejrzeć w popołudnie, dwie warstwy uwierzytelniania, każdy dostęp zalogowany.
Instalacja
git clone https://github.com/build-on-ai/consciousness-key-server.git
cd consciousness-key-server
cp auth/allowed-clients.example.json auth/allowed-clients.json
# edytuj auth/allowed-clients.json: dodaj IP klientów i klucze API per klient
docker compose up -d
curl http://localhost:3040/health Domyślny port to 3040 — część
zarezerwowanego zakresu Consciousness Server 3030–3050.
Zmień przez KEY_SERVER_PORT.
Pojęcia
Layout vaulta
Layout na dysku pod keys/ jest celowo prosty —
ls mówi, co tam jest. Prywatne klucze SSH żyją w
keys/ssh/<nazwa> (bez rozszerzenia); tokeny API
żyją w keys/<serwis>/api-key.txt. Ustaw
chmod 600 na każdym pliku po wypełnieniu.
Uwierzytelnianie — dwie warstwy
- Lista dozwolonych IP — same IP albo prefixy
CIDR
/24wauth/allowed-clients.json. Localhost (127.0.0.1/::1) zawsze dozwolony. - Opcjonalny header
X-API-Key— jeden klucz per klient. Rotuj per klient bez zakłócania innych. Jeśli wywołujący wysyła klucz, musi pasować do dozwolonej wartości; jeśli nie wysyła klucza, sprawdzenie IP samodzielnie decyduje o dostępie.
Log audytu
Każde zapytanie — sukces lub porażka — dopisuje jedną linię do
logs/audit.log. Format jest line-oriented i stabilny —
przepuszczasz do swojego SIEM bez parsera.
[2026-04-25T08:00:01Z] IP=10.0.0.20 ENDPOINT=/keys/ssh/git-deploy RESULT=SUCCESS size=3247
[2026-04-25T08:00:03Z] IP=10.0.0.30 ENDPOINT=/keys/ssh/git-deploy RESULT=SUCCESS size=3247
[2026-04-25T14:22:05Z] IP=10.0.0.99 ENDPOINT=/keys/ssh/git-deploy RESULT=FORBIDDEN IP_not_whitelisted
[2026-04-25T14:22:18Z] IP=10.0.0.20 ENDPOINT=/keys/ssh/../etc/passwd RESULT=REJECTED path_traversal_attempt Typowe zastosowania
Pobieranie klucza SSH z hosta
curl -s http://localhost:3040/keys/ssh/github-deploy \
-H 'X-API-Key: zastap-mnie-dlugim-losowym-stringiem' \
> ~/.ssh/id_deploy
chmod 600 ~/.ssh/id_deploy Pobieranie tokenu API
curl -s http://localhost:3040/keys/api/openai \
-H 'X-API-Key: zastap-mnie-dlugim-losowym-stringiem' \
| jq -r .api_key Dystrybucja kluczy SSH dla floty
Jeden deploy key w vaulcie na primary hoście. Każdy inny host
(GPU box, dev laptop, CI runner) pobiera klucz przy boot przez
systemd oneshot albo /etc/rc.local. Zero plików
.env we flocie; rotacja to jedna operacja na primary
hoście. Każdy fetch widoczny w logu audytu, więc wiesz dokładnie
kto co wyciągnął i kiedy.
Dystrybucja tokenów Consciousness Server
Consciousness Server może pobrać swój bearer token z vaulta przy
starcie, więc nie wkładasz AUTH_TOKEN do
.env. Rotacja staje się operacją vaulta, nie
redeploy. Natywne wsparcie planowane dla CS v0.2; dziś integruj
ze skryptu deploy.
Scope credentials per agent
Każdy agent we flocie dostaje swoją tożsamość klienta
X-API-Key, z osobnymi wpisami w logu audytu per klient.
"Kto wyciągnął OPENAI_API_KEY wczoraj o 3 rano?" — jedna
linia w logs/audit.log.
API
Pięć endpointów. Cała powierzchnia.
| Metoda | Ścieżka | Cel |
|---|---|---|
| GET | /health | Health i uptime |
| GET | /keys/list | Lista dostępnych kluczy SSH i serwisów API |
| GET | /keys/ssh/:name | Pobierz prywatny klucz SSH (text/plain) |
| GET | /keys/api/:service | Pobierz klucz API (JSON) |
| GET | /audit | Ostatnie 100 wpisów w logu audytu |
Model zagrożeń
Chroni przed
- Przypadkowym ujawnieniem przez
git push— klucze żyją całkowicie poza repo. - Wyciekami współdzielonych sekretów w env —
rotujesz jeden wpis w vaulcie, nie dziesięć plików
.env. - Próbami path traversal — hard-coded odrzucenie
..i/w nazwach kluczy. - Cichym dostępem — każde zapytanie dopisuje do logu audytu, włącznie z odmowami i odrzuceniami.
Nie chroni przed
- Skompromitowanym hostem na liście dozwolonych IP — uwierzytelnianie tylko po IP.
- Słabymi lub wyciekłymi wartościami
X-API-Key— Ty je ustawiasz; trzymaj długie i losowe. - Brak TLS — usługa mówi czystym HTTP. Owin w reverse proxy z TLS dla cross-host.
- Złośliwym czytelnikiem na tym samym filesystemie co vault — używaj uprawnień OS; vault nie jest sandboxem.
Dla wdrożeń wyższego zaufania oczywiste upgrade'y to: terminacja
TLS w reverse proxy, uruchomienie za prywatną siecią lub VPN,
ścisłe uprawnienia OS na keys/, rotacja wartości
X-API-Key harmonogramowo. Model zagrożeń jest
napisany do low-friction LAN; hartuj w miarę poszerzania
perimetru.