GunSpec
Praxis

Schlüssel im Produktivbetrieb

Ein Schlüssel ist ein Inhaberpapier: wer ihn hat, ist Sie. Hier steht, wo einer liegen darf, wie er aus dem Browser bleibt und wie man ihn ohne Ausfall rotiert.

Der Test ist einfach: kann ihn jemand anders lesen? Ein Schlüssel in allem, was Sie an ein Gerät ausliefern, ist ein veröffentlichter Schlüssel, wie gut er auch verschleiert ist.

OrtUrteilWarum
Serverseitige UmgebungsvariableJaDer einzige Ort, an dem er wirklich privat ist. Beim Deploy eingespielt, nie eingecheckt.
Ein Secret-Manager oder Plattform-SecretJaNoch besser: Rotation und Zugriff werden protokolliert statt erinnert.
Browser-JavaScript, App, Spiele-ClientNeinAusgelieferter Code ist lesbarer Code. Jeder kann ihn extrahieren und Ihr Kontingent verbrauchen.
Ein Repository, auch ein privatesNeinKlone, Forks, CI-Logs und Backups überleben Ihren Vorsatz, ihn wieder zu entfernen.
Ein Query-StringNeinProxys, Analytics und Browserverlauf behalten URLs. Senden Sie ihn im Header.

Ein Browser, der Katalogdaten braucht, ruft Ihren Server, und Ihr Server ruft uns. So arbeitet gunspec.io selbst: die Website hält keinen Schlüssel, ihr Proxy trägt ein serverseitiges Token und eine Pfad-Positivliste.

app/api/gunspec/route.ts
javascript
// A server route your app calls instead of calling GunSpec.// The key stays on this side; the browser never sees one.const ALLOWED = new Set(['/v1/firearms', '/v1/firearms/resolve', '/v1/calibers']) export async function GET(request) {  const url = new URL(request.url)  const path = url.searchParams.get('path') ?? ''   // An allow-list, not a pass-through. An open proxy is your key  // with extra steps: anyone who finds it spends your quota.  if (!ALLOWED.has(path)) return new Response('not allowed', { status: 403 })   const upstream = new URL(`https://api.gunspec.io${path}`)  upstream.search = url.searchParams.toString()  upstream.searchParams.delete('path')   const res = await fetch(upstream, {    headers: { 'X-API-Key': process.env.GUNSPEC_API_KEY },  })   // Pass the cache headers through: the answer is as cacheable for  // your visitors as it was for you.  return new Response(res.body, {    status: res.status,    headers: {      'Content-Type': 'application/json',      'Cache-Control': res.headers.get('Cache-Control') ?? 'public, max-age=300',    },  })}
  • Führen Sie eine Positivliste der Pfade. Ein offener Durchreicher ist Ihr Schlüssel mit Zwischenschritt: wer ihn findet, verbraucht Ihr Kontingent.
  • Reichen Sie das Cache-Control von oben durch, damit Ihre Besucher dieselbe Cachebarkeit bekommen; siehe Caching.
  • Begrenzen Sie Ihren eigenen Proxy pro Besucher. Unsere Limits gelten für Ihren Schlüssel als Ganzes, sonst verbraucht ein missbräuchlicher Besucher das Kontingent aller.
  • Geben Sie den Schlüssel nie in einer Antwort, einer Logzeile oder einer Fehlerseite zurück.

Schlüssel sind kostenlos, und Nutzung wird je Schlüssel ausgewiesen. Ein einziger gemeinsamer Schlüssel macht aus einem Vorfall irgendwo einen Ausfall überall.

  • Einen je Umgebung: Produktion, Staging, lokal. Ein geleakter Staging-Schlüssel kostet Sie dann einen Staging-Schlüssel.
  • Einen je Dienst. Verdoppelt sich die Nutzung, sagt die Aufschlüsselung, welcher Dienst sich geändert hat.
  • Einen je Dienstleister oder fremder Integration, damit das Ende der Zusammenarbeit ein Klick ist.
  • Benennen Sie sie nach dem, was sie sind. backend-prod lässt sich beruhigt widerrufen, Schlüssel 3 nicht.

Zwei Schlüssel können gleichzeitig gültig sein, also ist Rotation ein Deploy und keine Umschaltung. Deaktivieren Sie vor dem Löschen: Deaktivieren ist umkehrbar, Löschen nicht.

rotate.sh
bash
# Two keys live at once, so rotation is a deploy and not an outage.# 1. Create the new key in your account, alongside the old one.# 2. Ship it as the environment variable your service already reads.GUNSPEC_API_KEY=gsk_live_new... # 3. Watch traffic move: the usage breakdown reports per key.curl -sS -H "X-API-Key: $GUNSPEC_API_KEY" https://api.gunspec.io/v1/me/usage | jq '.data.perKey' # 4. Disable the old key. Disabled answers 401 KEY_DISABLED and can#    be switched back on; deletion cannot be undone, so disable#    first and delete once nothing has failed for a day.

Handeln Sie zuerst am Schlüssel, untersuchen Sie danach. Ein deaktivierter Schlüssel antwortet sofort 401 KEY_DISABLED, und einen zweifelhaften zu deaktivieren kostet nichts. Melden Sie sich unter support@gunspec.io, wenn die Offenlegung bei uns liegt; Sicherheit nennt den Meldeweg.

  1. Ersatz anlegenZuerst ein neuer Schlüssel, damit die Behebung ein Deploy ist und kein Notfall.
  2. AusrollenDen neuen Schlüssel überall einspielen, wo der alte gelesen wird, und in der Nutzung je Schlüssel prüfen, dass der Verkehr umgezogen ist.
  3. Alten Schlüssel deaktivierenUmkehrbar, sofort wirksam, und es zeigt sofort, ob noch etwas daran hing.
  4. Prüfen, wofür er genutzt wurdeDie Aufschlüsselung zeigt den Verkehr des offengelegten Schlüssels. Unbekanntes Volumen ist ein Support-Ticket wert.
  5. LöschenWenn einen Tag lang nichts gescheitert ist, den Schlüssel löschen und dort entfernen, wo er offengelegt wurde.