Zaroz
Units API guide

Service principals

A service principal is a Workload's own identity. It exists so that a hub's code can create duel servers without anyone pasting a personal key into an environment variable.

  • At most one principal per Workload, created by a person with manage access.
  • It holds grants: a target Workload of the same project (itself included) and one capability each:
    • units.read reads units and the event stream.
    • units.control also creates, starts, stops, destroys and allocates, and includes reading.
  • It can never change the scaling policy, the webhooks, or its own grants.

Create it and grant access

curl

TerminalCode
P="$ZAROZ_API/projects/$PROJECT/service-instances/$SERVICE/principal" curl -sS -X PUT "$P" -H "$AUTH" # 201 created / 200 already there curl -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"} ] }'

TypeScript

TypeScriptCode
const P = `/projects/${PROJECT}/service-instances/${SERVICE}/principal`; await call("PUT", P); // 201 created / 200 already there await call("PUT", `${P}/grants`, { grants: [ { target_service_instance_id: DUELS, capability: "units.control" }, { target_service_instance_id: LOBBIES, capability: "units.read" }, ], });

Python

Code
P = f"/projects/{PROJECT}/service-instances/{SERVICE}/principal" call("PUT", P) # 201 created / 200 already there call("PUT", f"{P}/grants", {"grants": [ {"target_service_instance_id": DUELS, "capability": "units.control"}, {"target_service_instance_id": LOBBIES, "capability": "units.read"}, ]})

PUT .../principal is idempotent and a new principal holds no grant. PUT .../principal/grants replaces the whole list (at most 64; an empty list removes everything). You must be able to manage every Workload you name: otherwise grant_target_unavailable and nothing changes. A grant takes effect on the program's next request.

Enabling a principal changes the Workload's pod template, so it applies as units restart, by the Workload's rollout rule.

Code inside a unit

Every unit of a Workload with a principal gets two things: ZAROZ_API_URL in its environment and a token file at /zaroz/credentials/token. The token lives 60 minutes and the platform replaces it before it expires, so read the file on every request (or when you get a 401) and never cache it.

curl

TerminalCode
# inside a unit of a service that has a principal curl -sS "$ZAROZ_API_URL/projects/$ZAROZ_PROJECT_ID/service-instances/$TARGET/units?label=mode:2v2" \ -H "Authorization: Bearer $(cat /zaroz/credentials/token)"

TypeScript

TypeScriptCode
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 os def 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, )

A program outside Zaroz

A matchmaker running on your own server, or a CI job, mints an external credential for the principal. It acts with the principal's grants, has a name, an expiry (1 to 365 days, default 90), is revocable, and tracks last_used_at.

curl

TerminalCode
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

TypeScriptCode
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

Send the token as Authorization: Bearer zaroz_sp_.... List credentials with GET .../principal/credentials and revoke one with DELETE .../principal/credentials/{credential_id}.

Limits and audit

A principal is limited to 50 requests per second. Every call it makes is audited with the principal id and token kind. Disabling the principal (DELETE .../principal) revokes every token. Tearing down the Workload that owns it revokes it too, and tearing down a target Workload deletes the grants that name it.

Last modified on