Skip to main content

Internal APIs & X-Internal-Key

Documentazione sul sistema di protezione delle API interne tra microservizi.

Panoramica​

Gli endpoint /internal/* sono progettati per la comunicazione service-to-service e non devono essere accessibili pubblicamente. Per proteggere questi endpoint, Γ¨ stato implementato un sistema di autenticazione basato su header.

Come funziona​

Header X-Internal-Key​

Tutte le richieste agli endpoint /internal/* devono includere l'header:

X-Internal-Key: <chiave-segreta>

Risposte​

ScenarioHTTP StatusRisposta
Header mancante403{"error": "forbidden", "message": "Invalid or missing X-Internal-Key header"}
Chiave sbagliata403{"error": "forbidden", "message": "Invalid or missing X-Internal-Key header"}
Chiave corretta200Dati richiesti

Configurazione​

Variabile d'ambiente​

Imposta in ogni microservizio:

INTERNAL_API_KEY=tua-chiave-segreta-qui

[!WARNING] Se non imposti la variabile, viene usata una chiave di default. All'avvio vedrai il warning:

⚠️ ATTENZIONE: Stai usando la chiave INTERNAL_API_KEY di default! 
Imposta INTERNAL_API_KEY nel file .env per la produzione!

Generare una chiave sicura​

openssl rand -hex 32

Servizi protetti​

I seguenti servizi espongono endpoint /internal/* protetti:

ServizioPrefissoEndpoint Esempio
auth/internal//internal/users/{id}, /internal/verify-token
devices/internal//internal/devices/{id}, /internal/users/{user_id}/devices

Servizi che chiamano API interne​

ServizioChiamaClient
notificationsauth, devicesauth_client.py, devices_client.py
sharingauth, devicesauth_client.py, devices_client.py
websocketauth, devicesauth_client.py, devices_client.py
commandsauth, devicesauth_client.py, devices_client.py
positionsauth, devicesauth_client.py, devices_client.py
eventsauth, devicesauth_client.py, devices_client.py
geofencesauth, devicesauth_client.py, devices_client.py
billingauthauth_client.py

Esempio di chiamata​

Python (client interno)​

import os
import httpx

INTERNAL_API_KEY = os.getenv("INTERNAL_API_KEY", "chiave-default")

def _headers():
return {"X-Internal-Key": INTERNAL_API_KEY}

def get_user(user_id: int):
with httpx.Client() as client:
resp = client.get(
f"http://auth:8081/internal/users/{user_id}",
headers=_headers()
)
return resp.json()

cURL (testing)​

# ❌ Senza header - 403 Forbidden
curl http://localhost:8081/internal/users/1

# βœ… Con header - 200 OK
curl -H "X-Internal-Key: tua-chiave" http://localhost:8081/internal/users/1

Protezione Traefik​

Oltre alla verifica header, Traefik blocca le richieste esterne a /internal/*:

# traefik/dynamic.yml
middlewares:
block-internal:
replacePath:
path: "/blocked"
# docker-compose.yml (auth)
labels:
- "traefik.http.routers.auth-internal-block.rule=PathPrefix(`/api/auth/internal`)"
- "traefik.http.routers.auth-internal-block.priority=200"
- "traefik.http.routers.auth-internal-block.middlewares=block-internal@file"

Best Practices​

  1. Non esporre /internal/ dall'esterno* - Usa Traefik per bloccare
  2. Usa chiavi diverse per ambiente - Dev, staging, produzione
  3. Ruota le chiavi periodicamente - Specialmente dopo data breach
  4. Non loggare la chiave - Evita di stamparla nei log
  5. Usa Docker secrets in produzione - PiΓΉ sicuro delle variabili ambiente