Skip to main content
RunBook Academy

VyOSXLVII · Management Plane HardeningMgmtPlane

HTTP API authentication — keys, localhost binding, TLS, the gRPC alternative

Intermediate⏱ ~20 minset service httpsshow service httpscurl -k https://<host>/api/...vyos

What you'll learn

  • Enable the HTTP API on VyOS 1.5 with key-based authentication
  • Restrict the API to localhost for local automation
  • Configure TLS for remote API access
  • Recognise the production failure modes where the API is open or unauthenticated

Prerequisites

Verified against VyOS 1.5.x LTS (circinus) · VyOS 1.4.x (sagitta) — legacy · FRRouting 10.x (VyOS 1.5) · Linux kernel 6.6 LTS (VyOS 1.5 base) · strongSwan 5.9.x (IPsec) · WireGuard 1.0.x (kernel module + userspace tooling) · 2026-08-15

Not yet marked complete on this device.

VyOS 1.5 LTS exposes an HTTP API for automation. The API allows Ansible, Terraform, custom scripts, and CI/CD pipelines to push configuration changes without interactive SSH sessions. The API uses HTTP over TLS, authenticates with API keys, and logs every request to syslog.

This lesson covers the HTTP API authentication model on VyOS 1.5, the localhost binding for local automation, the TLS configuration for remote automation, the rate-limit and audit-log controls, and the gRPC alternative for high-throughput automation.

The API access model

flowchart LR
  subgraph Internal["Localhost only"]
    A1["Ansible<br/>on the router"] -->|HTTP localhost| API
  end
  subgraph Remote["Remote network"]
    A2["Ansible controller"] -->|HTTPS over mgmt VRF| API
    A3["Terraform<br/>CI/CD"] -->|HTTPS| API
  end
  API["VyOS HTTP API<br/>port 8443"] --> AUDIT["Syslog audit log"]
  API --> CFG["Configuration tree"]
  AUDIT --> CENTRAL["Central syslog server"]

The API has two deployment patterns:

  • Localhost binding — the API listens on 127.0.0.1. Only processes on the router can reach the API. Used by Ansible running locally on the router, custom scripts, or any automation that runs on the router itself.
  • Remote binding — the API listens on the management VRF address. Remote automation (Ansible controller, Terraform, CI/CD) can reach the API over TLS.

Enabling the API

configure
set service https api keys id my-key key '<secret-key-string>'
set service https api keys id my-key user 'vyos'
set service https listen-address 127.0.0.1
set service https port 8443
set service https certificates cert-file '/etc/ssl/certs/vyos-api.crt'
set service https certificates key-file '/etc/ssl/private/vyos-api.key'
commit
save

The configuration:

  • keys id my-key — defines a named API key. The user is the VyOS user the key authenticates as; key is the secret string the API client sends.
  • listen-address 127.0.0.1 — the API listens on localhost only. No remote access.
  • port 8443 — the API listens on port 8443 (non-default).
  • certificates — the TLS certificate and key for the API.

Localhost binding

For local automation, the API listens on 127.0.0.1 only:

set service https listen-address 127.0.0.1

The API is not reachable from any remote network. Local automation on the router (Ansible playbooks running on the router, cron jobs, custom scripts) can reach it via https://127.0.0.1:8443/.

The local automation uses the API to push configuration:

curl -k -X POST \
  -H "X-API-Key: my-secret-key" \
  -H "Content-Type: application/json" \
  -d '{"op":"set","path":["interfaces","ethernet","eth0","address"],"value":"192.0.2.50/24"}' \
  https://127.0.0.1:8443/configure

The API authenticates the key, applies the change to the candidate configuration, and returns a JSON response with the result.

Remote binding

For remote automation, the API binds to the management VRF:

set service https listen-address 10.0.0.1
set service https vrf mgmt

The API is reachable from any host that can route to 10.0.0.1 over the management network. The API never listens on a production interface.

TLS configuration

set service https certificates cert-file '/etc/ssl/certs/vyos-api.crt'
set service https certificates key-file '/etc/ssl/private/vyos-api.key'
set service https certificates ca-cert-file '/etc/ssl/certs/ca-chain.crt'

The API serves HTTPS only. The certificate and key are at the configured paths; the CA chain validates the client certificate (if mutual TLS is configured).

For production, the certificate is signed by an internal CA or by Let’s Encrypt (covered in the PKI lesson). The certificate rotates on a regular cadence.

Authentication — API keys

set service https api keys id ansible-prod key 'a-long-random-string'
set service https api keys id ansible-prod user 'vyos'
set service https api keys id terraform-cicd key 'another-long-random-string'
set service https api keys id terraform-cicd user 'vyos'

The API supports multiple keys, each bound to a VyOS user. The user field determines the permissions of the key — the API enforces the same RBAC as SSH (covered in the user-roles lesson).

The client sends the key in the X-API-Key header:

curl -k -H "X-API-Key: a-long-random-string" https://10.0.0.1:8443/show/version

Mutual TLS

For higher-security environments, the API supports mutual TLS (mTLS). The client presents a certificate signed by a CA the router trusts:

set service https certificates ca-cert-file '/etc/ssl/certs/internal-ca.crt'
set service https api auth-type 'certificate'

The client uses a certificate instead of (or in addition to) an API key:

