8.1 KiB
title, version, lastUpdated
| title | version | lastUpdated |
|---|---|---|
| Obsługa publicznych poświadczeń | 3.8.40 | 2026-06-28 |
Obsługa publicznych poświadczeń
Source of truth:
open-sse/utils/publicCreds.tsTests:tests/unit/publicCreds.test.tsLast updated: 2026-06-28 — v3.8.40 Audience: Inżynierowie integrujący providerów, którzy udostępniają publiczne OAuth client_id / client_secret / klucze Firebase Web API w swoich publicznych CLI. Status: OBOWIĄZKOWE dla każdego nowego kodu, który osadza identyfikatory upstream.
Po co to istnieje
- OAuth 2.0 for native apps (PKCE) — OAuth client_id / client_secret dla zainstalowanych aplikacji są publiczne; rzeczywiste bezpieczeństwo zapewnia PKCE.
- Firebase API keys — identyfikatory klientów Web są publiczne z założenia.
OmniRoute musi osadzać te wartości, aby użytkownicy, którzy nie konfigurują .env, nadal mieli działający flow OAuth od razu po uruchomieniu. Bez wbudowanego fallbacku providerzy Gemini / Antigravity / Windsurf przestają działać dla każdego, kto idzie ścieżką „po prostu sklonuj i uruchom”.
Jednak literały w stylu AIzaSy…, GOCSPX-…, …apps.googleusercontent.com są łapane przez GitHub Secret Scanning, Semgrep i podobne skanery wzorców. Każdy release zamienia się w szum fałszywych alarmów, push protection blokuje legalne commity, a operatorzy tracą zaufanie do feedu alertów.
Helper open-sse/utils/publicCreds.ts rozwiązuje oba ograniczenia naraz:
- Osadza publiczny identyfikator jako sekwencję bajtów zamaskowaną XOR (brak wzorca skanera w źródle).
- Dekoduje w runtime przez
decodePublicCred/resolvePublicCred. - Wykrywa surowe wartości z dobrze znanymi prefiksami (
AIza,GOCSPX-,<digits>-<32hex>.apps.googleusercontent.com,Iv1.<hex>) i przepuszcza je bez zmian, dzięki czemu użytkownicy z surowymi wartościami w istniejącym.envdziałają dalej przy zerowej migracji.
To jest obfuskacja, nie szyfrowanie. Każdy, kto czyta źródło, może odzyskać wartość — i to jest w porządku, bo wartość jest publiczna z założenia. Jedynym celem jest uniknięcie dopasowań regex skanerów.
Obowiązkowy wzorzec
1. Dodawanie nowego publicznego poświadczenia
Gdy musisz osadzić nową wartość dostarczoną przez upstream, która:
- pochodzi z publicznego CLI / aplikacji desktopowej / bundla przeglądarkowego, oraz
- upstream provider dokumentuje ją (lub traktuje) jako publiczny identyfikator klienta, oraz
- skaner wzorców w przeciwnym razie by ją złapał (
AIza…,GOCSPX-…,<digits>-…apps.googleusercontent.comitd.),
…postępuj według tej checklisty:
-
Wygeneruj zamaskowaną sekwencję bajtów:
node --import tsx/esm -e \ 'import("./open-sse/utils/publicCreds.ts").then(m => console.log(JSON.stringify(Array.from( Buffer.from(m.encodePublicCred("THE_PUBLIC_VALUE"), "base64") ))))' -
Dodaj nowy wpis do
EMBEDDED_DEFAULTSwopen-sse/utils/publicCreds.tsz neutralną nazwą klucza (<provider>_id,<provider>_alt,<provider>_fbitd.). Nie używaj w helperze nazw w styluclient_secretaniapi_key— te słowa uruchamiają reguły Semgrep generic-secret. -
Dodaj
keyof typeof EMBEDDED_DEFAULTSdo publicznej unii typów (jest wnioskowany automatycznie). -
W kodzie konsumenckim zamień zahardkodowany literał na:
// single env override clientSecret: resolvePublicCred("provider_alt", "PROVIDER_OAUTH_CLIENT_SECRET"), // multiple env aliases (first non-empty wins) clientId: resolvePublicCredMulti("provider_id", [ "PROVIDER_CLI_OAUTH_CLIENT_ID", "PROVIDER_OAUTH_CLIENT_ID", ]), // no env override (always embedded default) firebaseApiKey: resolvePublicCred("provider_fb"), -
Usuń literał z
.env.example(zastąp dokumentacją wyłącznie w komentarzach, wskazującą czytelników tutaj):# ── Provider (Google / Firebase / etc.) ── # Public OAuth credentials are baked into the code via # open-sse/utils/publicCreds.ts. Set these vars only to use your own. # PROVIDER_OAUTH_CLIENT_ID= # PROVIDER_OAUTH_CLIENT_SECRET= -
Zaktualizuj
tests/unit/publicCreds.test.ts, dodając asercję kształtu dla nowego klucza (weryfikuj format, nie literał wartości — wzorzec w istniejących testach). -
Nigdy nie dodawaj literałów
AIza…/GOCSPX-…/…apps.googleusercontent.comdo plików testowych. Używaj stałychFAKE_*zbudowanych z fragmentów.join("")(patrz istniejące testy).
2. Konsumenci
- Czytaj wyłącznie z
resolvePublicCred()/resolvePublicCredMulti()— nigdy nie wywołujdecodePublicCredBytes()bezpośrednio poza helperem. - Helper jest celowo tani (liniowy XOR na bajtach) i bezpieczny do wywołania w czasie ładowania modułu; domyślne wartości są liczone raz.
- Override ze zmiennej env zawsze wygrywa. Jeśli użytkownik ustawi
PROVIDER_OAUTH_CLIENT_SECRET=GOCSPX-myown, helper przepuszcza tę surową wartość bez zmian.
3. Zabronione wzorce
❌ Nigdy nie rób żadnej z poniższych rzeczy w kodzie produkcyjnym (src/, open-sse/, electron/, bin/):
// BAD: literal value triggers Secret Scanning + Semgrep
clientSecret: process.env.PROVIDER_OAUTH_CLIENT_SECRET || "GOCSPX-realvalue",
// BAD: base64 of the literal — GitHub still detects since Feb/2025
clientSecret: process.env.PROVIDER_OAUTH_CLIENT_SECRET ||
Buffer.from("R09DU1BYLXJlYWx2YWx1ZQ==", "base64").toString(),
// BAD: string concatenation that re-assembles the pattern at runtime
clientSecret: "GO" + "CS" + "PX-" + "realvalue",
// BAD: hex/ROT13 encoding — different obfuscation, same risk of detection
clientSecret: hexDecode("474f4353..."),
Wszystkie te warianty w końcu odpala skaner. Używaj resolvePublicCred().
❌ Nigdy nie dodawaj literałów poświadczeń do .env.example. Użytkownicy, którzy potrzebują prawdziwych wartości upstream, mogą je wyciągnąć z publicznego CLI sami albo użyć własnej rejestracji OAuth.
❌ Nigdy nie odrzucaj nowego alertu secret-scanning bez wcześniejszego sprawdzenia, czy poświadczenie nie powinno trafić do tego helpera.
Powiązane kontrole
RAW_VALUE_PATTERNwpublicCreds.tswylicza prefiksy uruchamiające passthrough (retrokompatybilność). Rozszerzaj go wyłącznie o udokumentowane formaty publicznych poświadczeń, nigdy o sekrety własnościowe..env.examplejest objęty skryptem CIcheck-env-doc-sync— gdy usuniesz tu zmienną, upewnij się, że dokumentacja się zgadza.- Oba zestawy testów
npm run test:vitestoraznode --import tsx/esm --test tests/unit/publicCreds.test.tsmuszą pozostać zielone.
Kiedy NIE używać tego helpera
Ten helper jest wyłącznie dla poświadczeń, które są:
- Publicznie dystrybuowane przez upstream providera (binarka CLI, bundel przeglądarkowy, oficjalna dokumentacja).
- Udokumentowane lub silnie sugerowane jako niepoufne (chronione PKCE, klucz Firebase Web, podobne).
Dla wszystkiego innego — tokeny wydane przez operatora, sekrety per-tenant, client_secret Twojej własnej aplikacji OAuth, klucze szyfrowania, sekrety JWT, hasła do bazy — używaj wyłącznie zmiennych env (process.env.FOO, fallback || do pustego / jawnego błędu). Te wartości należą do .env i do szyfrowanego magazynu poświadczeń, nie do źródeł.
Referencje
- Google: OAuth 2.0 for native apps
- Firebase: API keys for client identification
- GitHub Secret Scanning supported secrets
- GitHub: base64 detection for tokens (Feb 2025)
- Commit wprowadzający ten helper:
1a39c31f— fix(security): mask public upstream creds + centralize error sanitization