Skip to content

User Management: AAA, Groups, and RADIUS

RouterOS provides a layered access control system for router management:

  • Local users — accounts stored on the router itself, each assigned to a group
  • User groups — define what actions users can perform via policy flags
  • Remote AAA — delegate router login authentication to an external RADIUS server

The system uses local-first lookup: if a username exists locally, RADIUS is never consulted. RADIUS is only queried when the username is not found in the local database.

  • RouterOS v7 (most features also apply to v6)
  • For RADIUS: a reachable RADIUS server with a shared secret configured
  • For WinBox RADIUS login: CHAP support must be enabled on the RADIUS server

Local users are managed under /user:

# List all users
/user print
# Create a new user
/user add name=alice group=full password="S3curePass!" address=192.168.1.0/24 comment="NOC admin"
# Change a user's password
/user set alice password="N3wPass!"
# Restrict login to specific IP/subnet
/user set alice address=10.0.0.0/8
# Disable a user without deleting
/user set alice disabled=yes
# Force password change on next login
/user expire-password alice
PropertyTypeDescription
namestringUsername (alphanumeric, _, ., #, -, @)
passwordstringLogin password
groupstringGroup membership (controls permissions)
addressIP/mask or IPv6 prefixRestrict login to this host/network; empty = unrestricted
inactivity-timeouttimeAuto-logout after idle period (1min–24h, default 10min)
inactivity-policylogout | lockscreen | noneAction on inactivity timeout
commentstringFree-form description

RouterOS supports SSH public key authentication, eliminating the need for passwords for SSH logins.

Import a public key from file:

/user ssh-keys import public-key-file=alice.pub user=alice

Add a public key inline:

/user ssh-keys add user=alice key="ssh-rsa AAAA... alice@workstation"

Import a private key (for outbound SSH from router):

/user ssh-keys private import private-key-file=id_rsa user=admin passphrase=secret

User groups define the set of operations a user is permitted to perform. Each user belongs to exactly one group.

Three built-in groups are provided and cannot be deleted:

GroupPolicies
fullAll policies
writelocal,telnet,ssh,reboot,read,write,test,winbox,password,web,sniff,sensitive,api,romon,rest-api — no ftp, no policy
readlocal,telnet,ssh,reboot,read,test,winbox,password,web,sniff,sensitive,api,romon,rest-api — no ftp, no write, no policy

The built-in read group includes sensitive, reboot, and other powerful policies. Do not assign it to untrusted users. Create custom groups for minimal access.

PolicyDescription
localLog in from local console
telnetLog in via Telnet
sshLog in via SSH
ftpLog in via FTP; full file read/write/delete
winboxLog in via WinBox
webLog in via WebFig
apiAccess via API
rest-apiAccess via REST API
romonConnect to RoMon server
readRead router configuration
writeWrite router configuration (except user management)
policyUser management rights (requires write)
passwordChange own password
rebootReboot the router
testRun ping, traceroute, bandwidth tests
sniffRun packet sniffer and traffic generator
sensitiveView/change “hide sensitive” setting

Use ! to explicitly deny a policy: !ftp,!write means FTP and write are denied.

# Read-only operator: SSH and WinBox access, no sensitive data, no changes
/user/group/add name=operator policy=local,ssh,winbox,web,read,test,password,!write,!policy,!sensitive,!ftp
# Network admin: can read and write, but not manage users or see sensitive data
/user/group/add name=netadmin policy=local,ssh,winbox,api,rest-api,read,write,reboot,test,password,!policy,!sensitive,!ftp
# Verify
/user/group/print
/user add name=bob group=operator password="Str0ngPass#" address=10.10.0.0/24
/user add name=carol group=netadmin password="Adm1nPass#"
Login attempt
Is username in local /user database?
├── YES → authenticate locally, apply local group
└── NO → query RADIUS server (if use-radius=yes)
├── RADIUS ACCEPT → apply Mikrotik-Group from RADIUS reply
│ (falls back to default-group if not sent)
└── RADIUS REJECT → login denied
# Enable RADIUS authentication for router logins
/user aaa set use-radius=yes accounting=yes interim-update=5m default-group=read
PropertyTypeDescription
use-radiusyes | noQuery RADIUS when username not found locally
accountingyes | noSend login/logout accounting records to RADIUS
interim-updatetimeInterval for Interim-Update accounting packets
default-groupstringGroup assigned to RADIUS users when Mikrotik-Group VSA is absent
exclude-groupslistLocal groups excluded from RADIUS authentication flow
/radius add address=192.168.100.10 secret=RadiusSecret123 service=login authentication-port=1812 accounting-port=1813

To monitor RADIUS server statistics (requests, accepts, rejects, timeouts):

/radius monitor 0 once

RouterOS reads these attributes from the RADIUS Access-Accept reply:

AttributeDescription
Mikrotik-GroupGroup name to assign the user (maps to a local /user group)
Session-TimeoutMaximum session duration in seconds
Idle-TimeoutIdle timeout in seconds
Framed-IP-AddressIP address to assign (where applicable)
Mikrotik-Address-ListAdd user’s IP to a firewall address list
Mikrotik-Rate-LimitBandwidth limit (e.g. 10M/5M)
# Create a custom limited group
/user/group/add name=monitoring policy=local,ssh,read,test,!write,!policy,!sensitive,!ftp,!winbox
# Create the user locked to the monitoring server IP
/user add name=monitor group=monitoring password="M0n1tor!" address=10.0.10.5/32 comment="Zabbix monitoring"

Example 2: RADIUS-Authenticated Admin with Local Fallback

Section titled “Example 2: RADIUS-Authenticated Admin with Local Fallback”
# Local break-glass admin (never goes to RADIUS — exists locally)
/user add name=breakglass group=full password="EmergencyOnly!" address=192.168.0.0/24
# RADIUS for all other users
/user aaa set use-radius=yes default-group=read accounting=yes interim-update=10m exclude-groups=full
# RADIUS server
/radius add address=10.1.1.100 secret=SharedSecret99 service=login

RADIUS server sends Mikrotik-Group=full in Access-Accept to grant admin rights to specific users.

# Create user with no password (key-only)
/user add name=deploy group=write password=""
# Import the CI/CD system's public key
/user/ssh-keys/public/import public-key-file=deploy_rsa.pub user=deploy
  1. Confirm user exists and is not disabled:
    /user print where name=<username>
  2. Check address restriction — if address is set, login must come from that range.
  3. Confirm the group exists and has the required policies:
    /user/group/print where name=<group>
  1. Verify RADIUS reachability — use /radius test (see above).
  2. Check shared secret matches exactly on both sides.
  3. If logging in via WinBox, confirm CHAP is enabled on the RADIUS server.
  4. Enable logging to see RADIUS exchange:
    /system/logging/add topics=radius action=memory
    /log/print where topics~"radius"
  5. Confirm use-radius=yes is set:
    /user aaa print
  • Ensure accounting=yes and interim-update is set to a non-zero value.
  • If Mikrotik-Group is not returned by RADIUS, users get default-group — verify the RADIUS reply attributes.
  • Confirm the key is imported for the correct username:
    /user ssh-keys print
  • Verify the SSH client is using the matching private key.
  • Ensure the user’s group has ssh policy.

Hardware-validated on staging-router-02 (RouterOS 7.15.3, CHR x86_64), 2026-03-22.

[admin@staging-router-02] > /user print
Columns: NAME, GROUP, LAST-LOGGED-IN
# NAME GROUP LAST-LOGGED-IN
;;; system default user
0 admin full 2026-03-22 15:36:41
[admin@staging-router-02] > /user add name=alice group=full password="S3curePass!" address=192.168.1.0/24 comment="NOC admin"
[admin@staging-router-02] > /user set alice password="N3wPass!" address=10.0.0.0/8 disabled=yes
[admin@staging-router-02] > /user expire-password alice
[admin@staging-router-02] > /user print where name=alice
Flags: E - EXPIRED; X - DISABLED
Columns: NAME, GROUP, ADDRESS
# NAME GROUP ADDRESS
;;; NOC admin
1 EX alice full 10.0.0.0/8

expire-password sets the E flag; disabled=yes sets the X flag.

[admin@staging-router-02] > /user/group/print
0 name="read" policy=local,telnet,ssh,reboot,read,test,winbox,password,web,
sniff,sensitive,api,romon,rest-api,!ftp,!write,!policy
skin=default
1 name="write" policy=local,telnet,ssh,reboot,read,write,test,winbox,password,
web,sniff,sensitive,api,romon,rest-api,!ftp,!policy
skin=default
2 name="full" policy=local,telnet,ssh,ftp,reboot,read,write,policy,test,winbox,
password,web,sniff,sensitive,api,romon,rest-api
skin=default
[admin@staging-router-02] > /user/group/add name=operator policy=local,ssh,winbox,web,read,test,password,!write,!policy,!sensitive,!ftp
[admin@staging-router-02] > /user/group/add name=netadmin policy=local,ssh,winbox,api,rest-api,read,write,reboot,test,password,!policy,!sensitive,!ftp
[admin@staging-router-02] > /user/group/print
3 name="operator" policy=local,ssh,read,test,winbox,password,web,!telnet,!ftp,
!reboot,!write,!policy,!sniff,!sensitive,!api,!romon,!rest-api
skin=default
4 name="netadmin" policy=local,ssh,reboot,read,write,test,winbox,password,api,
rest-api,!telnet,!ftp,!policy,!web,!sniff,!sensitive,!romon
skin=default
[admin@staging-router-02] > /user aaa print
use-radius: no
accounting: yes
interim-update: 0s
default-group: read
exclude-groups:
[admin@staging-router-02] > /user aaa set use-radius=yes accounting=yes interim-update=5m default-group=read
[admin@staging-router-02] > /user aaa print
use-radius: yes
accounting: yes
interim-update: 5m
default-group: read
exclude-groups:
[admin@staging-router-02] > /radius add address=192.168.100.10 secret=RadiusSecret123 service=login authentication-port=1812 accounting-port=1813
[admin@staging-router-02] > /radius print
Columns: SERVICE, ADDRESS, SECRET
# SERVICE ADDRESS SECRET
0 login 192.168.100.10 RadiusSecret123
[admin@staging-router-02] > /radius monitor 0 once
pending: 0
requests: 0
accepts: 0
rejects: 0
resends: 0
timeouts: 0
bad-replies: 0
last-request-rtt: 0ms
[admin@staging-router-02] > /user ssh-keys print
Columns: USER, KEY-TYPE, BITS, KEY-OWNER
# USER KEY-TYPE BITS KEY-OWNER
0 admin ed25519 256 chr-staging-access

Note on path syntax: RouterOS 7 uses space-separated paths for SSH key management (/user ssh-keys import, /user ssh-keys add, /user ssh-keys print). The slash-delimited sub-path form /user/ssh-keys/public/... is not valid.