Custom Lua scripts configuration for extending AAA processing logic
scripts
The scripts clause registers named Lua scripts that can be invoked from AAA
pipelines (authentication / authorization / accounting hooks, maps, or other
extensible points). Scripts enable custom logic, enrichment, transformation,
and external integration without recompiling the server.
Each lua block defines exactly one script by name. Source can be loaded from a
file (filename) or embedded inline using content. A script is compiled the
first time it is executed (or explicitly requested), then cached until its
version changes (e.g. configuration reload with modified content).
Structure
scripts {
lua "auth_enrichment" {
filename "./lua/auth_enrichment.lua";
}
lua "inline_example" {
content "
function main(context, previous)
-- context is an AAA context object
-- previous is the Option<bool> result from prior action (may be nil)
-- Return:
-- true -> accept (if used in a decision point)
-- false -> reject
-- nil -> no explicit decision
return nil
end
";
}
}
Blocks and Statements
| Element | Context | Required | Description |
|---|---|---|---|
scripts { ... } | top-level | No (only needed if you use scripts) | Container for script definitions |
lua "NAME" { ... } | inside scripts | Yes (≥1) | Declares a script with the given name |
filename "path"; | inside lua | One of filename or content | Loads Lua source from file |
content "…"; | inside lua | One of filename or content | Inline Lua source (quoted multi-line string) |
Exactly one of filename or content must be present in a lua block. If both
are provided the configuration is invalid.
Naming
Script names are case sensitive. Reusing a name overwrites the earlier definition in the same configuration pass (last one wins), but you should treat duplicates as a configuration smell and avoid them.
Runtime Model (Summary)
- Configuration parser registers all script definitions (name + source origin).
- When a script is executed the runtime:
- Compiles it (if not yet compiled).
- Caches the compiled function keyed by script name and a version token.
- Subsequent invocations reuse the compiled function unless the script changed.
- Script runs inside a sandboxed Lua VM with restricted environment (no direct uncontrolled filesystem or OS access unless exposed explicitly).
- Script receives:
- An AAA context userdata exposing sub-contexts (protocol, acct, user data, etc.).
- The previous optional boolean result (if part of a sequential pipeline).
Return semantics:
true→ Treated as an explicit accept (where meaningful).false→ Treated as an explicit reject.nil→ Neutral; processing continues.
(Exact decision integration depends on where you inject the script; a neutral return simply delegates to subsequent pipeline steps.)
Common Use Cases
| Use Case | Approach |
|---|---|
| Attribute enrichment | Fetch external values (HTTP backend + mapping) then augment response via script |
| Conditional policy tuning | Inspect combined attributes and set control variables |
| Audit tagging | Log structured events (using provided logging or by setting response fields) |
| Dynamic authorization | Compute accept/reject based on composite or temporal logic |
Example Script (File-Based)
./lua/auth_enrichment.lua:
function main(context, previous)
-- Example: add a tag if realm matches
local realm = context:aaa().realm
if realm == "example.com" then
-- Set response attribute via helper (pseudo accessor)
-- context:set("response.reply-message", "Welcome example.com user")
end
return nil
end
Configuration:
scripts {
lua "auth_enrichment" {
filename "./lua/auth_enrichment.lua";
}
}
Then used inside an authorization block (pseudo):
authorization {
# call script "auth_enrichment"
script "auth_enrichment";
accept;
}