Skip to content

Roles and permissions

How access is granted in Sondar — the three-layer model (functions, roles, operations), how to create a role and assign it, and how the repo-level, time-level and APM-level limits work. Everything here was read from the shipped type definitions (@sondar/app-sdk apis/permission, apis/permission/role, apis/permission/user), not from a document.


Access is decided by roles, which a user holds. A role bundles function permissions — a function (EFunc, ~150 ids) names a feature surface, and an operation (EFuncOperation) says what the role may do with objects of that function. On top of that, a role carries limits that shrink what the functions already grant: which indexes it may read, which time window a search may cover, which APM services it may see, and when the role expires. A permission can arrive three ways — set directly (custom), taken from an inherited role (inherit), or granted by a repo match (match) — and the UI shows which.

There are built-in roles and custom roles. Seven are built-in, seeded when the instance initializes:

RolePurpose
adminThe root user’s role. Holds the special _admin function, which grants every operation.
general_userThe default role for a new account.
data_managerData administration.
analystData analysis.
monitorMonitoring Console access.
alarm_managerAlert administration.
auditorReads, verifies and exports the audit log, and nothing else — no data, no settings. Assigning it needs Pro; removing it never does, and an assignment made under Pro keeps working after Pro ends.

Custom roles are whatever you define.

Built-in roles cannot be edited or deleted — the Roles page renders those actions grayed out, and the editor refuses a built-in even if reached directly. To vary permissions, copy the closest built-in into a custom role.


A function is a string id naming one feature surface. EFunc holds the full list (in @sondar/app-sdk/src/apis/permission/role/model.ts); grouped, the shipping set is:

groupfunctions
Search & knowledgesearch, repo (indexes), sourcetype, extraction, spl_macro (macros), dataset, report, lookup_file, lookup_rule, fieldalias, dashboard, auto_report, search_export_task, dashboard_export, spl_job_manager (search jobs), search_action
Alertsalert_event_view, alert_event_own, alert_event_config, alert_rules, aggregation_rules, alert_templates, alert_prototype, alert_shield, alert_notices, alert_notice_upgrade, alert_level, alert_user_group, alert_notice_user
Collectionupload, dc_collector_config_client (client collection tasks), dc_collector_config_server (server-side collection), dc_agent (machines), dc_tag, dc_agent_upgrade_task, dc_package, dc_traffic_stats, dc_resource_mon, dc_overview, dc_collect_type, dc_transformer_type (parse templates), dialtesting, monitor_ftp / monitor_sftp / monitor_http / monitor_tcp / monitor_udp
Metrics & objectsmetric, metric_view, metric_gen_rule, metric_downsampling_rule, target, monitoring_coverage, target_rule, target_type, target_layer, target_relation, target_relation_merge_rule, target_clean_rule, biz_system, topology, client, target_collect_config, target_alert_config
APMapm_service, apm_trace, apm_exception, apm_database, apm_mq, apm_overview, apm_config, apm_monitor, apm_external_service, apm_profiling
Data managementdata_masking, view_unmasked_data, repo_logcluster_target (log-pattern targets), backup_destination, backup_snapshot_task, backup_snapshot, backup_snapshot_monitor, backup_file_archive, backup_file_archive_task, backup_file_archive_monitor, backup_history_file_archive_task, backup_history_file_archive_monitor, backup_restore
External datadb_connect, db_query, db_driver, lookup_file, lookup_rule
Notificationssmtp_informer (email), dingding_informer, wechat_informer
Administration_admin (everything), role, user, password_setting, token_all, token_own, collect_token, oauth_client, system_setting, setting_ui, setting_domain, system_group, license, cluster_deploy, global_settings, encrypt_key, encrypt_content, monitor_internal_api

view_unmasked_data is the one function that removes a restriction rather than granting a surface. A user sees unmasked values if any role they hold holds it, so it composes by OR across roles like every other function — which means adding it to one role is enough to undo masking for that user everywhere. The role editor grants it as a single Full Access box. See data-masking.md for how it interacts with the masking rules.

The id is usually the surface name — repo gates indexes, search gates search, alert_rules gates alert rules — but a few are not obvious (dc_* = data collection, dialtesting = dial testing, target = the object list, client = external connections). The enum is the authority.

2. Operations — what a function lets you do

Section titled “2. Operations — what a function lets you do”

Each function permission carries an operation, from EFuncOperation:

operationmeaning
listread / see the objects — the role editor labels this “View/Access”, because it gates reaching a feature at all (its page route, and for data masking the report endpoint), not merely listing rows
create / edit / deletethe CRUD actions
alleverything on the objects
shareshare objects with other roles
configconfigure (e.g. a collector’s settings)
downloaddownload (search results, packages)
quick_diagnoserun the one-click agent diagnosis
emergency_sleep_awakethe fleet-wide emergency sleep / wake
admin_all_objectsadminister every object regardless of owner
reassign_knowledge_objectsreassign knowledge objects between owners

