Nomad — API Surface#
API types#
REST/HTTP, gRPC (internal plugin protocol), CLI, and Go library (api/ package).
REST/HTTP API#
- Router: stdlib
net/http.ServeMux— no third-party router. Go 1.22 method-qualified patterns are used in a few places (e.g.,"GET /v1/volumes"). - Route registration: All routes registered programmatically in
command/agent/http.go:registerHandlers()vias.mux.HandleFunc(...)ands.mux.Handle(...). - Base path: All public routes under
/v1/.
Middleware chain#
Requests flow through three layers, outermost-first:
authMiddleware(newAuthMiddleware, http.go:1184) — wraps the entire mux for the Task API subpath. ValidatesX-Nomad-Tokenvia anACL.WhoAmIRPC call; returns 401 if token absent, 403 if invalid.wrap()(http.go:738) — applies to nearly every handler. Sets custom response headers, callsauditHandler()(audit logging), maps RPC errors to HTTP codes (403 for ErrPermissionDenied, 400 for ErrIncompatibleFiltering, 500 otherwise), and handles?prettyJSON formatting.wrapCORS()/wrapCORSWithAllowedMethods()(http.go:1165–1182) — applied to specific endpoints that need cross-origin access (client filesystem, stats, allocation endpoints, variables).
Authentication#
Token-based. Clients pass a token via:
X-Nomad-TokenHTTP header (preferred), or?token=query parameter.
parseToken() (http.go:1019) extracts the token and sets it on every RPC request struct. The server validates tokens against the ACL state store on each request. OIDC/JWT workload identity tokens are also accepted via the JWKS endpoint.
Key endpoints (grouped by resource)#
| Group | Endpoints | Notes |
|---|---|---|
| Jobs | GET/POST /v1/jobs, POST /v1/jobs/parse, GET /v1/jobs/statuses, GET/PUT/DELETE /v1/job/{id}, /v1/job/{id}/plan, /v1/job/{id}/dispatch, /v1/job/{id}/versions, /v1/job/{id}/allocations, etc. | Primary operator interface |
| Nodes | GET /v1/nodes, /v1/node/{id}, /v1/node/{id}/drain, /v1/node/{id}/eligibility, /v1/node/pools, /v1/node/pool/{name} | Node management |
| Allocations | GET /v1/allocations, /v1/allocation/{id}, /v1/allocation/{id}/stop, /v1/allocation/{id}/restart | Allocation control |
| Evaluations | GET /v1/evaluations, GET /v1/evaluations/count, /v1/evaluation/{id} | Scheduler evaluation status |
| Deployments | GET /v1/deployments, /v1/deployment/{id}, /v1/deployment/{id}/promote, /v1/deployment/{id}/fail, /v1/deployment/{id}/pause | Rolling deploy management |
| Volumes (CSI) | GET /v1/volumes, /v1/volumes/external, /v1/volumes/snapshot, /v1/volume/csi/{id}, /v1/plugins, /v1/plugin/csi/{id} | CSI storage |
| Volumes (Host) | /v1/volume/host/{id}, /v1/volumes/claims, /v1/volumes/claim/{id} | Host volume management |
| ACL | /v1/acl/policies, /v1/acl/policy/{name}, /v1/acl/tokens, /v1/acl/token, /v1/acl/token/{id}, /v1/acl/bootstrap, /v1/acl/roles, /v1/acl/role/{id}, /v1/acl/auth-methods, /v1/acl/auth-method/{name}, /v1/acl/binding-rules, /v1/acl/oidc/auth-url, /v1/acl/oidc/complete-auth, /v1/acl/login | Full ACL + OIDC federation |
| Agent | /v1/agent/self, /v1/agent/join, /v1/agent/members, /v1/agent/force-leave, /v1/agent/servers, /v1/agent/schedulers, /v1/agent/schedulers/config, /v1/agent/health, /v1/agent/host, /v1/agent/monitor, /v1/agent/monitor/export, /v1/agent/pprof/ | Agent introspection |
| Client (node-local) | /v1/client/fs/ (CORS), /v1/client/gc, /v1/client/stats (CORS), /v1/client/allocation/ (CORS), /v1/client/metadata, /v1/client/identity | Direct client node API |
| Namespaces | /v1/namespaces, /v1/namespace, /v1/namespace/{name} | Multi-tenancy |
| Variables | /v1/vars (CORS), /v1/var/{path} (CORS, HEAD/GET/PUT/DELETE) | Encrypted secrets storage |
| Services | /v1/services, /v1/service/{name} | Native service discovery |
| Scaling | /v1/scaling/policies, /v1/scaling/policy/{id} | Autoscaler integration |
| Events | /v1/event/stream | Server-sent event stream (blocking HTTP) |
| Search | /v1/search, /v1/search/fuzzy | Cross-resource fuzzy search |
| Operator | /v1/operator/raft/, /v1/operator/keyring/, /v1/operator/autopilot/configuration, /v1/operator/autopilot/health, /v1/operator/snapshot, /v1/operator/scheduler/configuration, /v1/operator/utilization, /v1/operator/upgrade-check/ | Cluster operations |
| System | /v1/system/gc, /v1/system/reconcile/summaries | Maintenance |
| Status | /v1/status/leader, /v1/status/peers | Cluster status |
| Misc | /v1/metrics, /v1/validate/job, /v1/regions, /v1/keyring/ | Observability + validation |
| OIDC/JWKS | /.well-known/openid-configuration, /nomad/.well-known/jwks.json (structs.JWKSPath) | Workload identity federation |
| UI | /ui/ | Embedded SPA (served from bindata) |
| Debug | /debug/pprof/ (conditional) | Go profiling |
Blocking queries#
Every read endpoint supports Consul-style blocking queries: clients pass ?index=N&wait=Xs. The server blocks until the state store index advances past N, then responds. This is the primary “watch” mechanism — no WebSocket required for most polling. Implemented via go-memdb watch sets.
Streaming endpoints#
A few endpoints upgrade to streaming:
/v1/event/stream— server-sent events / newline-delimited JSON stream of cluster events./v1/client/fs/and/v1/client/allocation/*/logs— WebSocket for interactive exec and log following (c.websocket()in the API client)./v1/agent/monitor— log stream.
gRPC API (plugin protocol)#
Nomad does not expose a public-facing gRPC API. gRPC is used exclusively for the internal driver/plugin subprocess protocol via hashicorp/go-plugin.
Proto files#
| File | Service | Purpose |
|---|---|---|
plugins/base/proto/base.proto | BasePlugin | Required by all plugin types |
plugins/drivers/proto/driver.proto | Driver | Task driver RPC interface |
plugins/device/proto/device.proto | DevicePlugin | Hardware device plugin |
client/logmon/proto/logmon.proto | LogMon | Log collection subprocess |
drivers/shared/executor/proto/executor.proto | Executor | Task executor subprocess |
drivers/docker/docklog/proto/docker_logger.proto | DockerLogger | Docker log collection |
plugins/shared/hclspec/hcl_spec.proto | — | HCL schema shared type |
plugins/shared/structs/proto/*.proto | — | Shared attribute/stats types |
BasePlugin service (all plugins must implement)#
PluginInfo(PluginInfoRequest) → PluginInfoResponse— name, type, versionConfigSchema(ConfigSchemaRequest) → ConfigSchemaResponse— HCL schemaSetConfig(SetConfigRequest) → SetConfigResponse— push config to plugin
Driver service (task drivers)#
TaskConfigSchema— schema for task-level HCL configCapabilities— what optional RPCs the driver supportsFingerprint(stream)— streaming driver health/capability reportingRecoverTask— re-attach to a running task after driver restartStartTask— launch a task; returns handleWaitTask— block until task exitsStopTask— send signal + wait for exit with timeoutDestroyTask— clean up resourcesInspectTask— detailed task infoTaskStats(stream)— streaming resource usage metricsTaskEvents(stream)— streaming task lifecycle eventsSignalTask— send arbitrary signal (optional capability)ExecTask— one-shot command execution (optional)ExecTaskStreaming— interactive exec with streaming stdin/stdout (optional)CreateNetwork/DestroyNetwork— network namespace management (optional)NetworkIsolationSpec— get network isolation details (optional)
Transport#
All plugin gRPC runs over stdio (hashicorp/go-plugin with GRPCServer/GRPCClient). The Nomad client forks the plugin binary and connects over stdin/stdout pipes — this is not network-accessible.
CLI#
- Framework:
hashicorp/cli(not cobra). Commands registered as amap[string]cli.CommandFactoryincommand/commands.go. - Top-level binary:
nomad <command> [subcommands] [flags]
Command structure#
| Top-level | Subcommands |
|---|---|
acl | auth-method (create/delete/info/list/update), binding-rule (create/delete/info/list/update), bootstrap, policy (apply/delete/info/list/self), role (create/delete/info/list/update), token (create/update/delete/info/list/self) |
alloc | exec, signal, pause, stop, fs, logs, restart, checks, status |
agent | (starts the agent process) |
config | validate |
deployment | fail, list, pause, promote, resume, status, unblock |
eval | delete, list, status |
job | action, allocs, restart, deployments, dispatch, eval, history, init, inspect, periodic (force), plan, promote, revert, run, scale, scaling-events, status, stop, start, tag (apply/unset), validate |
namespace | add, delete, inspect, list, status |
node | config, drain, eligibility, meta (apply/read), pool (apply/delete/info/init/jobs/list/nodes), status |
operator | autopilot (get/set-config, health), client-state, debug, gossip (keyring install/use/list/remove/generate), metrics, raft (list-peers/remove-peer/transfer-leadership/info/logs/state/migrate-backend), root (keyring list/remove/rotate), scheduler (get/set-config), snapshot (save/inspect/state/restore/redact), utilization |
plugin | status |
quota | apply, delete, init, inspect, list, status |
scaling | policy (info/list) |
server | force-leave, join, members |
service | list, info, delete |
setup | consul, vault |
system | gc, reconcile summaries |
tls | ca (create/info), cert (create/info) |
var | purge, init, list, put, lock, get |
version | — |
volume | init, status, register, deregister, detach, create, delete, snapshot (create/delete/list), claim (list/delete) |
Legacy top-level aliases exist for run, stop, start, plan, inspect, exec, fs, status, validate, alloc-status, eval-status, server-force-leave, server-join, server-members, client-config — all delegate to their modern equivalents.
Flag patterns#
- Global flags:
-address,-region,-namespace,-token,-ca-cert,-client-cert,-client-key,-tls-server-name— available on all commands. - Output format: many commands accept
-t(Go template),-json,-verbose,-short. - Env var binding:
NOMAD_ADDR,NOMAD_REGION,NOMAD_NAMESPACE,NOMAD_TOKEN,NOMAD_CACERT,NOMAD_CLIENT_CERT,NOMAD_CLIENT_KEYmap to the corresponding global flags.
Plugin / Extension system#
- Mechanism:
hashicorp/go-pluginwith gRPC transport over stdio. Each plugin is a separate OS process forked by the Nomad client. - Extension points:
- Task drivers — implement
plugins/drivers.DriverPlugininterface (materialized as theDrivergRPC service). Ships as a named binary (e.g.,nomad-driver-lxc). - Device plugins — implement
plugins/device.DevicePlugininterface. Discover and expose hardware devices (GPUs, FPGAs, etc.) to Nomad. - CSI plugins — Container Storage Interface drivers. Communicate over a Unix socket using the standard CSI spec, managed via
client/dynamicplugins.
- Task drivers — implement
- Plugin discovery: The
pluginmanagerpackage scans a configured plugin directory at startup. Plugins are identified by theBasePlugin.PluginInfo()RPC response. - Built-in drivers:
docker,exec,rawexec,java,qemu— all live indrivers/and implement the sameDriverPlugininterface as external drivers. - Versioning: The
plugin_api_versionsfield inPluginInfoResponseallows version negotiation between Nomad client and driver.
Library API (api/ package)#
The api/ package is the official Go client library for Nomad, used by the CLI and available for third-party tooling.
- Public packages:
github.com/hashicorp/nomad/api— single package exposing all resources. - API style: Resource-oriented facades.
Clienthas accessor methods that return typed service objects:c.Jobs()→*Jobsc.Nodes()→*Nodesc.Allocations()→*Allocationsc.Deployments()→*Deploymentsc.Evaluations()→*Evaluationsc.ACLPolicies(),c.ACLTokens(),c.ACLRoles(), etc.c.CSIVolumes(),c.Namespaces(),c.Variables(), etc.
- Blocking query support: All read methods accept
*QueryOptionswithWaitIndexandWaitTime. Returns*QueryMetacontaining the response index for chaining. - Write methods: All mutations accept
*WriteOptionsand return*WriteMeta. - Streaming: WebSocket-based streaming for
Allocations.Exec()(interactive), log following. TheEvents.Stream()method returns a channel of*Events. - TLS: Full TLS config support via
TLSConfigstruct passed toNewClient(). - Backward compatibility: The package follows Nomad’s versioning; breaking changes tracked via changelog. No explicit semantic import versioning (
v2).