Radiator Server Documentation — v10.34.1

collection

Defines a document collection within a RadiatorDB backend. Collections organize documents into logical groups and define their field schema for Radiator 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

OptionRequiredDescription
nameNoHuman-readable display name for Radiator UI
descriptionNoDescription text shown in Radiator UI
timeseriesNoTime-series PostgreSQL storage
revisionsNoArchived revision cleanup limits for normal storage
rolesYesGrants read and write access to specified RadiatorDB roles
keyYesOrdered key definition with one or more key fields
fieldNoZero or more payload field definitions
actionNoZero or more document actions shown in Radiator UI

name

Sets the display name shown in Radiator 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 Radiator UI.

description "WiFi users and support-managed credentials";

timeseries

The timeseries feature is experimental.

Configures time-series PostgreSQL storage for the collection. If omitted, the collection uses normal mutable storage with archived revisions.

Use this block for time-series storage:

timeseries {
    partition calendar-month;
    create-ahead 2;
    overflow quarantine;
}

Time-series collections are immutable. They do not support expiration, rename, soft delete, revision queries, or revision garbage collection. AAA backend pipeline query operations also do not support time-series collections. Management API reads remain supported.

Do not configure a revisions block with timeseries. Revision cleanup limits apply only to normal mutable collections.

The time-series parameters are:

  • partition selects calendar-hour, calendar-day, calendar-week, or calendar-month. Hourly partitions start at the top of each UTC hour. Weekly partitions start at Monday 00:00 UTC. The default is calendar-month.
  • create-ahead creates the current interval and this many complete future intervals. The allowed range is 0..=120. The default is 2.
  • overflow selects quarantine or error. The default is quarantine.

When overflow is error, set create-ahead to at least 1. Radiator rejects create-ahead 0 with overflow error because inserts would fail at the next partition boundary.

Radiator creates this finite partition window during startup. Long-running processes do not extend the window automatically.

revisions

Configures archived revision cleanup for a normal mutable collection. If you omit this block, garbage collection keeps all archived revisions for the collection.

revisions {
    age 30d;
    max 100;
}

The revisions block supports these optional parameters:

  • age removes archived revisions older than the configured duration. If omitted, RadiatorDB does not remove revisions based on age.
  • max keeps at most this many archived revisions for each document key. If omitted, RadiatorDB does not remove revisions based on count.

Garbage collection removes a revision when it exceeds either configured limit. The block does not change tombstone garbage collection.

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";
}
  • read roles can list and view documents.
  • write roles can create, edit, and delete documents. A write role also implicitly grants read access.
  • A collection must configure at least one read or write role. The parser rejects collections without a roles block or with an empty roles block.

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, every write validates the document against that schema, including AAA backend pipeline put queries, the Radiator UI, and the REST API. 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. Radiator 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 Radiator 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 Radiator 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 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:

TypeDescription
textFree-form text string.
passwordPassword-style value.
secretSecret-style value (e.g. API key or token).
numberNumeric value (integer or decimal).
booleanBoolean value (true or false).
datetimeRFC3339 date-time string. Example: "2026-12-31T23:59:59Z" for a termination date.
uuidRFC UUID string. Stored in canonical form.
uuid7RFC UUID version 7 string. Stored in canonical form.
ipIPv4 or IPv6 host address string. Stored in canonical form.
networkIPv4 or IPv6 CIDR network string. Stored in canonical form.
macMAC address string. Stored in canonical form.
enumEnumerated 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 /32 or /128. CIDR values must not contain host bits.
  • uuid and uuid7: Stored in canonical lowercase hyphenated UUID form. uuid7 accepts only UUID version 7 values.
  • mac: Accepts common formats such as AA:BB:CC:DD:EE:FF, AA-BB-CC-DD-EE-FF, and AABB.CCDD.EEFF. Stored as 12 lowercase hex digits, for example aabbccddeeff.

When Radiator 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

