Token-gated and internal endpoints for challenge administration and runtime control on the subnet master.
This page documents the operator-facing admin surface and the internal endpoints
used between the master and its containers.
The /admin* and /v1/admin/* routes are gated by an admin token and are not
public. The Docker broker and challenge get_weights endpoints are internal
service-to-service routes — they are not exposed to end users.
Every management route depends on require_admin, which reads the token from an
X-Admin-Token header or from an Authorization: Bearer <token> credential and
compares it in constant time (app_admin.py:121-130, auth.py:28-29). The
expected value comes from the ADMIN_TOKEN environment variable, or from the
file at ADMIN_TOKEN_FILE (auth.py:10-18). A mismatch returns 401
(app_admin.py:127-130).
Updates mutable metadata and returns a ChallengeAdminView
(app_admin.py:247-264). Request — ChallengeUpdate; all fields optional
(schemas/challenge.py:51-67).
The following routes are internal — they run on separate service apps and are
authenticated with per-challenge tokens, not the admin token. They are documented
here for operators; they are not part of the public API.
The Docker broker runs as its own app (docker_broker.py:653-659). Each request
is authenticated with Authorization: Bearer <broker token> plus an
X-Platform-Challenge-Slug header (_authenticate, docker_broker.py:717-730).
Method
Path
Request
Response
Source
POST
/v1/docker/run
BrokerRunRequest
BrokerRunResponse
docker_broker.py:669-690
POST
/v1/docker/cleanup
BrokerCleanupRequest
BrokerCleanupResponse
docker_broker.py:692-701
POST
/v1/docker/list
BrokerListRequest
BrokerListResponse
docker_broker.py:703-712
POST /v1/docker/run returns 429 when a workload quota is exceeded
(docker_broker.py:685-688) and 400 on an executor error
(docker_broker.py:689-690). BrokerRunResponse carries container_name,
stdout, stderr, returncode, and timed_out (schemas/docker_broker.py:51-56);
BrokerCleanupResponse carries status (schemas/docker_broker.py:82-83);
BrokerListResponse carries containers (schemas/docker_broker.py:74-75).
The master collects per-challenge weights by calling each challenge’s
GET /internal/v1/get_weights, authenticated with the challenge’s bearer token
and an X-Platform-Challenge-Slug header (challenge_client.py:31-36). The
challenge replies with a ChallengeWeightsResponse
(challenge_client.py:43; see Weights schema).