Documentation

SAMM documentation

The complete operator manual — from first install to day-to-day operations.

25 topics 8 sections One-command install
Quick install

Online in minutes, from one command.

Run a single line on a fresh Ubuntu or Debian server — the bootstrapper fetches the latest release and installs the whole SAMM stack for you.

Read the full installation guide
install.sh — bash
curl -fsSL https://samm.securytik.com/install.sh | sudo bash

Getting started

Overview & architecture

SAMM — SecuryTik Active Mikrotik Manager — is a complete ISP management platform for MikroTik PPPoE & Hotspot networks. One installer turns a bare Linux server into a full AAA, billing, and subscriber-management system.

Who SAMM is for

SAMM is built for wireless ISPs, fibre operators, and hotspot providers running MikroTik RouterOS. If you authenticate subscribers over PPPoE or Hotspot and need to enforce speed tiers, data caps, expiry dates, and billing — SAMM does all of it from one screen.

How it works

SAMM keeps the hot path close to the database. FreeRADIUS handles every authentication and accounting packet; on each accounting Interim-Update it calls PostgreSQL functions directly to accumulate usage and evaluate limits — there is no Python round-trip while subscribers are online.

Four execution surfaces cooperate through the single database:

  • FreeRADIUS (unlang + rlm_sql) — authenticates every packet; on each Interim-Update it accumulates bytes/uptime and evaluates limits inside Postgres.
  • samm-radius — runs time-driven sweeps (expiry, daily reset, speed windows) and is the only process that sends Change-of-Authorization packets.
  • samm-worker — pings routers and syncs MikroTik device metadata over the API.
  • samm-api — the admin & customer portals; admin actions are queued to the database and applied by samm-radius, never sent as CoAs directly.

The five services

ServiceRole
samm-apiAdmin portal + customer self-service portal + REST API
samm-radiusDrains the CoA outbox; runs expiration / daily-reset / speed-window sweeps
samm-workerPings routers; syncs MikroTik device metadata over the API
samm-notificationDelivers email & Telegram notifications through one throttled queue
samm-telegramRuns the interactive Telegram self-service bot

What SAMM does

AAA core

PPPoE & Hotspot authentication, per-user speed enforcement, hybrid CoA.

Plans & limits

Speed tiers plus four independent limits and scheduled speed windows.

Subscribers

PPPoE/Hotspot users plus prepaid hotspot voucher cards with printable PDFs.

Billing

Per-plan pricing, automatic invoices, a double-entry receipts/payments/expenses ledger.

Self-service

A customer web portal and a Telegram bot for usage, invoices, and tickets.

Operations

Live MikroTik inventory, role-based admins, backup & restore, bulk tools.

System

Built-in WireGuard VPN, Cloudflare Tunnel, six languages, themeable UI.

Notifications

Renewal, expiry, quota and receipt alerts over email and Telegram.

The rest of this manual is a how-to for every one of these areas. Use the menu on the left, or start with Installation.

Getting started

Installation

SAMM installs everything it needs — FreeRADIUS, PostgreSQL, nginx, WireGuard, cloudflared, and the five SAMM services — in one step. The installer is idempotent: re-running it upgrades an existing install in place and never overwrites your config or regenerates your database password.

SAMM runs anywhere — pick the install path that fits your network:

  • Option A / B — bare-Linux server (recommended for production): one-command or manual install on Ubuntu / Debian.
  • Option C — Docker Compose: same SAMM as containers; multi-arch (amd64 + arm64) so it runs on Ubuntu, Windows Docker Desktop, Apple-silicon Macs, anywhere.
  • Option D — MikroTik RouterOS 7 container: paste the compose YAML directly into your router. No external Linux box needed.

Prerequisites

  • A fresh server: Ubuntu 22.04 LTS, Ubuntu 24.04 LTS, or Debian 12. Server-grade Linux only — desktop variants are not supported.
  • Root / sudo access and an internet connection.
  • systemd, and a host where PostgreSQL can be installed locally (one is set up for you).

Option A — install with one command

On the server, run:

curl -fsSL https://samm.securytik.com/install.sh | sudo bash

This bootstrap script downloads the latest SAMM release bundle from GitHub, extracts it, and runs the full installer automatically. Done in a few minutes.

Option B — install manually from a release bundle

Download the latest samm-<version>.tar.gz from the GitHub Releases page, then on the server:

tar -xzf samm-<version>.tar.gz
cd samm-<version>
sudo bash install.sh

You can also deploy from a zip produced on another machine — the installer rsyncs the source into /opt/samm itself:

mkdir -p /opt/samm && unzip samm.zip -d /tmp/samm-bundle
sudo bash /tmp/samm-bundle/samm/install.sh

Or clone the repository to /opt/samm and run sudo bash /opt/samm/install.sh.

Either way, once the installer finishes, open the admin portal and sign in with these credentials:

Login URLhttp://<your-server>/admin · Usernameadmin · Passwordadmin

Change the admin password immediately after your first login.

Option C — install with Docker Compose

If you'd rather run SAMM as containers — same product, packaged differently — use the Docker Compose distribution at github.com/mhdhaidarah/samm-docker. On any host with Docker available:

curl -fsSL https://github.com/mhdhaidarah/samm-docker/releases/latest/download/install.sh | sudo bash

That installs Docker if it's missing, drops a docker-compose.yml + .env into /opt/samm-docker/, and starts the stack. The image mhdhaidarah/samm is built from the same compiled bundle as the bare-OS install — closed source by construction.

Multi-arch since v2.2.6 — the same tag ships for linux/amd64 and linux/arm64. docker pull picks the right variant transparently, so the install path is identical on a 64-bit Intel/AMD server, an Apple-silicon Mac running Docker Desktop, or an ARM MikroTik device (RB5009, hAP ax², CCR2004/2116/2216) using RouterOS 7's container feature.

On hosts where piping curl to bash isn't allowed (locked-down boxes, strict egress policies), you can fetch the ready-to-run compose file directly:

git clone https://github.com/mhdhaidarah/samm-docker.git
cd samm-docker
cp .env.example .env
$EDITOR .env       # set POSTGRES_PASSWORD and SAMM_PUBLIC_HOST
docker compose up -d

A few features are not yet in the Docker variant (staged license lockdown, dynamic FreeRADIUS reload). The built-in WireGuard and Cloudflare Tunnel admin pages are intentionally hidden in the Docker variant — they manage host-level systemd services that aren't reachable from inside the container. Pick Option A or B above if you need those built in, or run cloudflared / wg-quick on the Docker host directly alongside SAMM. See the Docker variant's README for the full v1 caveats and the manual install path.

On Windows (Docker Desktop) — evaluation only

Not recommended for production. Windows sleep / hibernate / lid-close stops the containers; boot-restart only fires when WSL starts (not on Windows boot); the daily auto-update cron only runs while WSL is alive. Use it for evaluation / demo, then deploy production on a Linux VM (Hyper-V, Proxmox, ESXi) or a small physical box (e.g. a NUC running Ubuntu Server).

Install Docker Desktop for Windows (lets it set up the WSL2 backend on first launch). Then from PowerShell — no WSL terminal needed — grab the compose bundle and start the stack:

mkdir C:\samm-docker
cd C:\samm-docker
curl.exe -fLO https://github.com/mhdhaidarah/samm-docker/releases/latest/download/docker-compose.yml
curl.exe -fLO https://github.com/mhdhaidarah/samm-docker/releases/latest/download/env.example
copy env.example .env
notepad .env       # set POSTGRES_PASSWORD and SAMM_PUBLIC_HOST (your Windows LAN IPv4)
docker compose pull
docker compose up -d

Watch the stack boot in Docker Desktop → Containers — the samm group expands into 7 services. Once they're all green, open the admin portal and sign in with these credentials:

