Un principal de servicio es la identidad propia de un Workload. Existe para que el código de un hub pueda crear servidores de duelo sin que nadie pegue una clave personal en una variable de entorno.
Como máximo un principal por Workload, creado por una persona con acceso de gestión.
Tiene permisos: un Workload destino del mismo proyecto (el propio incluido) y una capacidad por cada uno:
units.read lee unidades y el flujo de eventos.
units.control además crea, inicia, detiene, destruye y asigna, e incluye leer.
Nunca puede cambiar la política de escalado, los webhooks ni sus propios permisos.
Crearlo y darle acceso
curl
Code
P="$ZAROZ_API/projects/$PROJECT/service-instances/$SERVICE/principal"curl -sS -X PUT "$P" -H "$AUTH" # 201 created / 200 already therecurl -sS -X PUT "$P/grants" -H "$AUTH" -H "Content-Type: application/json" -d '{ "grants": [ {"target_service_instance_id": "<duels service uuid>", "capability": "units.control"}, {"target_service_instance_id": "<lobbies service uuid>", "capability": "units.read"} ]}'
PUT .../principal es idempotente y un principal nuevo no tiene ningún permiso. PUT .../principal/grants reemplaza la lista entera (máximo 64; una lista vacía los quita todos). Debes poder gestionar cada Workload que nombres: si no, grant_target_unavailable y no cambia nada. Un permiso surte efecto en la siguiente petición del programa.
Activar un principal cambia la plantilla de pods del Workload, así que se aplica a medida que las unidades se reinician, según la regla de despliegue del Workload.
Código dentro de una unidad
Cada unidad de un Workload con principal recibe dos cosas: ZAROZ_API_URL en su entorno y un archivo de token en /zaroz/credentials/token. El token dura 60 minutos y la plataforma lo reemplaza antes de que caduque, así que lee el archivo en cada petición (o al recibir un 401) y nunca lo guardes en caché.
curl
Code
# inside a unit of a service that has a principalcurl -sS "$ZAROZ_API_URL/projects/$ZAROZ_PROJECT_ID/service-instances/$TARGET/units?label=mode:2v2" \ -H "Authorization: Bearer $(cat /zaroz/credentials/token)"
TypeScript
Code
import { readFileSync } from "node:fs";// The mounted token is rotated by the platform: read it per request, never cache it.const token = () => readFileSync("/zaroz/credentials/token", "utf8").trim();const res = await fetch( `${process.env.ZAROZ_API_URL}/projects/${process.env.ZAROZ_PROJECT_ID}/service-instances/${TARGET}/units?label=mode:2v2`, { headers: { Authorization: `Bearer ${token()}` } },);
Python
Code
import osdef token() -> str: # rotated by the platform: read it per request, never cache it with open("/zaroz/credentials/token") as f: return f.read().strip()r = requests.get( f"{os.environ['ZAROZ_API_URL']}/projects/{os.environ['ZAROZ_PROJECT_ID']}/service-instances/{TARGET}/units", params={"label": "mode:2v2"}, headers={"Authorization": "Bearer " + token()}, timeout=10,)
Un programa fuera de Zaroz
Un matchmaker en tu propio servidor, o un trabajo de CI, crea una credencial externa para el principal. Actúa con los permisos del principal, tiene nombre y caducidad (de 1 a 365 días, 90 por defecto), es revocable y registra last_used_at.
curl
Code
curl -sS -X POST "$P/credentials" -H "$AUTH" -H "Content-Type: application/json" \ -d '{"name": "matchmaker-eu", "expires_in_days": 90}'# {"credential": {...}, "token": "zaroz_sp_..."} the token is shown this once
TypeScript
Code
const cred = await call("POST", `${P}/credentials`, { name: "matchmaker-eu", expires_in_days: 90 });console.log(cred.body.token); // zaroz_sp_...: store it in your secret manager now
Python
Code
status, cred = call("POST", f"{P}/credentials", {"name": "matchmaker-eu", "expires_in_days": 90})print(cred["token"]) # zaroz_sp_...: store it in your secret manager now
Envía el token como Authorization: Bearer zaroz_sp_.... Lista las credenciales con GET .../principal/credentials y revoca una con DELETE .../principal/credentials/{credential_id}.
Límites y auditoría
Un principal está limitado a 50 peticiones por segundo. Cada llamada suya se audita con el id del principal y el tipo de token. Desactivar el principal (DELETE .../principal) revoca todos sus tokens. Eliminar el Workload que lo posee también lo revoca, y eliminar un Workload destino borra los permisos que lo nombran.