OptionRequiredDescription
nameNoHuman-readable display name for the field
typeYesField data type
item-typeNoList item validation mode (only valid for list type)
requiredNoWhether the field is mandatory. Default: false
maskedNoHides the stored value on read. Default: false
defaultNoDefault value for new documents
valueNoAllowed enum option (repeatable for enum fields or list items)
fieldNoNested field definition (only valid for list type)
actionNoNested action definition (only valid for list type)

Field name

Sets the display name for the field in Radiator UI:

field "macAddress" {
    name "MAC Address";
    type text;
}

Field type

Specifies the data type for the field. Required for every field definition.

TypeDescription
anyAny JSON value, including strings, numbers, booleans, null, objects, and arrays.
textFree-form text string.
hexBinary value stored as lowercase hexadecimal with a 0x prefix.
passwordPassword field. Displayed masked in Radiator UI.
secretSecret value (e.g. TOTP secret, API key). Displayed masked in Radiator UI.
numberNumeric value (integer or decimal).
booleanBoolean value (true or false).
datetimeRFC3339 date-time string. Example: "2026-12-31T23:59:59Z" for a termination date.
ipIPv4 or IPv6 host address string. Example: "192.0.2.10" for a static IP.
networkIPv4 or IPv6 CIDR network string. Example: "192.0.2.0/24" for a site subnet.
enumEnumerated value. Allowed options must be defined with value directives.
listJSON array. Set item-type, or define item structure with child field blocks.

Fields with type any accept strings, numbers, booleans, null, objects, and arrays. Radiator UI shows these fields as JSON textareas. It parses the textarea before saving and preserves the JSON value type.

Hex fields accept hexadecimal strings with or without a 0x prefix. RadiatorDB stores them in lowercase with the 0x prefix. Radiator UI edits hex fields with a text input. RadiatorDB put bindings encode raw byte values automatically.

Datetime fields accept RFC3339 and RFC2822 strings, dates, timezone-less datetimes, and Unix timestamps. Dates and timezone-less datetimes are interpreted as UTC. RadiatorDB stores all accepted datetime values as RFC3339 strings and preserves an explicit timezone offset.

required

Marks the field as mandatory when creating or editing documents through Radiator 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";
}

Nested fields

A list field defines its items with either item-type or nested field blocks. Do not combine these forms.

Set item-type to require every list item to have exactly that type. It accepts the same values as type, with the same validation and canonicalization:

field "filters" {
    name "Filters";
    type list;
    item-type text;
}

This configuration accepts a document payload such as:

{
  "filters": ["allow-office", "allow-vpn"]
}

Every item in filters must be a string. A number, boolean, object, array, or null item is rejected. item-type any accepts items of any JSON type. Omitting item-type is equivalent to item-type any when the list has no nested fields. The list item type requires every item to be an array but does not validate the contents of those arrays.

Use nested field blocks to define a list of custom objects. Each list item must be an object that follows the nested field definitions:

field "groups" {
    name "Groups";
    type list;

    field "group" {
        name "Group";
        type text;
        required true;
    }

    field "enabled" {
        name "Enabled";
        type boolean;
        required true;
    }
}

This configuration accepts a document payload such as:

{
  "groups": [
    { "group": "operators", "enabled": true },
    { "group": "auditors", "enabled": false }
  ]
}

Nested fields support the same options as top-level payload fields. The Radiator UI displays typed items with an editor appropriate for their type and displays custom objects in a nested list view.

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

OptionRequiredDescription
nameNoHuman-readable display name for the action
iconNoRadiator UI icon name used by Radiator UI
descriptionNoConfirmation dialog text
rolesYesOne or more allow roles for action visibility and invocation
fieldNoScalar input field shown in the confirmation dialog
@executeYesPipeline 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:

VariableDescription
docCurrent document payload fetched server-side. For deleted documents, this is the latest non-tombstone payload, or null if none exists.
keyMultivalue document key parts.
inputValidated action input object.
itemNested list item fetched from doc, or null for top-level actions.
pathNested list path array, or an empty array for top-level actions.
deletedBoolean 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;
    }
}