List substrate tools with their URLs and how to reach them.
curl --request GET \ --url https://stratum.example.com/v1/admin/substrate/tools \ --header 'Authorization: Bearer <token>'Bootstrap-admin only. One entry per substrate-internal tool (OpenBao, VictoriaMetrics vmui + query API, vmagent, Postgres, OVN NB/SB, libvirt, the Stratum control plane): its URLs, the SSH-tunnel command, where its credential lives and caveats. Powers the console’s substrate-tools panel.
No secret is ever returned, in any mode: credentialsHint
says where the credential lives on the node.
Each HTTP tool’s access.published says how the node publishes its
port, and the URLs follow it, so none is a dead link:
all (the API; OpenBao on HA) also gets urls.node at the node’s plane
address; loopback (dev mode: VictoriaMetrics, vmagent, single-node
OpenBao,) is reached through access.sshTunnel or urls.local
on the node and never at the plane address; none (dev mode off) has no
local URL or tunnel and is reached through the front door
(urls.frontDoor, when the install has one) or podman exec on the
node. With a front door, the fronted tools’ canonical URL is
https://<tool>.<parentDomain>/ behind Stratum IAM.
Every successful call emits a platform.admin.substrate_tools.queried
audit event.
Authorizations
Section titled “Authorizations”Responses
Section titled “Responses”Tool list.
object
object
Short stable slug — openbao / victoriametrics-vmui /
victoriametrics-query / vmagent / postgres / ovn-nb /
ovn-sb / libvirt / stratum-controlplane. UI uses for
icons + ordering.
Human-readable label shown next to the icon.
Grouping for the UI panel.
One-sentence description of what the tool is for.
Every working address for this tool. Keys present:
internal — stratum-internal podman network URL (only
reachable from inside the controlplane or via podman exec);
ui — web UI path (when the tool has a UI);
local — the URL on the node, and on a workstation after the
SSH-forward in access.sshTunnel; absent when the port is not
published on the host (access.published: none);
host — the control plane’s http://<sshHost>:8443, or the
front-door URL for a fronted tool;
frontDoor — https://<tool>.<parentDomain>/ behind Stratum
IAM, when the install has a front door;
node — local rewritten to the serving node’s plane address,
present only for a tool published on every address
(access.published: all: the API, and OpenBao on HA;).
Prefer node from a workstation when present: local points at
the caller’s OWN machine there, which does not error, it silently
reaches something else.
Tool-specific keys may also appear (e.g. targets for
vmagent’s scrape target status page).
No key here is guaranteed resolvable from outside the
cluster; see reachability on the enclosing response.
object
object
Operator-side ssh -L command to make the tool’s local URL
reachable from their workstation. Omitted when it cannot work
(published: none) or the tool is behind the front door.
How to authenticate against the tool: where its credential
lives on the node (the API never returns one,). Go
field is AuthHint to avoid gosec G101 false positives.
How the node publishes the tool’s port. all: every
address, so urls.node works. loopback: 127.0.0.1 only (dev
mode,): access.sshTunnel from a workstation or
urls.local on the node, never the plane address. none: not on
the host (dev mode off): the front door or podman exec on the
node. Absent for tools without an HTTP host port (Postgres, OVN,
libvirt), whose notes say how to reach them.
Never returned. The access hint says where a secret lives on the node; the API does not hand it out.
object
Human-readable credential field name (e.g. “root token”).
Literal secret. UI must mask behind a click-to-reveal toggle and only render when the dev-mode posture banner is visible.
Free-form caveats the operator should see, including how to reach a tool whose port is on the node’s loopback only or not published.
Mirrors STRATUM_DEV_MODE. When true the node publishes the
observability tools (and single-node OpenBao) on its loopback; each tool’s access.published states the effect, so a
client needs only that. Never puts a secret in the response.
Answers “which IP do I point at?” for the URLs in items, none of which are resolvable from outside the cluster on their own.
object
The address the *.<frontDoorDomain> names resolve to.
Intended for a hosts-file entry, NOT for use as a bare-IP URL — see
hostHeaderRequired. Absent when no front door is configured.
The parent domain those names live under, so a client can render the exact hosts line to paste.
True when the front door dispatches on the Host header, which it always
does when one is configured. http://<frontDoorIp>/ therefore reaches
the wrong backend or none at all; the hostname must be preserved.
Stated explicitly so a client does not render frontDoorIp as a link.
The plane address of the node that served this request. Tools advertised
on localhost are reachable here from anywhere with plane access — a
tool’s urls.node entry is its urls.local rewritten to this address.
The answer differs per node and a request may land on any of them, which
is why nodeId accompanies it.
Identifies which node nodePlaneIp belongs to.
Example
{ "items": [ { "category": "secrets", "access": { "published": "all" }, "credentials": { "type": "token" } } ], "reachability": { "frontDoorIp": "192.0.2.240", "frontDoorDomain": "private.stratum-labs.cloud", "nodePlaneIp": "192.0.2.111", "nodeId": "n-msst0001" }}Missing or invalid token.
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
Field errors, for codes that carry them: each problem at its field
(see FieldError). Documented on the responses that set it, e.g.
approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED.
Absent otherwise.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
Structured facts about the refusal, for codes that carry them. The
shape is fixed per code and documented on the response that answers
it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and
IMAGE_IN_USE. Absent for codes that carry none.
object
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}Headers
Section titled “Headers”Caller is authenticated but lacks the bootstrap-admin role.
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
Field errors, for codes that carry them: each problem at its field
(see FieldError). Documented on the responses that set it, e.g.
approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED.
Absent otherwise.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
Structured facts about the refusal, for codes that carry them. The
shape is fixed per code and documented on the response that answers
it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and
IMAGE_IN_USE. Absent for codes that carry none.
object
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}