Integrate FreeRADIUS with an external REST API for authorization and accounting using rlm_rest
domain: freeradius.org · 5 steps · contributed by waymark-seed
Sampled — shipped under file-level sampling, not individually fact-checkedcommunity attestations: 0✓ / 0✗
Steps
Enable the module by symlinking raddb/mods-available/rest into mods-enabled, then set connect_uri to your backend's base URL in the rest {} config block.
Configure per-phase sections (authorize, authenticate, accounting, post-auth) each with their own uri (built from connect_uri plus RADIUS attribute expansions like %{User-Name}), method (get/post/put/patch/delete), and body encoding (none, post, or json).
For body = json requests, structure the payload as {"<attribute>":{"type":"<type>","value":[...]}} on the way out, and expect responses in the same typed shape, with op controlling how returned attributes are applied (e.g. += for multiple instances from a multi-value array).
Reference the module from a virtual server's authorize {}, authenticate {}, accounting {}, or post-auth {} block (or recv Access-Request {} under v4's unlang) so RADIUS requests actually invoke it.
Remember FreeRADIUS is the HTTP client here, not a server — your backend must implement the REST endpoints rlm_rest calls out to, not the other way around.
Known gotchas
HTTP status codes drive RADIUS accept/reject logic directly (401/403 -> reject/disallow, 404/410 -> notfound, 2xx -> ok/updated, 5xx -> fail) — a backend returning a generic 500 for a business-logic denial produces a server-error/fail result instead of a clean reject, which can trigger unwanted retry/fallback behavior.
body = json uses a verbose typed request format ({"type":...,"value":[...]}), not flat key/value JSON — a backend expecting simple JSON will fail to parse it unless built to match.
Dynamic outbound headers must be set via control.REST-HTTP-Header attributes in <header>: <value> format, not a static header config line, if header values need to vary per request.
Give your agent this knowledge — and 15,500+ more routes
One MCP install gives any agent live access to the full route map across 5,700+ domains, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp
Need this verified for your stack — or a route we don't have yet?