Login URLhttp://localhost:8000/admin · Usernameadmin · Passwordadmin

Change the admin password immediately after your first login.

If a real MikroTik NAS will hit this Windows host for RADIUS, allow UDP 1812 + 1813 through Windows Firewall:

New-NetFirewallRule -DisplayName "SAMM RADIUS" -Direction Inbound -Protocol UDP -LocalPort 1812,1813 -Action Allow

Tear down: docker compose down -v from the install dir (the -v wipes the postgres volume and the Fernet key — back them up first if you've added data).

Option D — install on a MikroTik router (RouterOS 7)

Same SAMM, no Linux box needed. If your MikroTik device supports the container package and has a USB drive or microSD attached, you can run the whole stack directly on the router. The image ships multi-arch (linux/amd64 + linux/arm64), so devices like RB5009, hAP ax², CCR2004/2116/2216 pull the right variant transparently.

Supported: arm64 MikroTik — RB5009, hAP ax², CCR2004-1G-12S+2XS, CCR2116, CCR2216. amd64 SKUs — CCR2004-1G-2XS-PCIe (amd64), x86 RouterOS, CHR on amd64 hypervisors.
Not supported: armv7 / mipsbe / smips / tile / ppc devices (hEX, RB750, older RB models) — no container support or too little RAM/CPU for SAMM's stack.

1. Prepare the router

Install the container package (from extra_packages.zip on mikrotik.com/download — upload the matching container-*.npk via Files, then reboot). Then enable container mode (one-time, requires a reboot):

/system device-mode update container=yes
# router reboots

2. Format and mount the disk (ext4)

Insert a USB drive or microSD (≥ 8 GB recommended — Postgres + image layers add up). On the router:

/disk print
# note the disk slot, e.g. "usb1-part1" or "disk1"
/disk format-drive usb1-part1 file-system=ext4 label=samm

After formatting, verify the disk mounts and is writable:

/disk print detail
# look for "type=ext4" and a mount point like "/usb1-part1"

3. Paste the compose YAML in the container app

In WebFig or WinBox open ContainerApps+ NewYAML. Paste the compose file below into the YAML field, set the disk you formatted in step 2 as the storage location, and submit. RouterOS will pull each image and wire the services up for you.

docker-compose.yaml — copy and paste
name: samm

services:
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: samm
      POSTGRES_USER: samm
      POSTGRES_PASSWORD: change-me-strong-random-string
      TZ: UTC
    volumes:
      - pgdata:/var/lib/postgresql/data

  samm-api:
    image: mhdhaidarah/samm:latest
    restart: unless-stopped
    command: ["api"]
    environment:
      # SAMM_ROLE picks the daemon. Docker reads `command:` above; MikroTik's
      # container feature drops that field on YAML import, so we also pass
      # the role as an env var — every parser preserves environment blocks.
      SAMM_ROLE: api
      POSTGRES_HOST: postgres
      POSTGRES_PORT: 5432
      POSTGRES_DB: samm
      POSTGRES_USER: samm
      POSTGRES_PASSWORD: change-me-strong-random-string
      TZ: UTC
      SAMM_API_HOST: 0.0.0.0
      SAMM_API_PORT: 8000
      SAMM_API_WORKERS: 2
    ports:
      - "8000:8000"
    volumes:
      - etcsamm:/etc/samm
      - sammvar:/opt/samm/var
      - sammlogs:/var/log/samm
      - sammlocales:/opt/samm/app/locales

  samm-radius:
    image: mhdhaidarah/samm:latest
    restart: unless-stopped
    command: ["radius"]
    environment:
      SAMM_ROLE: radius
      POSTGRES_HOST: postgres
      POSTGRES_PORT: 5432
      POSTGRES_DB: samm
      POSTGRES_USER: samm
      POSTGRES_PASSWORD: change-me-strong-random-string
      TZ: UTC
    volumes:
      - etcsamm:/etc/samm
      - sammvar:/opt/samm/var
      - sammlogs:/var/log/samm

  samm-worker:
    image: mhdhaidarah/samm:latest
    restart: unless-stopped
    command: ["worker"]
    environment:
      SAMM_ROLE: worker
      POSTGRES_HOST: postgres
      POSTGRES_PORT: 5432
      POSTGRES_DB: samm
      POSTGRES_USER: samm
      POSTGRES_PASSWORD: change-me-strong-random-string
      TZ: UTC
    volumes:
      - etcsamm:/etc/samm
      - sammvar:/opt/samm/var
      - sammlogs:/var/log/samm

  samm-notification:
    image: mhdhaidarah/samm:latest
    restart: unless-stopped
    command: ["notification"]
    environment:
      SAMM_ROLE: notification
      POSTGRES_HOST: postgres
      POSTGRES_PORT: 5432
      POSTGRES_DB: samm
      POSTGRES_USER: samm
      POSTGRES_PASSWORD: change-me-strong-random-string
      TZ: UTC
    volumes:
      - etcsamm:/etc/samm
      - sammvar:/opt/samm/var
      - sammlogs:/var/log/samm

  samm-telegram:
    image: mhdhaidarah/samm:latest
    restart: unless-stopped
    command: ["telegram"]
    environment:
      SAMM_ROLE: telegram
      POSTGRES_HOST: postgres
      POSTGRES_PORT: 5432
      POSTGRES_DB: samm
      POSTGRES_USER: samm
      POSTGRES_PASSWORD: change-me-strong-random-string
      TZ: UTC
    volumes:
      - etcsamm:/etc/samm
      - sammvar:/opt/samm/var
      - sammlogs:/var/log/samm

  freeradius:
    image: mhdhaidarah/samm:freeradius-latest
    restart: unless-stopped
    environment:
      POSTGRES_HOST: postgres
      POSTGRES_PASSWORD: change-me-strong-random-string
      TZ: UTC
    ports:
      - "1812:1812/udp"
      - "1813:1813/udp"

volumes:
  pgdata: {}
  etcsamm: {}
  sammvar: {}
  sammlogs: {}
  sammlocales: {}

Before pasting, replace every change-me-strong-random-string with the SAME strong random password (≥ 24 random characters) — it goes into Postgres on first start and every SAMM service uses it to connect. Generate one with a password manager or run pwgen 32 1 on any Linux box.

4. Verify and connect MikroTik to SAMM

Once all 7 containers are running, open the admin portal in a browser and sign in with these credentials:

Login URLhttp://<router-ip>:8000/admin · Usernameadmin · Passwordadmin

Change the admin password immediately. RADIUS auth + accounting are exposed on UDP 1812 + 1813 on the router itself, so the MikroTik RADIUS client can point at 127.0.0.1 with the shared secret you set in System → RADIUS.

Experimental in v1. RouterOS's container feature is leaner than Docker Compose — service-name DNS, dependency ordering (depends_on), and live restarts behave differently. If the stack misbehaves on your hardware, fall back to running Docker on a small Linux box (NUC, Pi 4, Linux VM) next to the MikroTik. The same compose file works there with full Compose semantics.

Non-interactive options

All prompts can be pre-answered with environment variables, so the installer can run unattended:

VariableEffect
DB_PASSUse this database password instead of an auto-generated one (first install only)
CF_TOKENInstall the Cloudflare Tunnel connector with this Zero Trust token
SAMM_HTTP_PORTForce the nginx listen port (skips the port-80 detection prompt)
SAMM_VERBOSE1 streams raw command output instead of the progress bar
NO_COLOR1 disables colored output
DB_PASS='strong_pw'   sudo bash /opt/samm/install.sh
CF_TOKEN='eyJ...'     sudo bash /opt/samm/install.sh
SAMM_HTTP_PORT=8080   sudo bash /opt/samm/install.sh

What the installer sets up

The installer runs as a live, colored progress display — a percentage bar and a per-phase checklist. Each phase's raw output is captured to /var/log/samm-install.log; on failure the last 30 lines are printed.

ComponentDetails
FreeRADIUS 3Configured with a PostgreSQL backend and dynamic NAS clients; validated with freeradius -CX
PostgreSQLDatabase, schema, and all SQL migrations applied — every migration file is idempotent
Python venvAll dependencies built from requirements.txt; translation catalogs compiled
nginxReverse proxy added additively — existing sites are never removed. Uses port 80 when free; otherwise prompts for an alternate port
5 servicessamm-api, samm-radius, samm-worker, samm-notification, samm-telegram — all enabled as systemd units
WireGuardPackages installed; configured later from System → VPN
cloudflaredBinary always installed; the tunnel token is optional at install or added later from System → Cloudflare Tunnel

All credentials — the database password and the session signing keys — are generated automatically on first install.

Interactive prompts

Any prompts happen up front, before installation begins:

  • Cloudflare token — paste a Zero Trust connector token to publish SAMM online with no open ports, or press Enter to skip and configure it later.
  • HTTP port — if port 80 is already in use, the installer leaves those sites untouched and asks for an alternate port (default 8080).

Install summary

When the installer finishes it prints a summary with the admin URL, the default login, the chosen HTTP port, the database credentials, and the config-file paths:

============================================================
  SAMM is installed and running.
  Admin portal  : http://localhost/admin/login
  Default login : admin / admin   <- CHANGE AFTER FIRST LOGIN
  Config files  : /etc/samm/samm.yaml  /etc/samm/api.env
============================================================

Upgrading

To upgrade, fetch the new source and re-run the installer:

git -C /opt/samm pull        # or unpack a newer release bundle
sudo bash /opt/samm/install.sh

The re-run re-syncs the source, upgrades the venv, re-applies all migrations, reloads the FreeRADIUS and nginx configs, and restarts every service. Your config files and the HTTP port chosen at first install are preserved.

Tip SAMM can also update itself — see Licensing & updates. Enable automatic updates, or apply them on demand, from System → License.
Air-gapped & remote DB SAMM ships only SAMM — FreeRADIUS, PostgreSQL, nginx and the rest are fetched at install time from upstream apt repos, so air-gapped installs must pre-stage those packages. For a remote PostgreSQL, set the DSN in /etc/samm/samm.yaml after install.

Getting started

First steps

Five short tasks take a fresh install to the point where subscribers can connect and be billed.

1 · First login

  1. Open http://<your-server>/admin/ (use the HTTP port from the install summary if it is not 80), or your Cloudflare tunnel URL.
  2. Sign in with admin / admin.
  3. Immediately change the password from System → Admins, or from the profile menu in the top bar.

2 · Add your first router

  1. Go to MikroTik → NAS and click Add Router.
  2. Enter the router's IP, a shortname, and a RADIUS shared secret. For MikroTik devices, optionally add API credentials for live device sync.
  3. On the MikroTik, add a RADIUS server pointing at the SAMM host (ports 1812/1813) with the same shared secret, and enable RADIUS for PPP / Hotspot.

No FreeRADIUS restart is needed — SAMM resolves NAS clients dynamically from the database. See Routers (NAS) for the full procedure, or let the setup wizard configure the MikroTik for you.

3 · Create a plan

A plan defines the speed, the limits, and the price you sell. Go to Users → Plans → New plan. Full field reference: Plans & limits.

4 · Add a subscriber

Go to Users → New customer, fill in the login credentials and pick a plan. The subscriber can connect immediately. For prepaid hotspot access, generate voucher cards instead.

5 · Activate your license

A fresh install runs unregistered at a minimum tier. Open System → License and activate to lift the limits — see Licensing & tiers.

Day-to-day rhythm Add routers → create plans → add subscribers or cards → watch the Dashboard → record payments under Accounting.

Subscribers & plans

Plans & limits

A plan is the service definition assigned to subscribers — it sets the speed, the limits, and the price. Create plans before adding users.

Create a plan

  1. Go to Users → Plans.
  2. Click New plan.
  3. Fill in the form and click Save plan.

Each limit is a toggle — enable only the ones you need. The same modal edits an existing plan (open the row's ⋮ menu → Edit).

Plan fields

FieldMeaning
NameUnique plan name, e.g. Home-50M
PriceCharged per billing period when invoicing is used
Download / Upload speede.g. 50M, 512K, 1G — enforced as the MikroTik rate limit
Limit: ExpirationThe subscription ends a fixed period after activation (days/months/hours/minutes)
Limit: QuotaA total data cap (combined, download-only, or upload-only) for the whole subscription
Limit: UptimeA cap on cumulative connected time — the sum of all session durations
Limit: Daily usageA data cap that resets every day at the configured daily-reset time
Unlimited windowQuick-add of one speed window — the full editor lives in the plan's Speed Windows page
IP poolOptional RADIUS Framed-Pool name for address assignment
Auto-renewStart a fresh period on expiry instead of switching plan or disconnecting

The four limits

Each limit is independent and optional. When several are set, SAMM checks them in a fixed order — expiration → quota → uptime → daily — and the first one exhausted decides the action.

LimitTracksOn exhaust
ExpirationCalendar time since activationSwitch to another plan, or disconnect
QuotaTotal bytes usedSwitch to another plan, or disconnect
UptimeCumulative session secondsSwitch to another plan, or disconnect
DailyBytes since the last daily resetThrottle (switch to a slower plan) until the next daily reset

For each limit you choose what happens on exhaust: pick a next plan to switch the subscriber onto, or leave it as — disconnect —. For the daily limit the next plan acts as a throttle — the subscriber reverts to the original plan at the next daily reset automatically.

Speed windows

A speed window overrides the plan's base speed for set hours — for example an unlimited-speed window after midnight. Click a plan row to open its Speed Windows editor, which adds day-of-week control and supports windows that cross midnight. When several windows match, the highest-speed one wins.

Note Throttled or limit-exhausted subscribers are excluded from speed windows — SAMM never lifts speed while a limit is in force.

Two notions of usage

SAMM keeps usage in two places, and never conflates them:

  • Resettable counters — the per-limit state. Zeroed by an admin reset and by the daily reset.
  • Billing counters — non-resettable lifetime totals. Never zeroed, so reports and invoices stay accurate.

Managing plans

The Plans list shows each plan's speed, subscriber count, active limits, and speed windows. From a row's ⋮ menu you can edit, open its speed windows, enable/disable it, jump to its subscribers, or delete it (only when it has no subscribers). Editing auto-renew offers to propagate the change to all current subscribers.

Subscribers & plans

Subscribers

A subscriber (customer / user) is a PPPoE or Hotspot account that authenticates against SAMM. Each subscriber is assigned exactly one plan.

Create a subscriber

  1. Go to Users and click New customer.
  2. Complete the form and save — the subscriber can connect immediately.
FieldMeaning
Username *The PPPoE / Hotspot login name — must be unique
Password *The login password (stored for PAP/CHAP RADIUS auth)
First / Last nameThe subscriber's name
Mobile / Email / AddressContact details — used for notifications and invoices
Plan *The service plan to assign
Expiration overrideOptional manual expiry date instead of the plan's computed one
Auto-renewRenew the plan period automatically on expiry

The subscriber list

The Users page lists every subscriber with an at-a-glance status dot, the assigned plan, and how much of each limit is left — daily usage with a progress bar, quota remaining, uptime remaining, and days left. Filter by status (All / Active / Suspended / Expired / Online) or search by username, name or mobile.

The plan-swap badge A single badge is the subscriber's plan. Two badges joined by an arrow mean the subscriber hit their daily limit and is temporarily parked on a throttle plan — they revert to the original at the next daily reset.

Managing a subscriber

Right-click a row — or use the ⋮ menu — for every per-subscriber action:

ActionWhat it does
View / EditOpen the detail page, or edit contact details, password and expiry
Enable / DisableSuspend the account — online subscribers are disconnected
Renew ExpirationAdd the plan's duration on top of any remaining time; generates an invoice if the plan has a price
Reset Uptime / Quota / DailyZero the chosen limit counter
UsageOpen usage graphs and session history
DeleteRemove the subscriber and all their history — active sessions are disconnected first
How actions take effect Resets, plan changes and renewals are queued to an audit log and applied by the samm-radius tick — typically within a few seconds. If the subscriber is online, SAMM also sends a live refresh. See CoA & live changes.

The Usage view

The Usage action opens a detailed traffic page for one subscriber, with a 7d / 14d / 30d / 90d period selector. It reports three headline figures — today's traffic (with the upload/download split and minutes online), this month's traffic, and the cumulative online time for the month. Below them is a daily traffic chart of upload against download, and a full session history table: the start and stop time, duration, bytes down and up, the NAS, and the terminate cause of every session.

Bulk operations

To change owner, expiration, status or auto-renew for many subscribers at once — or to delete many — use the Bulk Changes and Bulk Delete tools. To create subscribers in bulk from a spreadsheet, use Export / Import.

Subscribers & plans

Hotspot cards

For prepaid Hotspot access, generate a batch of voucher cards instead of individual subscribers. Each card is a username/password pair with its own speed and limits, generated by the thousand and printed for distribution.

Create a card group

  1. Go to Users → Hotspot Cards and click New group.
  2. Fill in the form below and click Create group — SAMM generates every card's credentials automatically.
SectionFields
IdentityUnique group name, description, optional username prefix, how many cards to generate (up to 10,000)
CredentialsUsername and password format (numbers / letters / alphanumeric) and length
Speed limitDownload and upload speed — 256k, 6M, 1G; 0 = unlimited
Limit TransferUnlimited, combined cap, or separate download/upload caps (MB / GB / TB)
Limit TimesUptime cap, expiration after first login, and a group "valid until" shelf date

The expiration counts from each card's first login, while valid until is a hard shelf date — cards cannot be used after it, whether or not they were ever activated.

Card statuses

StatusMeaning
UnusedGenerated but never logged in
ActiveIn use, within its limits
ExhaustedA limit (quota, uptime or expiration) has been reached
DisabledManually disabled

Printing & tracking

Open a group to see its cards, print them to a PDF for distribution (the print layout uses your ISP logo from Settings), and review per-card usage. Card traffic also appears in Reports under the Cards tab, and each group has its own accounting view.

Network & routers

Routers (NAS)

A NAS (Network Access Server) is a router that authenticates subscribers against SAMM over RADIUS. Every router that carries subscriber traffic needs a NAS record.

Add a router

  1. Go to MikroTik → NAS and click Add Router.
  2. Fill in the fields below and save.
FieldMeaning
NAS IP / hostnameThe router's address, as seen by the SAMM host
ShortnameA friendly label shown across the UI
Typemikrotik unlocks live device sync and config push; other types are RADIUS-only
SecretThe RADIUS shared secret — must match the router exactly, or authentication fails
CoA portUDP port SAMM sends Change-of-Authorization packets to (MikroTik default 3799)
API port / user / passwordMikroTik API credentials SAMM uses to read device info and push config
No restart needed SAMM resolves NAS clients dynamically from the database — adding or removing a router never requires a FreeRADIUS restart.

The NAS list

Every router shows in one table — ID, NAS IP / hostname, shortname, type, a masked secret (click the cell to reveal it), the CoA and API ports, and a live ping result with round-trip time. The search box filters by IP, shortname or description.

Each row's ⋮ menu carries the per-router actions — View Device and Refresh Info (MikroTik only), Edit, Push RADIUS config (MikroTik only), and Delete. Opening a mikrotik-type row jumps straight to its device page.

Discover neighbours

Click Discover neighbors to scan for MikroTik devices on the network and add them as NAS records without typing each address by hand.

Push RADIUS config to the router

For MikroTik NAS records, the row's ⋮ menu offers Push RADIUS config — SAMM configures the router for you over the API instead of you typing it by hand. You confirm the SAMM server IP (it must be reachable from the router) and the auth, accounting and CoA ports; SAMM then creates or replaces a RADIUS entry on the router:

SettingValue
CommentSAMM — the tag SAMM uses to find and update this entry later
Servicehotspot, ppp
Address / secretThe SAMM host, with the shared secret from this NAS record
Timeout3000 ms
CoA incomingAccepted, on the CoA port you confirmed

The dialog shows a result log when the push finishes.

Configure the MikroTik side

If you configure the router manually instead:

  • Add a RADIUS server pointing at the SAMM host, with the same shared secret, enabled for PPP / Hotspot.
  • Use auth port 1812, accounting port 1813.
  • Accept incoming CoA on port 3799.
  • Set the accounting Interim-Update interval to about 60 seconds — this is how often SAMM accumulates usage and evaluates limits.

Monitor-only devices

A router added as a monitor appears in the MikroTik inventory and is pinged and synced, but has no RADIUS role — it cannot authenticate subscribers. Use it to keep an eye on routers that aren't subscriber NASes.

Network & routers

MikroTik manager

When a router has API credentials, SAMM manages it directly over the MikroTik API — no WinBox, no SSH. The MikroTik section is a live inventory of every router, and each device opens a detail page with fifteen tabs that configure almost every part of RouterOS from your browser.

MikroTik Monitor

MikroTik → Monitor shows one card per router, laid out as a grid. Each card reports — refreshed by samm-worker and live-polled every 30 seconds — the reachability dot, RouterOS version, CPU load and core count, memory use, active session count, uptime, and the time of the last sample.

A card is tagged either NAS (a router that also authenticates subscribers over RADIUS) or monitor (a device added for monitoring only). Add MikroTik registers a new device; Refresh now forces an immediate poll. Monitor-only cards carry a right-click menu — Open, Edit, Refresh Info, Delete.

The device page — sixteen tabs

Open any device for its full management page. The tabs fall into four groups.

Monitoring

TabWhat it shows
OverviewDevice info, system info, and performance-history charts (CPU, memory, sessions over time)
InterfacesEvery interface with its live state, plus per-interface traffic history
WebsitesWebsites & apps seen on the router and a performance-history view of that traffic

Manager

The Manager → General tab is the housekeeping page for the device: Identity (the router name), Time (clock, timezone and NTP), and Tools (reboot, ping and other one-click router actions).

Network configuration

TabWhat you configure
BridgeCreate LAN bridges and choose which physical interfaces (ports) belong to each
VLANAdd and manage VLAN interfaces
IPThree sub-tabs — Static (static and dynamic addresses), DHCP client (pull an address from upstream), DHCP server (hand out addresses, with a live lease table)
DNSDNS servers and cache, plus a Websites & App filter — DNS-based content blocking
WiFi / CAPsMANWi-Fi interfaces with their configurations and security profiles; and the CAPsMAN controller — configurations, provisioning rules and remote CAPs
QoSApplication-aware download priority — drag the apps and sites seen by the Websites & App filter into eight priority slots, cap any app's speed, and push it to the router as a queue tree

Services & maintenance

TabWhat you configure
PPPoEPPPoE servers, PPP profiles, IP pools, and the RADIUS accounting interim-update interval
HotspotHotspot servers, hotspot profiles and user profiles, DHCP/IP pools, and the captive-portal login page
InternetWAN uplinks — SAMM-managed WANs and default routes, with any existing non-SAMM WANs shown read-only
FirewallFilter rules, a router-security analysis, connectivity & targets, security modules, and firewall backups
UpdateRouterOS updates — pick an update channel, check and apply, and review installed packages
WizardThe guided first-time setup, below

The PPPoE interim-update interval

On the PPPoE tab, Interim update sets how often the router sends RADIUS accounting Interim-Update packets to SAMM. SAMM uses those packets to accumulate byte and uptime counters and to evaluate the quota, daily and uptime limits — without them, limit enforcement and the live-session counters stall. The recommended value is 5m.

The Hotspot login page

From the Hotspot tab you manage the captive-portal login page: keep the MikroTik default pages, apply one of the built-in templates, or apply one of your saved designs. SAMM includes a visual design editor and a template gallery — customise a login page and push it straight to the router's hotspot.

Application-aware QoS

The QoS tab turns the apps and sites SAMM already sees on the router into a download-priority plan. Drag each app from the pool into one of eight priority slots — slot 1 is served first under contention, slot 8 last; apps left in the pool are not shaped. Optionally cap any app's download speed (for example 10M) and set a total download ceiling for priority to compete for. Auto-distribute by category arranges everything in one click — messaging and conferencing first, bulk downloads and speed-tests last.

When you push, SAMM compiles the slots into a MikroTik queue tree (tagged SAMM:qos, parent=global) with matching packet-mark firewall rules, highest priority first. It is built on the same Websites & App filter catalogue that powers monitoring, so only apps actually seen on the router appear — and removing SAMM QoS strips every SAMM:qos object back off the router, leaving your counters untouched.

The setup wizard

The Wizard tab collects everything in nine short steps and pushes the full configuration to the router in one batch at the end. Nothing is sent until you confirm on the final review step.

  1. Welcome & detect — SAMM probes the router and shows what is already configured, so you can skip those items in the push.
  2. Bridge interface — name the LAN bridge.
  3. Bridge ports — pick which physical interfaces join the bridge.
  4. DNS — set upstream resolvers (one-click presets for Google, Cloudflare, Quad9 and more), cache size, and optionally a DNS content filter.
  5. Internet — add one or more WAN uplinks (Static / DHCP / PPPoE).
  6. RADIUS to SAMM — point the router at your SAMM host for authentication, accounting and CoA.
  7. Services — choose whether the wizard creates a PPPoE server, a Hotspot server, or both.
  8. PPPoE / Hotspot details & Firewall — pools, profiles, lease times, plus the firewall & NAT rules.
  9. Review & push — see the exact list of commands that will be sent, then push them all to the router.
Per-user speed comes from RADIUS The wizard creates a single PPPoE / hotspot profile — it does not push per-tier profiles. Each subscriber's speed is delivered by SAMM in the RADIUS reply at login, so plan changes never need a router edit.

Network & routers

CoA & live changes

CoA (Change-of-Authorization) is how SAMM changes a subscriber's session while they are online — to lift or drop their speed, or to disconnect them — without waiting for them to reconnect.

How a change reaches a live subscriber

SAMM never pushes a router change straight from a button click. Every admin action follows one safe path:

Admin action Audit log samm-radius tick CoA outbox Router
  1. The action is recorded in an audit log as a queued command.
  2. The samm-radius service drains the queue on its next tick, applies the change, and — if the subscriber is online — enqueues a CoA.
  3. The CoA outbox is drained and the packet is sent to the router.

Time-driven events — expiry, speed-window edges, daily resets — feed the same outbox. The upper bound on latency is one samm-radius tick (30 s by default; lower it in Settings for tighter enforcement).

Hybrid CoA

SAMM sends a CoA-Update first to change the session in place. If the router rejects it after the configured retries, SAMM automatically falls back to a Disconnect-Request — the subscriber reconnects and picks up the new settings. This hybrid strategy works across MikroTik firmware versions.

The CoA Outbox page

Users → CoA Outbox is the live view of that queue. samm-radius is the only sender — the admin panel never pushes a CoA directly — and it drains the queue every tick. The page auto-refreshes every 30 seconds.

Six counters head the page — Pending, Sent, NACK (retrying), Done, Failed and Total. Filter the table by status, by action (update or disconnect), or search by username, NAS IP or reason.

StatusMeaning
pendingQueued, waiting for the next samm-radius tick
sentDispatched to the router, awaiting its reply
nackThe router rejected the CoA-Update — SAMM is retrying, then falls back to a disconnect
doneApplied successfully
failedGave up after the retry limit — hover the badge for the last error

Each row shows the user, router, action, attempt count, reason, and the created and sent times. Per-row actions let you Retry a failed or nack'd packet, Cancel one still in flight, or open Attributes to inspect the exact RADIUS attributes the packet carries. The sidebar badge counts pending rows; the Dashboard tracks 24-hour failures. A healthy system keeps this queue near-empty.

Daily operations

Dashboard & live sessions

The two screens under Overview are where you start every shift — the Dashboard for the health of the whole system, Live Sessions for exactly who is connected right now.

Dashboard

Overview → Dashboard is the operator home screen. A period selector at the top — Today, 7d, 14d, 30d, 90d — sets the window for the trend chart and the date-bounded figures.

The six KPI tiles

Each tile is a live counter and a shortcut — click it to jump straight to the filtered list behind the number.

TileShowsOpens
Online nowSubscribers with a live RADIUS session right nowUsers filtered to Online
Active subscribersActive accounts, with the total subscriber count beneathUsers filtered to Active
ExpiredSubscribers whose subscription lapsed with no next plan setUsers filtered to Expired
CoA queuePending Change-of-Authorization packets, plus the count that failed in the last 24 hThe CoA Outbox
RoutersTotal NAS records, plus the count currently unreachableThe MikroTik monitor
Unpaid invoicesInvoices still needing payment follow-upInvoices filtered to Unpaid

Users & live sessions chart

A daily-snapshot line chart plots three series across the selected period — active users, online sessions, and expired users — so growth and churn are visible at a glance.

Pipeline health

This panel is the heartbeat of the enforcement engine. On a healthy system the queues sit at or near zero — a number that stays high points to a stuck service or a router rejecting changes.

MetricWhat it means
samm-radius queuePending CoAs waiting for the next tick — should clear within seconds
Failed CoA (24h)Zero on a healthy system; a non-zero count means a router is rejecting CoAs
Audit log pendingQueued admin actions not yet applied by samm-radius
Sessions throttledSubscribers currently held at a reduced speed by a limit — expected, not an error
Sessions snapshotThe live session count — should track Online now
Active plansThe size of your plan catalogue
The enforcement path Admin actions are queued to samm.audit_log; the samm-radius tick drains them and emits CoAs into samm.coa_outbox. The full path is in CoA & live changes.

Recent-activity tables

Four tables under the chart give a rolling view of what just happened, each with a View all link to its full page:

  • Recent CoA outbox — action, user, status (done / pending / nack / failed), attempt count, reason, and time.
  • Recent admin actions — action, target, the actor who triggered it, whether it is applied yet, and time.
  • Recent subscribers — the newest accounts with their status and last authentication time.
  • Routers — every NAS with a reachable / unreachable / no-data health dot.

Live Sessions

Overview → Live Sessions lists every subscriber the routers currently report as online over RADIUS accounting. The page auto-refreshes every 30 seconds; a manual Refresh button sits in the header.

Filtering the list

  • Search — matches username, framed IP, or NAS IP, submitting as you type.
  • Router — narrow the list to the sessions on a single NAS.
  • Only throttled — show just the subscribers a limit is holding at a reduced speed.
  • Per page — 20, 50, 100 or 200 rows.

What each row shows

ColumnMeaning
UserUsername — links to the subscriber's detail page
Framed IPThe address the router assigned to this session
RouterThe NAS shortname and its IP address
PlanThe subscriber's current plan
Effective speedThe speed enforced on the router right now — the plan speed adjusted by any active speed window. A throttled badge means a limit is holding the subscriber at a reduced speed.
Down / UpLive byte counters for the session
OnlineHow long the session has been up
StartedWhen the session began

Disconnecting a session

The Disconnect button on a row enqueues a CoA-Disconnect for that exact session (reason admin_manual) after a confirmation prompt. The subscriber drops immediately; if their account is still active they are free to reconnect. Track the packet in the CoA Outbox.

Daily operations

Reports & analytics

Overview → Reports is the analytics view — subscriber trends, traffic over time, and the heaviest users and cards on your network.

Choosing the range

Every figure on the page is bound to a date range. Pick a preset — 7d, 14d, 30d, 90d — or type explicit start and end dates and click Apply. A loading overlay covers the page while a long-range query such as 90d runs.

Subscriber & session trends

A line chart with three series over the chosen range: Active subscribers, Online sessions, and Expired subscribers. Use it to spot growth, churn, and the busy hours of your network.

Daily traffic

A stacked bar chart of upload and download bytes per day. Hovering a day shows the upload and download figures plus a combined total in the tooltip footer.

Top 10 lists

Four tables surface your heaviest-traffic accounts, each ranked by volume in GB:

ListRanks
Top 10 download todayLargest download since the last daily reset
Top 10 upload todayLargest upload since the last daily reset
Top 10 download monthLargest download this calendar month
Top 10 upload monthLargest upload this calendar month

Traffic by entity

A paginated, searchable table of per-account traffic. Two tabs switch what it lists:

  • Users — each subscriber with their name, plan, today's upload/download in MB, and this month's upload/download in GB.
  • Cards — each hotspot card with its group, status, and the same today / month traffic split.

The search box filters the table as you type; the per-page selector takes 20 to 200 rows. Every row links through to that subscriber's or card's detail page.

Exporting Reports is an on-screen analytics view. For raw rows to crunch in a spreadsheet, use Tools → Export / Import to download users, plans or NAS as CSV / XLSX.

Daily operations

Accounting & billing

SAMM has a complete double-entry bookkeeping system built in — invoices, expenses, receipts, payments, resellers, fixed assets and full financial statements. There is no separate billing product to integrate, and no accountant needed to keep the books straight.

You never touch debits and credits Every action — recording a payment, adding an expense, selling a card group — posts a balanced journal entry to the ledger automatically. You work in plain terms (invoices, expenses, receipts); SAMM keeps the double-entry books behind the scenes and proves they balance in the Trial Balance.

The Accounting page is organised into ten tabs.

Overview

The financial snapshot. Four headline figures sit at the top:

FigureMeaning
Cash on handTotal balance across all cash & bank accounts
Money you're owedReceivables — unpaid customer and reseller invoices
Money you owePayables — unpaid expenses
Profit this monthIncome minus expenses for the current month

Below: a table of every cash & bank account with its balance, and an income vs expenses chart over the last 1, 2, 3, 6 or 12 months.

Invoices

An invoice is a bill you issue. Click New invoice and fill in:

FieldMeaning
CustomerType-ahead search for the account being billed
Revenue categoryWhich income account the sale posts to
Issue / Due dateBlank issue date = today; blank due date = the issue date
Tax rate %Defaults to the rate in Settings → Billing
Line itemsOne or more description / quantity / unit-price rows — subtotal, tax and total compute live

Invoices are also generated automatically when a subscriber's plan is renewed (from the user's Renew Expiration action or by auto-renew), provided the plan has a price. The list filters by status — unpaid, partial, due, paid — and searches by invoice number or customer. Open any invoice for its detail page and a printable PDF; subscribers can download their own copies from the customer portal and Telegram bot.

Expenses

An expense is money spent running the ISP. New expense records a category (the expense account), the vendor paid, the amount, the date incurred and an optional due date. Each expense has the same unpaid / partial / due / paid lifecycle as an invoice, a detail page, and a printable voucher PDF.

Receipts & Payments

These two tabs record cash actually moving — distinct from the invoice or expense that caused it.

  • Receipts — money in: cash received from a customer, a reseller, or other income, landing in one of your cash accounts. An invoice is the bill; the receipt is the money arriving against it.
  • Payments — money out: cash paid against an expense or to a reseller.

Recording a receipt or payment moves the related invoice or expense toward paid and posts the matching ledger entry.

Customers & Card sales

The Customers tab lists each customer's running balance — what they owe you. Card sales covers prepaid hotspot revenue: it tracks sold card groups and resellers. A reseller buys whole card groups from you on an invoice, then resells the individual cards to end users; their balance owed is what they still need to pay you.

Assets & Cash accounts

  • Assets — register fixed assets (routers, vehicles, equipment). SAMM tracks their value and depreciation over time.
  • Cash — manage your cash & bank accounts, and your capital accounts: owner's equity, where a contribution is money the owner puts into the business and a withdrawal is money taken out. Capital is not revenue and never appears in Profit & Loss.

Reports — the financial statements

The Reports tab is the accountant's view. Five statements, each date-ranged and exportable to PDF:

ReportAnswers
Profit & LossIncome vs expenses and net profit over a date range. Accrual basis — income counts when invoiced, expenses when incurred, not when cash moves.
Balance SheetAs of a date: what you own (assets) against what you owe (liabilities) plus equity. A balanced badge confirms the two sides match.
Cash FlowPer cash account — opening balance, money in, money out, closing balance over a range.
AgingOutstanding receivables and payables sorted into age buckets, so you can chase overdue invoices and stay ahead of bills.
AdvancedThe raw books: General Ledger (every line on one account with a running balance), Trial Balance (the balanced-books check), the Journal, and an activity log.
The balanced check In the Trial Balance every account's debit and credit columns must total equal — that is the proof the books are sound. If it is ever out of balance, it points to a posting error worth investigating.

Daily operations

Support tickets

SAMM has a built-in help desk. Subscribers raise tickets from the customer portal or the Telegram bot, an admin can open one on a subscriber's behalf, and your team works them all from Users → Support Tickets.

The ticket queue

The queue lists every ticket — number, customer, subject, priority, status, the opened and last-updated dates, and the message count. Filter it with:

  • Status chips — one per ticket status, each carrying a live count, so the workload is visible at a glance.
  • Priority — Normal, Moderate or Critical.
  • Active / Withdrawn — a customer can withdraw a ticket they no longer need; withdrawn tickets are dimmed and hidden by default.
  • Search — by ticket number, subject, or customer.

The sidebar badge counts open tickets so nothing is missed.

Opening a ticket

New ticket lets an admin raise a ticket for a chosen customer — pick the customer, then set a subject, priority and description. Subscribers also open their own from the customer portal or the Telegram bot.

Working a ticket

Open a ticket to read the full conversation thread. From there you can:

  • Reply to the customer — a public message the subscriber sees on their portal and through the Telegram bot.
  • Add an internal note — a staff-only message, hidden from the customer, for handover notes between your team.
  • Change the ticket's status and priority.

Right-click any row — or use its ⋮ button — for the same status, priority, reply and internal-note actions without leaving the queue.

Daily operations

Notification Center

SAMM keeps subscribers informed automatically — over email and Telegram — and lets you broadcast messages. The samm-notification service delivers everything through one throttled queue. The System → Notification Center page has six tabs.

Overview

The landing tab — live counts (queued, sending, sent today, failed, skipped, opted-out), the state of each delivery channel, and a feed of the most recent notifications.

Channels

Configure how messages leave SAMM. Email uses its own notification account, kept separate from the password-recovery SMTP in Settings. Telegram uses a bot token. Each subscriber, from the customer portal, picks which channels they want and can opt out entirely.

Messages

The message templates, one set per event. Edit the wording of any notification — renewal reminders, receipts, and the rest — so every message goes out in your own voice and language.

Rules & Timers

This tab governs when and how automatic notifications fire. For each event you control:

  • Whether the rule is on.
  • Ignore opt-out — when set, the message reaches every subscriber even if they opted out. Reserve it for important transactional messages.
  • Timing — for example, how many days before expiry a renewal reminder is sent.
  • Delivery & throttling — the worker drains the queue one batch per tick; the batch size and tick interval together pace how fast messages go out, so a large broadcast never floods your mail server.

The events SAMM can emit on its own include the renewal reminder (before a subscription expires), the expiry notice (when it lapses), the quota warning (as a data cap runs low), the payment receipt (when a payment is recorded), and plan renewed.

Broadcast

Send a one-off message — a maintenance window, a price change — to a chosen set of subscribers. The broadcast flows through the same throttled queue as automatic notifications.

Outbox

Every message SAMM has queued or sent, with its per-message delivery status, so you can confirm a notification reached the subscriber or see why it did not.

System

WireGuard VPN

SAMM can run a WireGuard VPN server on the SAMM host — typically for remote-admin access into the SAMM box and management access to the MikroTiks behind it. It is managed entirely from System → VPN; no shell needed.

Server tab

  1. Click Generate Keys to create the server keypair. The Server Public Key appears once generated — clients need it.
  2. Set the Listen Port (UDP, default 51820), the Server Tunnel Address (the CIDR on the wg0 interface, default 10.254.254.1/24), and the Client IP Range — the start and end addresses SAMM hands out to new peers automatically.
  3. Turn on Enable WireGuard VPN and click Save — SAMM brings the wg0 interface up. The toggle is locked until server keys exist.

Clients tab

Click Add Client, give the peer a name, and SAMM assigns it the next address from the client range. For each peer you can download its config file, scan a QR code with the WireGuard mobile app, or copy ready-made MikroTik RouterOS commands to bring a router onto the VPN. Peers can be toggled on/off or deleted; status colours show whether each is connected, stale, or never seen.

Regenerating keys is destructive Regenerate Keys changes the server keypair. Every already-deployed client config has the old server public key baked in and will stop connecting until you re-hand-out the updated config. The UI gates this behind a type-to-confirm dialog.

System

Cloudflare Tunnel

A Cloudflare Zero Trust tunnel publishes SAMM to the public internet without opening any firewall ports — useful when the SAMM host sits behind NAT. It is managed from System → Cloudflare Tunnel.

Service status

The page opens on a status card that reports the connector's state:

StateMeaning
RunningThe tunnel is active and forwarding traffic
StoppedConfigured but not currently running
Not configuredThe binary is present — paste a token to set it up
Not installedRe-run install.sh to install the cloudflared binary

It also shows the cloudflared version and whether the connector is set to auto-start at boot.

Configure the tunnel

  1. In the Cloudflare Zero Trust dashboard (one.dash.cloudflare.com), open Networks → Tunnels and Create a tunnel.
  2. Choose the Cloudflared connector, name the tunnel, and save. On the install step, copy only the token — the long string after --token.
  3. Paste it into SAMM and click Configure Tunnel. SAMM hands the token to cloudflared and starts the connector.
  4. Back in Cloudflare, add a Public hostname: your chosen address, type HTTP, URL localhost:80 (proxied by nginx — recommended) or localhost:8000 (direct to the API).

Within a few seconds the status badge turns green and SAMM is reachable on the public hostname. Once configured, one-click actions let you Start, Stop or Restart the connector, Replace Token to rotate it, or Remove tunnel (a type-REMOVE-to-confirm action).

No open ports, token never in the database The tunnel makes an outbound connection to Cloudflare's edge — no firewall port is ever opened on the server. The token is forwarded to cloudflared and stored under /etc/cloudflared/; SAMM never persists it in the database. TLS terminates at Cloudflare's edge, so SAMM itself runs plain HTTP on the loopback.

System

Settings

System → Settings holds the live, hot-reloadable tunables. The daemons re-read them on their next tick — no service restart is needed. Settings are organised into tabs.

General tunables

SettingDefaultControls
samm-radius interval30 sHow often time-driven events are evaluated and CoAs sent
samm-worker interval60 sRouter ping + MikroTik API sync cadence
Acct interim interval60 sThe accounting interval pushed to routers
Daily reset time00:00When daily usage counters roll over
Server timezoneUTCTimezone for speed windows and the daily reset
CoA default port3799Default UDP port for CoA packets
CoA retry max3Retries before the Disconnect-Request fallback

Lower the samm-radius interval for tighter enforcement; raise it to reduce load.

ISP tab

Set your ISP identity and upload an ISP logo. The logo is resized automatically and appears on printed hotspot cards and invoice PDFs.

Email tab

Configure the SMTP server used for password-recovery codes sent to admins and customers (host, port, SSL/STARTTLS, username, from-address, password). Click Test connection to verify the credentials without sending mail.

Two email accounts The Email tab here is only for OTP / password recovery. The account used for customer notifications is configured separately in the Notification Center.

System

Admins & roles

System → Admins manages who can sign in to the admin portal and what each person can do. It has two tabs: Admins and Roles.

Admin accounts

Create an admin with a username, password, optional email, and a role. From a row's ⋮ menu you can edit the role or password, disable the account, or delete it. Only a superadmin can manage other admins.

Roles & permissions

A role grants per-area access. The built-in superadmin role always has full access and cannot be changed. Create custom roles for limited access — a new role starts with no access until you set its permissions.

For each area of SAMM (subscribers, plans, NAS, accounting, tools, settings, and so on) a role is set to one of three levels:

LevelMeaning
Not allowedThe area is hidden from the sidebar entirely
ViewRead-only access
EditFull access — create, change, delete

Data-visibility scope

Each role also has a scope. See all customers & cards means the role sees every record; with it unticked, its admins see only the subscribers and cards they themselves created — ideal for resellers or branch staff.

License is always reachable The System → License page is intentionally exempt from the permission matrix — it is the recovery path out of a lockdown and must never be hidden from any admin.

System

Tools

The Tools section bundles bulk and maintenance utilities.

Backup & Restore

Create a full database snapshot before any major change. A backup is a gzipped pg_dump archive stored on the server, each with a SAMM header.

  • Create backup — optionally add a note; tick Skip usage & history for a smaller, faster dump that omits bulky log tables.
  • Download a backup to your PC, or upload a previous SAMM backup back to the server.
  • Restore overwrites the current database — gated by a type-RESTORE-to-confirm dialog.

History Cleaner

Permanently delete old log and history rows to reclaim database space. Pick a retention preset and confirm. The cleaner trims closed RADIUS sessions, post-auth records, daily-usage rollups, router/interface history, limitation logs, applied audit entries, and finished CoA rows. It never touches live sessions, queued commands, pending CoAs, or the non-resettable lifetime usage totals.

Take a backup first History Cleaner deletes permanently. Run a backup before cleaning if you might want the data later.

Export / Import

Bulk export and import for Users, Plans and NAS as .csv or .xlsx. Download a template (the right columns plus a sample row) or a snapshot of current data, fill it in, and upload it back. Every row is validated and shown on a preview screen — duplicates and invalid rows are surfaced, and you choose whether to skip duplicates or update them in place — before anything is written.

Bulk Changes

Apply one change — owner, expiration date, status, or auto-renew — to every subscriber matching a filter, in a single run. Pick the change, build the filter (status / plan / owner / search), review the matching list, and confirm.

Bulk Delete

Permanently delete many subscribers or hotspot cards at once, selected by filter. Deleting a subscriber also removes their usage history, sessions, RADIUS accounting and invoices, and disconnects any live session. Gated by a type-DELETE-to-confirm dialog.

System

Languages & themes

Languages

The admin and customer portals are fully translatable. Six languages ship built in: English, Arabic (right-to-left), Turkish, French, Spanish and German. Each user picks their language from the top bar or their profile; the choice is remembered per account.

The translation editor

A superadmin can edit translations live from System → Translations — no restart, no file editing. The editor also creates entirely new languages and imports/exports translation workbooks as .xlsx, so you can localise SAMM into any language you serve.

Themes

SAMM ships 11 visual themes, light and dark. Each user picks a theme from the top bar; the preview updates instantly and is saved per account. IT terminology is never translated, so technical screens stay precise in every language.

System

Audit log

System → Audit Log is the record of admin actions — and the command queue that carries them out. When you reset a counter, change a plan, or renew a subscriber, SAMM writes the action here rather than touching a live router directly.

Each entry shows the action, its target, the admin who triggered it, when it happened, and whether it has been applied yet. The samm-radius service drains pending entries on its next tick and, where needed, emits a CoA to refresh a live session. The sidebar badge counts entries still pending; the Dashboard's pipeline-health panel tracks the backlog.

Why a queue Routing every admin action through the audit log means changes are applied by exactly one process in a predictable order — there is never a race between the web portal and a router.

Licensing

Licensing & tiers

Each SAMM installation is licensed per device — the plan lives on that install, so you can run several SAMM servers, each on its own tier. The tier sets three numeric caps.

TierAAA usersHotspot cardsNAS / routers
Unregistered252001
Free1005002
Pro2,0005,0005
Pro Maxunlimitedunlimitedunlimited

A fresh install runs unregistered at the minimum floor. Every feature is available at every tier — the tier only sets the caps. Creating a subscriber, card or NAS past the cap is blocked until you upgrade; no data is ever lost.

Activate & upgrade

  1. Open System → License.
  2. Activate by signing in with your SecuryTik account — or use Link this device, which shows a code you approve on samm.securytik.com without typing your password on the server. The device activates on Free.
  3. To go higher, request Pro or Pro Max from the same page — a SecuryTik admin reviews and approves it.

The License page also re-checks the license on demand and shows your current usage against each cap. Unlink device drops the install back to the unregistered tier without deleting any data.

If a paid license lapses

SAMM never deletes data. A lapsed license steps down gracefully:

StageWhat happens
WarningA reminder banner; everything keeps running
GraceA short window to reactivate; subscribers stay online
Soft lockdownBackground services stop; RADIUS keeps authenticating for about 7 days
Hard lockdownServices stop except the reactivation page

Reactivating at any stage restarts every service automatically — all subscriber data and history are intact.

Automatic updates

Auto-update is independent of licensing — every tier updates, and a lapsed license never blocks it. SAMM checks for a new signed release daily. From System → License you can switch between notify (the default — a banner with an Apply now button) and auto (apply unattended). Each update is verified, backed up, and applied in place. You can also re-run the installer at any time — it upgrades idempotently.

For your subscribers

Customer portal & bot

SAMM gives every subscriber two self-service surfaces — a web portal and a Telegram bot — so they can check usage and pay without contacting you.

The customer portal

Subscribers sign in at the SAMM site root (/) with their SAMM username and password. The portal has:

PageWhat the subscriber sees
OverviewAccount status, plan, expiry, today's and this month's usage, any outstanding invoice
Usage & sessionsTotal downloaded/uploaded, uptime budget, and full session history
My plansThe current plan plus the catalogue of available plans
My invoicesBilling history with one-click PDF download
Support ticketsOpen and follow support tickets
ProfileEdit contact details, change password, set language & theme, manage notifications

From Profile, a subscriber connects their Telegram account, orders their preferred notification channels, or opts out of notifications entirely. If they forget their password, an OTP code is emailed to them (this needs the Email tab configured).

The Telegram bot

The samm-telegram service runs an interactive self-service bot. A subscriber sends /start, verifies once with their SAMM username and password (the bot deletes the password message immediately), and can then, entirely from chat:

  • Check their plan, quota, usage and expiry date
  • View and download invoices as PDF
  • Update their profile and change their password
  • Open and follow support tickets

The bot also delivers the automatic notifications — renewal reminders, expiry notices, quota warnings and receipts — to subscribers who connected Telegram.

Reference

Operating SAMM

Almost everything is done from the admin portal. This page is the shell reference for the rare times you need it.

Service management

# Restart all SAMM services
systemctl restart samm-api samm-radius samm-worker samm-notification samm-telegram

# Live logs for one service
journalctl -u samm-api    -f
journalctl -u samm-radius -f

# Validate the FreeRADIUS config after any change
freeradius -CX

Admin CLI

For quick subscriber operations from the shell. Each command is queued to the audit log and applied on the next samm-radius tick — exactly like the UI actions.

CLI="sudo -u samm /opt/samm/venv/bin/python -m samm_radius.cli"

$CLI reset-quota      alice          # reset a limit counter
$CLI reset-daily      alice
$CLI reset-uptime     alice
$CLI reset-expiration alice
$CLI change-plan      alice home-50M # switch a subscriber's plan

Configuration files

FileHolds
/etc/samm/samm.yamlThe database DSN, connection-pool sizes, log level
/etc/samm/api.envPortal session secrets and the password-recovery SMTP settings
/etc/samm/secret.keyThe encryption key for stored router API passwords

These files are preserved across upgrades and never overwritten by a re-run of the installer. Runtime tunables (loop cadences, daily-reset time, CoA ports) live in Settings instead, and apply with no restart.

Updating SAMM

Either let SAMM update itself from System → License, or re-run the installer — see Installation → Upgrading. Both paths re-apply migrations and restart services; your config and data are untouched.

Backup & recovery

Use Tools → Backup & Restore for a full database snapshot before any major change. To rebuild on a fresh host, install SAMM and then restore the backup.

Reference

FAQ & troubleshooting

What operating systems does SAMM support?

Ubuntu 22.04 LTS, Ubuntu 24.04 LTS, and Debian 12. Server-grade Linux only — desktop variants aren't supported. The installer expects systemd, a fresh PostgreSQL install (one is set up for you), and root access.

Do I need an internet connection to run SAMM?

No. SAMM runs entirely on your own server and authenticates subscribers locally over RADIUS. The only outbound traffic is a periodic licence heartbeat to the SecuryTik licence server so your plan stays validated.

Can I run SAMM in the cloud, or does it need to be on-prem?

Either works. Most operators run on-prem next to their core routers; some run on a small cloud VM with a Cloudflare Zero Trust tunnel back. The only requirement is that the MikroTik routers can reach the SAMM server on the RADIUS ports (1812/1813 UDP) and that SAMM can reach the routers over the MikroTik API.

Do I have to restart FreeRADIUS when I add or remove a router?

No. SAMM resolves NAS clients dynamically from the database, so adding, editing or removing a router in MikroTik → NAS takes effect with no restart.

How fast does a plan change or counter reset take effect?

Admin actions are queued and applied by the samm-radius service on its next tick — within 30 seconds by default. If the subscriber is online, SAMM also sends a live CoA to refresh the session. Lower the samm-radius interval in System → Settings for tighter timing.

What happens to my data if a paid licence lapses?

Nothing is ever deleted. A lapsed licence steps down through warning, grace, a soft lockdown (RADIUS keeps authenticating for about a week) and finally a hard lockdown. Reactivating at any stage restarts every service with all data intact.

Is SAMM free? What does Pro add?

The Free tier is free forever and includes every feature. Pro and Pro Max don't unlock features — they raise the caps on AAA users, hotspot cards and routers. See Licensing & tiers.

A subscriber can't authenticate — where do I start?

Check that the router's RADIUS shared secret matches the NAS record exactly, that the router is enabled for PPP / Hotspot RADIUS, and that the subscriber's account is Active and not expired. Watch journalctl -u samm-api -f and the FreeRADIUS log, and confirm the router can reach the SAMM host on UDP 1812/1813.

Need more help?

Email [email protected] to report a bug or request a feature.