The front-end turns these into a per-function permission map — readable, editable, creatable, deletable, configable, shareable, allable, downloadable, … — which is what a page checks to decide whether to show a button. A permission check can be a tree too: “this route needs token_own or token_all, each with the list operation.”

A role (IRole) is:

fieldwhat it holds
name, descidentity; the name is the key
typebuiltin or custom
inheritanceroles this role inherits from (their function permissions and repo limits merge in)
funcPermsthe function permissions — each `{ function, operation, permType: custom
repoLimitswhich indexes the role may touch, each { repo, repoAuth, groups, permType }
dataMaskper-index data-masking on/off
searchLimit, repoSearchLimitsper-index search limits
searchTimeLimita time-window restriction on search (below)
apmServiceLimits, apmBizSystemLimitswhich APM services / service namespaces are visible
expireConfigexpiry — relative (minute/hour/day/none) or an absolute time
groupsthe resource groups the role is scoped to

repoAuth is the read/write level on an index: READABLE, WRITABLE or NONE. Two special markers name whole classes instead of one index — _all_internal (every built-in index) and _all_non_internal (every other) — so a role can be “read everything” without enumerating indexes.

Search limits on stored and search-time fields

Section titled “Search limits on stored and search-time fields”

A per-index search limit (repoSearchLimits, e.g. service="checkout-api") restricts which events of that index the role sees. A limit on a stored field — host, sourcetype, source, or a field from an accelerated (ingest-time) extraction — is applied in the index query. A limit on a field that is only extracted at search time, such as a key of a JSON event, is evaluated per event as the index is read, on the extracted value and before any masking. Either way the role cannot search its way outside the limit. A limit naming a field that nothing stores or extracts matches no events.

A role can cap how far back a search may reach, per index: a rule lists the indexes and a duration + timeUnit window. The three shapes that exist in the model are the parent role’s limit (inherited), the role’s own, and the result — the effective limit after inheritance — which is what actually applies.


A user (IUser) carries:

  • identity — username, nickname, phone, countryCode;
  • access — roles (the role names), groups (resource groups), perms (the resolved permission strings), userType (root / normal / notsondaruser);
  • lifecycle — status (normal, frozen, or p_frozen for permanently banned), loginLimit (login permitted), expireDays;
  • notification — noticeTypes and the mail / WeChat / DingTalk contact details the notice system resolves to.

Users are assigned roles (and unassigned) through the role’s assign action (/auth/role/assign), which moves a list of usernames into or out of a list of roles at once.


The Access Control surface holds the machine-facing credentials, each gated by its own function:

itemfunctionwhat it is
Collect tokenscollect_tokenthe token that authenticates data going in — agent uploads, OTLP and HEC senders. It does not authorize the JSON API, which is session-based (see the API reference). Created under Access Control → Collect Tokens
API tokenstoken_own / token_allscoped API tokens — token_own for your own, token_all to administer everyone’s. A token never carries more authority than the person who creates it: a role or permission the creator does not hold is refused, and so is a token for an account that holds one
OAuth clientoauth_clientOAuth2 client registration. The client secret is shown once, when the client is created or its secret rotated; the list and the client’s details never return it
Encrypt key / contentencrypt_key / encrypt_contentthe encryption-key and encrypted-content settings

The rest of Access Control is the account-security settings:

  • Password policy (password_setting) — the password rules and change settings.
  • Login lock — lock an account after repeated failures.
  • IP access control — an allow/deny list of source addresses.
  • Directory and SSO — LDAP, CAS, OpenID Connect and SAML 2.0 sign-in, and SCIM provisioning — see Single sign-on and provisioning.

surfacenavigationroutefunction
UsersUsers & Authentication → User & Role → User/permission/useruser
RolesUsers & Authentication → User & Role → Role/permission/rolerole
Access ControlUsers & Authentication → Access Control/usercontrol (password), /tokens, /collectTokens, /encrypt, /encryptContent, /oauthClientpassword_setting, token_own/token_all, collect_token, encrypt_key, encrypt_content, oauth_client

The “Users & Authentication” group itself appears only to someone holding one of its functions; the User & Role entry needs user or role, the Access Control entry needs any one of its six functions.


At the end of the chain, the front-end resolves the current user’s roles into a per-function operation set and checks it against the action’s requirement. The requirements are declared in two shapes: a single function (or a list of them), or a tree of And/Or over functions and operations. The alerts page lists its own function ids; every other surface uses the same EFunc / EFuncOperation model here, so a role granting search + list is what lets a user open the Search page, and repo + create is what shows the “new index” button.

Object-level access is per-object, on top of the function. A knowledge object (a dashboard, a dataset, a lookup table) carries its own operations and an owner, and an object’s scope (private / app / global) decides who can see it at all. That is why some actions on an object are restricted to its owner or an administrator even when the role has the function — the object’s own operation list is the finer gate.