curl --cert /path/to/client.crt --key /path/to/client.key https://10.0.0.1:8443/show/version

mTLS is stronger than API keys because the client must possess the private key, not just a string. mTLS is the production pattern for high-security environments.

Rate limiting

set service https api rate-limit '60'

The API rate-limits requests to 60 per minute per IP. An attacker (or a misbehaving script) cannot flood the API. The operator can adjust the limit if needed.

Audit logging

set system syslog host 203.0.113.100 facility all level info

Every API request is logged to syslog:

Aug 15 12:00:01 R1 vyos-http-api: INFO [api] POST /configure from 10.0.0.50 (key ansible-prod, user vyos) - 200 OK
Aug 15 12:00:05 R1 vyos-http-api: INFO [api] GET /show/version from 10.0.0.50 (key terraform-cicd, user vyos) - 200 OK
Aug 15 12:00:10 R1 vyos-http-api: WARN [api] POST /configure from 10.0.0.99 (key INVALID, user unknown) - 401 Unauthorized

The audit log shows every request, the source IP, the API key, the user, and the response code. The operator can review the log for forensic analysis or to detect anomalies.

How the result is validated

show configuration service https
curl -k -H "X-API-Key: <key>" https://127.0.0.1:8443/show/version
curl -k -H "X-API-Key: <key>" https://127.0.0.1:8443/show/configuration

The first shows the API configuration. The second tests the API connectivity with the configured key. The third tests a read endpoint.

A working API:

  • Returns 200 OK with valid credentials
  • Returns 401 Unauthorized with invalid credentials
  • Returns 403 Forbidden when the key has insufficient permissions
  • Logs every request to syslog
vyos@R1:~$ curl -k -H "X-API-Key: my-secret-key" https://127.0.0.1:8443/show/version
{"version": "1.5-rolling-202408020557", "arch": "amd64"}

The gRPC alternative

For high-throughput automation, VyOS 1.5 LTS exposes a gRPC API:

set service grpc listen-address 10.0.0.1
set service grpc port 9119
set service grpc certificates cert-file '/etc/ssl/certs/vyos-grpc.crt'
set service grpc certificates key-file '/etc/ssl/private/vyos-grpc.key'
set service grpc authentication tls-required
commit
save

The gRPC API uses HTTP/2 and protobuf for high-throughput, low-latency automation. Authentication is via mTLS (no API keys). The gRPC API is the production pattern for Terraform, custom automation, and high-volume configuration changes.

How it fails

The production failure modes:

  • API bound to production interface. The API is reachable from the Internet or from production networks. The fix: bind to localhost or mgmt VRF.
  • API key in source code. The API key is committed to a public Git repository. The fix: use a secrets manager, rotate the key.
  • No TLS. The API serves HTTP without TLS. Credentials are sent in plain text. The fix: configure TLS.
  • Default port 8443 changed to default 443. The API on a default port is scanned by attackers. The fix: keep the non-default port.
  • Audit log not exported. The operator cannot review API requests. The fix: configure syslog export.
  • Rate limit too low. Legitimate automation is rate-limited. The fix: tune the rate limit to the automation volume.
  • No mTLS for high-security. API keys are bearer tokens; possession of the key is authentication. The fix: use mTLS.

Rollback

The recovery from a broken API configuration:

  • Wrong bind address: connect via SSH or OOB and fix the listen-address.
  • Wrong API key: connect via SSH or OOB and rotate the key.
  • API unreachable: connect via SSH and check the configuration, the certificate, the firewall.

The VyOS configuration rollback (rollback N) restores the previous revision if the API change breaks automation.

Production discipline

Cross-course references

  • XLVII-VyOS-MgmtPlane (vyos-xlvii-01-ssh-hardening, vyos-xlvii-03-source-restrictions, vyos-xlvii-05-user-roles, vyos-xlvii-06-pki-and-cert-rotation) cover the rest of the management plane hardening.
  • LIV-VyOS-Automation (vyos-liv-02-ansible-integration) covers the Ansible integration that uses this API.
  • XXVI-Linux-SSH (Linux course) covers the underlying SSH server configuration.

Quiz

Knowledge check · 4 questions

  1. Q1. Why is binding the HTTP API to a production interface a security anti-pattern?

  2. Q2. VyOS 1.5 LTS HTTP API is enabled by default with a well-known default key.

  3. Q3. An operator deploys Ansible integration with the VyOS HTTP API. The operator binds the API to 192.0.2.1 (a production interface). After a week, the auth log shows thousands of POST requests from random Internet IPs. What happened and what is the fix?

    The operator bound the API to a production interface that is reachable from the Internet. Opportunistic scanners discovered the API endpoint and began probing it with brute-force authentication attempts. The API is rejecting the requests (401 Unauthorized), but the auth log is filled with noise and the API is consuming resources on every request.

  4. Q4. An operator stores the API key in plain text in a Git repository. The repository is later made public (or a contractor with access leaks the key). What is the impact and what is the fix?

    The API key is a bearer token: whoever possesses the key is authenticated as the configured user. A leaked key is a permanent credential until rotated. An attacker with the key can push configuration changes to the router — including adding new routes, modifying firewall rules, or disabling security controls.

Passing score: 75%. Answers are checked in this browser.