collection
Defines a document collection within a RadiatorDB backend. Collections organize documents into logical groups and define their field schema for the management UI and RadiatorDB REST API. Each collection must define a key block that contains one or more ordered key fields.
Context
Valid inside a radiatordb block.
Example
collection "users" {
roles {
read "support";
write "ops";
}
name "Users";
description "WiFi users and support-managed credentials";
key {
field {
name "Username";
type text;
}
}
field "passwordHash" {
name "Password Hash";
type password;
required true;
}
field "email" {
name "Email";
type text;
}
field "enabled" {
name "Enabled";
type boolean;
default true;
}
action "send-coa" {
name "Disconnect";
icon "Bolt";
buttonText "CoA";
tooltipText "Open the CoA disconnect form.";
description "Send a disconnect request for this user.";
field "reason" {
name "Reason";
type text;
}
roles {
allow "ops";
}
@execute {
set vars.username doc | jsonpath("$.username");
invoke "SEND-COA";
}
}
}
Collection Options
| Option | Required | Description |
|---|---|---|
name | No | Human-readable display name for the management UI |
description | No | Description text shown in the management UI |
roles | Yes | Grants read and write access to specified RadiatorDB roles |
key | Yes | Ordered key definition with one or more key fields |
field | No | Zero or more payload field definitions |
action | No | Zero or more document actions shown in the management UI |
name
Sets the display name shown in the management UI for this collection. If omitted, the collection identifier (the quoted string after collection) is used.
name "Users";
description
Provides a description for the collection displayed in the management UI.
description "WiFi users and support-managed credentials";
roles
Grants RadiatorDB roles read or write access to this collection. Roles are
matched against the authenticated user's RadiatorDB roles, which are populated
by the AAA pipeline (for example, from a RadiatorDB lookup exposing
user.radiatordb_role).
roles {
read "support";
write "ops";
}
readroles can list and view documents.writeroles can create, edit, and delete documents. Awriterole also implicitly grants read access.- A collection must configure at least one
readorwriterole. The parser rejects collections without arolesblock or with an emptyrolesblock.
field
Defines a typed payload field within the collection. Each field is identified by its JSON field name (the quoted string after field).
When a collection declares one or more field blocks, the management UI and REST API validate every write against that schema: required fields must be present, typed values must match their declared type, and any field name not in the schema is rejected. Collections with no field declarations accept arbitrary JSON document bodies.
field and action blocks share the same ordered namespace in a collection.
The management UI renders visible fields and actions in the configured order.
Do not reuse a field or action identifier within the same collection. You may
reuse an action identifier in a different nested list field.
action
Defines an invokable action for each document in the collection. Actions are
shown in management UI tables and document detail pages when the authenticated
user can read the collection and has one of the action's roles allow roles.
Actions can run for active and soft-deleted documents.
action "send-coa" {
name "Disconnect";
icon "Bolt";
buttonText "CoA";
tooltipText "Open the CoA disconnect form.";
description "Send a disconnect request for this user.";
roles {
allow "ops";
}
@execute {
invoke "SEND-COA";
}
}
The action identifier is the quoted string after action. The optional name
sets the full action label used for the accessibility label and confirmation
dialog title. If name is omitted, the identifier is used. The
optional description is shown in the confirmation dialog. If description is
omitted, the UI shows a generic confirmation prompt.
Set icon to a supported Material UI icon name. Unknown icon names are not
configuration errors; the UI falls back to its default action icon.
Set buttonText when the visible button copy should be shorter or different
from the full action name. Labeled buttons render buttonText inline next to
the icon. If buttonText is omitted, labeled buttons render the action name.
Set tooltipText to show a Material UI tooltip for the action button. Tooltips
are opt-in; if tooltipText is omitted, action buttons do not show a tooltip.
key
Defines the ordered document key fields for the collection. The stored key is multipart when more than one key field is configured.
key {
field {
name "Site";
type text;
}
field {
name "Created At";
type datetime;
}
}
Key field types
Set type to one of the following values:
| Type | Description |
|---|---|
text | Free-form text string. |
password | Password-style value. |
secret | Secret-style value (e.g. API key or token). |
number | Numeric value (integer or decimal). |
boolean | Boolean value (true or false). |
datetime | RFC3339 date-time string. Example: "2026-12-31T23:59:59Z" for a termination date. |
uuid | RFC UUID string. Stored in canonical form. |
uuid7 | RFC UUID version 7 string. Stored in canonical form. |
ip | IPv4 or IPv6 host address string. Stored in canonical form. |
network | IPv4 or IPv6 CIDR network string. Stored in canonical form. |
mac | MAC address string. Stored in canonical form. |
enum | Enumerated value. Allowed options must be defined with value directives. |
Key normalization
RadiatorDB validates typed key values before storing a document. These key types are also normalized:
ip: Stored in canonical IP address form.network: Stored in canonical CIDR form. A bare IP address becomes a host network with/32or/128. CIDR values must not contain host bits.uuidanduuid7: Stored in canonical lowercase hyphenated UUID form.uuid7accepts only UUID version 7 values.mac: Accepts common formats such asAA:BB:CC:DD:EE:FF,AA-BB-CC-DD-EE-FF, andAABB.CCDD.EEFF. Stored as 12 lowercase hex digits, for exampleaabbccddeeff.
When the management UI opens a new document form, key fields with type
datetime, uuid, or uuid7 get an initial generated value if no explicit
default value is configured.
Field Options
| Option | Required | Description |
|---|---|---|
name | No | Human-readable display name for the field |
type | Yes | Field data type |
required | No | Whether the field is mandatory. Default: false |
masked | No | Hides the stored value on read. Default: false |
default | No | Default value for new documents |
value | No | Allowed enum option (repeatable, only valid for enum type) |
index | No | Database index type. Only gin is supported. |
field | No | Nested field definition (only valid for list type) |
action | No | Nested action definition (only valid for list type) |
Field name
Sets the display name for the field in the management UI:
field "macAddress" {
name "MAC Address";
type text;
}
Field type
Specifies the data type for the field. Required for every field definition.
| Type | Description |
|---|---|
text | Free-form text string. |
password | Password field. Displayed masked in the management UI. |
secret | Secret value (e.g. TOTP secret, API key). Displayed masked in the management UI. |
number | Numeric value (integer or decimal). |
boolean | Boolean value (true or false). |
datetime | RFC3339 date-time string. Example: "2026-12-31T23:59:59Z" for a termination date. |
ip | IPv4 or IPv6 host address string. Example: "192.0.2.10" for a static IP. |
network | IPv4 or IPv6 CIDR network string. Example: "192.0.2.0/24" for a site subnet. |
enum | Enumerated value. Allowed options must be defined with value directives. |
list | Ordered list of sub-documents. Nested structure defined with child field blocks. |
required
Marks the field as mandatory when creating or editing documents through the management UI:
field "hostname" {
name "Hostname";
type text;
required true;
}
Default: false
masked
Hides the stored value when documents are read through the management API. Masked fields are returned as a masking sentinel rather than their real value, so sensitive data such as password hashes is never sent to the browser. The field remains editable: leaving it blank in the editor keeps the stored value unchanged, while typing a new value replaces it.
field "passwordHash" {
name "Password Hash";
type text;
masked true;
}
Masking only applies to top-level fields; values nested inside list fields are
not masked.
Default: false
default
Sets a default value for new documents. Accepts strings, numbers (including negative), and booleans:
field "enabled" {
type boolean;
default true;
}
field "deviceType" {
type enum;
default "AP";
value "AP";
value "Switch";
value "Router";
}
value (enum options)
Defines an allowed value for an enum field. Repeat the value directive for each option. Only valid when type is enum.
field "authMode" {
name "Auth Mode";
type enum;
required true;
default "PEAP";
value "PEAP";
value "TTLS";
value "EAP-TLS";
}
index
Specifies a database index for the field. Only gin is supported. Indexes improve query performance for where clause filters on the indexed field.
field "tags" {
type text;
index gin;
}
Nested fields (list type)
Fields with type list contain an ordered collection of sub-documents. Define
the structure of each list item using nested field blocks:
field "groups" {
name "Groups";
type list;
field "group" {
name "Group";
type text;
}
}
Nested fields support the same options as top-level payload fields. Nested
action blocks are also valid inside list fields. The UI shows nested actions
for each item in the nested list view.
field "sessions" {
name "Sessions";
type list;
field "mac" {
name "MAC";
type text;
}
action "disconnect-session" {
name "Disconnect session";
roles {
allow "ops";
}
@execute {
set vars.session_mac item | jsonpath("$.mac");
invoke "SEND-COA";
}
}
}
Action Options
| Option | Required | Description |
|---|---|---|
name | No | Human-readable display name for the action |
icon | No | Material UI icon name used by the management UI |
description | No | Confirmation dialog text |
roles | Yes | One or more allow roles for action visibility and invocation |
field | No | Scalar input field shown in the confirmation dialog |
@execute | Yes | Pipeline to run when the action request is accepted |
Action roles
Each action must configure roles { allow "..." }. The user must have
collection read access and one of the action's allow roles. Users without an
allow role do not see the action and cannot invoke it through the REST API.
roles {
allow "ops";
allow "admin";
}
Action input fields
Action field blocks define optional confirmation dialog inputs. These fields
are not stored in the document. They are validated and exposed to the
@execute pipeline through the input local variable.
Action inputs are scalar only. Supported types are text, password,
secret, number, boolean, datetime, ip, network, and enum.
list fields and nested fields are not valid action inputs.
field "reason" {
name "Reason";
type text;
}
Action execute pipeline
The @execute block runs after the request is authorized and action input is
validated. The action succeeds only when this pipeline accepts. Reject and
ignore results make the REST API return 400.
If the pipeline sets aaa.message, for example with accept "Disconnect queued.";
or the message action, the REST API returns that message to the UI. If the
pipeline accepts without a message, the UI closes the confirmation dialog
without showing a success notification. aaa.reason and pipeline errors are
not returned to the UI because they can contain sensitive operational details.
The pipeline receives these local variables:
| Variable | Description |
|---|---|
doc | Current document payload fetched server-side. For deleted documents, this is the latest non-tombstone payload, or null if none exists. |
key | Multivalue document key parts. |
input | Validated action input object. |
item | Nested list item fetched from doc, or null for top-level actions. |
path | Nested list path array, or an empty array for top-level actions. |
deleted | Boolean that is true when the target document is soft-deleted. |
The server fetches doc and nested item by key, path, and item index. It does
not trust document or item data from the client request.
Complete Example
collection "devices" {
roles {
read "support";
write "ops";
}
name "Devices";
description "Network devices available for policy lookups";
key {
field {
name "Site";
type text;
}
field {
name "Hostname";
type text;
}
}
field "managementNetwork" {
name "Management Network";
type network;
required true;
}
field "managementIp" {
name "Management IP";
type ip;
required true;
}
field "deviceType" {
name "Device Type";
type enum;
required true;
default "AP";
value "AP";
value "Switch";
value "Router";
}
field "location" {
name "Location";
type text;
}
field "tags" {
name "Tags";
type list;
field "tag" {
name "Tag";
type text;
}
}
field "snmpSecret" {
name "SNMP Secret";
type secret;
}
field "managed" {
name "Managed";
type boolean;
default true;
}
field "vlan" {
name "VLAN";
type number;
required true;
}
field "warrantyExpires" {
name "Warranty Expires";
type datetime;
}
}