mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
doc: update user guide with more on nacm and user privileges
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
+644
@@ -0,0 +1,644 @@
|
||||
# Network Access Control Model (NACM)
|
||||
|
||||
NETCONF Access Control Model ([RFC 8341][1]) provides fine-grained access
|
||||
control for YANG data models. NACM controls who can read, write, and
|
||||
execute operations on specific parts of the configuration and operational
|
||||
state.
|
||||
|
||||
This document provides technical details about how NACM works, how rules
|
||||
are evaluated, and best practices for creating custom access control
|
||||
policies.
|
||||
|
||||
> [!TIP]
|
||||
> For a practical introduction to user management and the built-in user
|
||||
> levels (admin, operator, guest), see the [Multiple Users][2] section
|
||||
> in the System Configuration guide.
|
||||
|
||||
|
||||
## TL;DR - The Factory Defaults Work
|
||||
|
||||
**You don't need to understand NACM to use the system securely.**
|
||||
|
||||
The factory configuration implements a "permit by default, deny sensitive
|
||||
items" policy that provides:
|
||||
|
||||
- **Immediate usability** - Operators can configure the entire system
|
||||
without custom NACM rules
|
||||
- **Automatic security** - Passwords, cryptographic keys, and dangerous
|
||||
operations are protected out-of-the-box
|
||||
- **Future-proof design** - New features work immediately without NACM
|
||||
updates
|
||||
|
||||
The three built-in user levels (admin, operator, guest) cover most use
|
||||
cases. Only read on if you need to create custom access control policies.
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
NACM provides three types of access control:
|
||||
|
||||
- **Data node access** - Control read/write access to configuration and state
|
||||
- **Operation access** - Control execution of RPCs (remote procedure calls)
|
||||
- **Notification access** - Control subscription to event notifications (not covered here)
|
||||
|
||||
Access is controlled through:
|
||||
|
||||
1. **Global defaults** - Default permissions for read/write/exec
|
||||
2. **YANG-level annotations** - Security markers in YANG modules (see below)
|
||||
3. **NACM rules** - Explicit permit/deny rules organized in rule-lists
|
||||
|
||||
|
||||
## Rule Evaluation
|
||||
|
||||
NACM rules are evaluated in a specific order:
|
||||
|
||||
1. **Rule-lists are processed sequentially** in the order they appear in the configuration
|
||||
2. **Within each rule-list**, rules are evaluated sequentially
|
||||
3. **First matching rule wins** - no further rules are evaluated
|
||||
4. **If no rule matches**, global defaults apply (read-default, write-default, exec-default)
|
||||
5. **YANG annotations override everything** - `nacm:default-deny-all` in a YANG module requires an explicit permit rule regardless of global defaults
|
||||
|
||||
### Example Rule Evaluation
|
||||
|
||||
Given this configuration:
|
||||
|
||||
```json
|
||||
{
|
||||
"read-default": "permit",
|
||||
"write-default": "permit",
|
||||
"rule-list": [
|
||||
{
|
||||
"name": "operator-acl",
|
||||
"group": ["operator"],
|
||||
"rule": [
|
||||
{
|
||||
"name": "permit-system-rpcs",
|
||||
"module-name": "ietf-system",
|
||||
"access-operations": "exec",
|
||||
"action": "permit"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "default-deny-all",
|
||||
"group": ["*"],
|
||||
"rule": [
|
||||
{
|
||||
"name": "deny-passwords",
|
||||
"path": "/ietf-system:system/authentication/user/password",
|
||||
"access-operations": "*",
|
||||
"action": "deny"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
When operator user "jacky" tries to:
|
||||
|
||||
- **Read password**: Matches "deny-passwords" → **DENIED**
|
||||
- **Write interface config**: No match, uses write-default → **PERMITTED** (write-default=permit)
|
||||
- **Write hostname**: No match, uses write-default → **PERMITTED** (write-default=permit)
|
||||
- **Reboot system**: Matches "permit-system-rpcs" → **PERMITTED** (overrides `nacm:default-deny-all`)
|
||||
|
||||
## Global Defaults
|
||||
|
||||
NACM has three global defaults that apply when no rule matches:
|
||||
|
||||
```json
|
||||
{
|
||||
"read-default": "permit",
|
||||
"write-default": "permit",
|
||||
"exec-default": "permit"
|
||||
}
|
||||
```
|
||||
|
||||
**Factory configuration defaults:**
|
||||
|
||||
- `read-default: "permit"` - Users can read configuration and state by default
|
||||
- `write-default: "permit"` - Users can modify configuration by default
|
||||
- `exec-default: "permit"` - Users can execute RPCs by default
|
||||
|
||||
This permit-by-default approach, combined with targeted denials for
|
||||
sensitive items (passwords, cryptographic keys), provides a balance
|
||||
between usability and security. It also makes the system "future proof" -
|
||||
when new YANG modules are added, operators can immediately configure them
|
||||
without updating NACM rules.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> YANG modules with `nacm:default-deny-all` or `nacm:default-deny-write`
|
||||
> annotations override these global defaults. You must create explicit
|
||||
> permit rules for those operations.
|
||||
|
||||
## Module-Name vs Path
|
||||
|
||||
NACM rules can match operations using either `module-name` or `path`.
|
||||
The following sub-sections provide detailed information and examples of
|
||||
both.
|
||||
|
||||
### Module-Name Matching
|
||||
|
||||
Matches all nodes **defined** in a specific YANG module:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "permit-keystore",
|
||||
"module-name": "ietf-keystore",
|
||||
"access-operations": "*",
|
||||
"action": "permit"
|
||||
}
|
||||
```
|
||||
|
||||
This permits all operations on data **defined** in ietf-keystore, but does
|
||||
NOT cover augments from other modules.
|
||||
|
||||
**Example:** The `/interfaces/interface/ipv4/address` path:
|
||||
|
||||
- Interface is defined in `ietf-interfaces`
|
||||
- IPv4 config is defined in `ietf-ip` (augments ietf-interfaces)
|
||||
- A rule with `module-name: "ietf-interfaces"` does NOT cover ipv4/address
|
||||
|
||||
### Path Matching
|
||||
|
||||
Matches a specific data tree path and **all nodes under it**, including
|
||||
augments from other modules:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "permit-network-config",
|
||||
"path": "/ietf-interfaces:interfaces/interface",
|
||||
"access-operations": "*",
|
||||
"action": "permit"
|
||||
}
|
||||
```
|
||||
|
||||
This permits operations on `/interfaces/interface` **and all child nodes**,
|
||||
including augments like:
|
||||
|
||||
- `/interfaces/interface/ipv4` (from ietf-ip)
|
||||
- `/interfaces/interface/ipv6` (from ietf-ip)
|
||||
- `/interfaces/interface/bridge-port` (from infix-interfaces)
|
||||
|
||||
**Path syntax:**
|
||||
|
||||
- When used **with** module-name: Path is module-relative (no prefix)
|
||||
|
||||
```json
|
||||
"module-name": "ietf-system",
|
||||
"path": "/system/authentication/user/password"
|
||||
```
|
||||
|
||||
- When used **without** module-name: Path must include module prefix
|
||||
|
||||
```json
|
||||
"path": "/ietf-system:system/authentication/user/password"
|
||||
```
|
||||
|
||||
> [!TIP] Use path-based rules
|
||||
> When you want to permit/deny access to a configuration subtree
|
||||
> including all augments, e.g., all IP settings below
|
||||
> `/ietf-interfaces:interfaces/`. This is more flexible and requires
|
||||
> less maintenance as new features are added.
|
||||
|
||||
## YANG-Level Annotations
|
||||
|
||||
Many YANG modules include NACM annotations that provide baseline security:
|
||||
|
||||
### nacm:default-deny-all
|
||||
|
||||
Requires an explicit permit rule, regardless of global defaults:
|
||||
|
||||
```yang
|
||||
rpc system-restart {
|
||||
nacm:default-deny-all;
|
||||
description "Restart the system";
|
||||
}
|
||||
```
|
||||
|
||||
Even with `exec-default: "permit"`, users need an explicit permit rule to
|
||||
execute system-restart.
|
||||
|
||||
### nacm:default-deny-write
|
||||
|
||||
Write operations require an explicit permit rule:
|
||||
|
||||
```yang
|
||||
container authentication {
|
||||
nacm:default-deny-write;
|
||||
description "User authentication configuration";
|
||||
}
|
||||
```
|
||||
|
||||
Even with `write-default: "permit"`, users need an explicit permit rule to
|
||||
modify authentication settings.
|
||||
|
||||
### Protected Operations
|
||||
|
||||
The following are protected by YANG annotations and require explicit permits:
|
||||
|
||||
**RPC Operations:**
|
||||
|
||||
- `ietf-system:system-restart` ([ietf-system][3])
|
||||
- `ietf-system:system-shutdown` ([ietf-system][3])
|
||||
- `ietf-system:set-current-datetime` ([ietf-system][3])
|
||||
- `infix-factory-default:factory-default`
|
||||
- `ietf-factory-default:factory-reset` ([RFC 8808][4])
|
||||
- `infix-system-software:install-bundle`
|
||||
- `infix-system-software:set-boot-order`
|
||||
|
||||
**Data Containers:**
|
||||
|
||||
- `/system/authentication` (`nacm:default-deny-write`, [ietf-system][3])
|
||||
- `/nacm` (`nacm:default-deny-all`, [RFC 8341][1])
|
||||
- Routing protocol key chains ([ietf-key-chain][5])
|
||||
- RADIUS shared secrets ([ietf-system][3])
|
||||
- TLS client/server credentials ([ietf-tls-client][6])
|
||||
|
||||
This provides defense-in-depth - even if NACM rules are misconfigured, these
|
||||
critical operations remain protected.
|
||||
|
||||
## Access Operations
|
||||
|
||||
NACM supports the following access operations:
|
||||
|
||||
- `create` - Create new data nodes
|
||||
- `read` - Read existing data nodes
|
||||
- `update` - Modify existing data nodes
|
||||
- `delete` - Delete data nodes
|
||||
- `exec` - Execute RPC operations
|
||||
- `*` - All operations (wildcard)
|
||||
|
||||
**Common combinations:**
|
||||
|
||||
- `"create update delete"` - All write operations
|
||||
- `"*"` - Everything (read, write, execute)
|
||||
- `"read"` - Read-only access
|
||||
|
||||
## Rule-List Groups
|
||||
|
||||
Each rule-list applies to one or more user groups:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "operator-acl",
|
||||
"group": ["operator"],
|
||||
"rule": [...]
|
||||
}
|
||||
```
|
||||
|
||||
**Special group names:**
|
||||
|
||||
- `"*"` - Matches all users (including those not in any NACM group)
|
||||
|
||||
**Evaluation:**
|
||||
A user can be in multiple NACM groups. All rule-lists matching the user's
|
||||
groups are evaluated in order until a matching rule is found.
|
||||
|
||||
## Example: Factory Configuration
|
||||
|
||||
The factory configuration uses a "permit by default, deny sensitive items"
|
||||
approach. This design is "future proof" - when new YANG modules are added,
|
||||
operators can immediately configure them without updating NACM rules.
|
||||
|
||||
```json
|
||||
{
|
||||
"ietf-netconf-acm:nacm": {
|
||||
"enable-nacm": true,
|
||||
"read-default": "permit",
|
||||
"write-default": "permit",
|
||||
"exec-default": "permit",
|
||||
"groups": {
|
||||
"group": [
|
||||
{"name": "admin", "user-name": ["admin"]},
|
||||
{"name": "operator", "user-name": []},
|
||||
{"name": "guest", "user-name": []}
|
||||
]
|
||||
},
|
||||
"rule-list": [
|
||||
{
|
||||
"name": "admin-acl",
|
||||
"group": ["admin"],
|
||||
"rule": [
|
||||
{
|
||||
"name": "permit-all",
|
||||
"module-name": "*",
|
||||
"access-operations": "*",
|
||||
"action": "permit",
|
||||
"comment": "Admin has full unrestricted access"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "operator-acl",
|
||||
"group": ["operator"],
|
||||
"rule": [
|
||||
{
|
||||
"name": "permit-system-rpcs",
|
||||
"module-name": "ietf-system",
|
||||
"rpc-name": "*",
|
||||
"access-operations": "exec",
|
||||
"action": "permit",
|
||||
"comment": "Operators can reboot, shutdown, and set system time"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "guest-acl",
|
||||
"group": ["guest"],
|
||||
"rule": [
|
||||
{
|
||||
"name": "deny-all-write+exec",
|
||||
"module-name": "*",
|
||||
"access-operations": "create update delete exec",
|
||||
"action": "deny",
|
||||
"comment": "Guests can only read, not modify or execute"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "default-deny-all",
|
||||
"group": ["*"],
|
||||
"rule": [
|
||||
{
|
||||
"name": "deny-password-access",
|
||||
"path": "/ietf-system:system/authentication/user/password",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access password hashes"
|
||||
},
|
||||
{
|
||||
"name": "deny-keystore-access",
|
||||
"module-name": "ietf-keystore",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access cryptographic keys"
|
||||
},
|
||||
{
|
||||
"name": "deny-truststore-access",
|
||||
"module-name": "ietf-truststore",
|
||||
"access-operations": "*",
|
||||
"action": "deny",
|
||||
"comment": "No user except admins can access trust store"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Key design decisions:**
|
||||
|
||||
1. **Permit by default** - `write-default: permit` allows operators to configure any module
|
||||
2. **Minimal operator rules** - Only one rule to permit system RPCs (reboot, set time)
|
||||
3. **Future proof** - New YANG modules automatically configurable by operators
|
||||
4. **Targeted denials** - Only sensitive items (passwords, keys) are explicitly denied
|
||||
5. **Global denials** - Password/keystore/truststore denied for everyone via group "*"
|
||||
6. **YANG annotations** - Sensitive operations (factory-reset, software upgrades) still protected by `nacm:default-deny-all` in YANG modules
|
||||
|
||||
**Effective permissions by group:**
|
||||
|
||||
| Group | Read | Write | Exec | Exceptions |
|
||||
|-------|------|-------|------|------------|
|
||||
| admin | All | All | All | None |
|
||||
| operator | All | All | All | Cannot access passwords, keystore, truststore |
|
||||
| guest | All | None | None | Read-only access |
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Permit-by-Default
|
||||
|
||||
The factory default approach - allow everything except sensitive items:
|
||||
|
||||
```json
|
||||
{
|
||||
"write-default": "permit",
|
||||
"exec-default": "permit",
|
||||
"rule-list": [
|
||||
{
|
||||
"name": "admin-acl",
|
||||
"group": ["admin"],
|
||||
"rule": [
|
||||
{
|
||||
"name": "permit-all",
|
||||
"module-name": "*",
|
||||
"access-operations": "*",
|
||||
"action": "permit"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "global-denials",
|
||||
"group": ["*"],
|
||||
"rule": [
|
||||
{
|
||||
"name": "deny-passwords",
|
||||
"path": "/ietf-system:system/authentication/user/password",
|
||||
"access-operations": "*",
|
||||
"action": "deny"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
This approach is "future proof" - new YANG modules are automatically
|
||||
accessible without rule updates. Admins bypass the global denials
|
||||
because their `permit-all` rule is evaluated first.
|
||||
|
||||
### Deny-by-Default
|
||||
|
||||
More restrictive approach - deny everything except what is explicitly
|
||||
allowed:
|
||||
|
||||
```json
|
||||
{
|
||||
"write-default": "deny",
|
||||
"exec-default": "deny",
|
||||
"rule-list": [
|
||||
{
|
||||
"group": ["limited-user"],
|
||||
"rule": [
|
||||
{
|
||||
"name": "permit-interface-config",
|
||||
"path": "/ietf-interfaces:interfaces/interface",
|
||||
"access-operations": "create update delete",
|
||||
"action": "permit"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> This requires updating NACM rules whenever new features are added.
|
||||
|
||||
### Global Restrictions
|
||||
|
||||
Deny access to sensitive data for all users (except admins with permit-all):
|
||||
|
||||
```json
|
||||
{
|
||||
"rule-list": [
|
||||
{
|
||||
"group": ["*"],
|
||||
"rule": [
|
||||
{
|
||||
"name": "deny-passwords",
|
||||
"path": "/ietf-system:system/authentication/user/password",
|
||||
"access-operations": "*",
|
||||
"action": "deny"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Debugging NACM
|
||||
|
||||
### Viewing Effective Permissions
|
||||
|
||||
Check what NACM groups a user belongs to:
|
||||
|
||||
```
|
||||
admin@example:/> show nacm
|
||||
enabled : yes
|
||||
default read access : permit
|
||||
default write access : permit
|
||||
default exec access : permit
|
||||
denied operations : 0
|
||||
denied data writes : 0
|
||||
denied notifications : 0
|
||||
|
||||
┌──────────┬─────────┬─────────┬─────────┐
|
||||
│ GROUP │ READ │ WRITE │ EXEC │
|
||||
├──────────┼─────────┼─────────┼─────────┤
|
||||
│ admin │ ✓ │ ✓ │ ✓ │
|
||||
│ operator │ ⚠ │ ⚠ │ ⚠ │
|
||||
│ guest │ ⚠ │ ✗ │ ✗ │
|
||||
└──────────┴─────────┴─────────┴─────────┘
|
||||
✓ Full ⚠ Restricted ✗ Denied
|
||||
|
||||
USER SHELL LOGIN
|
||||
admin bash password+key
|
||||
jacky bash password
|
||||
monitor false key
|
||||
|
||||
GROUP USERS
|
||||
admin admin
|
||||
operator jacky
|
||||
guest monitor
|
||||
```
|
||||
|
||||
For details about a group's restrictions, use `show nacm group <name>`:
|
||||
|
||||
```
|
||||
admin@example:/> show nacm group operator
|
||||
members : jacky
|
||||
read permission : restricted
|
||||
write permission : restricted
|
||||
exec permission : restricted
|
||||
applicable rules : 4
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
permit-system-rpcs
|
||||
action : permit
|
||||
operations : exec
|
||||
target : ietf-system (rpc: *)
|
||||
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
deny-password-access (via '*')
|
||||
action : deny
|
||||
operations : *
|
||||
target : /ietf-system:system/authentication/user/password
|
||||
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
deny-keystore-access (via '*')
|
||||
action : deny
|
||||
operations : *
|
||||
target : ietf-keystore
|
||||
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
deny-truststore-access (via '*')
|
||||
action : deny
|
||||
operations : *
|
||||
target : ietf-truststore
|
||||
```
|
||||
|
||||
### Testing Access
|
||||
|
||||
The easiest way to test NACM permissions is to log in as the user and try
|
||||
the operation:
|
||||
|
||||
```bash
|
||||
$ ssh jacky@host
|
||||
jacky@example:/> configure
|
||||
jacky@example:/config/> edit system authentication user admin
|
||||
jacky@example:/config/system/authentication/user/admin/> set authorized-key foo
|
||||
Error: Access to the data model "ietf-system" is denied because "jacky" NACM authorization failed.
|
||||
Error: Failed applying changes (2).
|
||||
```
|
||||
|
||||
### NACM Statistics
|
||||
|
||||
NACM tracks denied operations. If you suspect permission issues, check
|
||||
the statistics:
|
||||
|
||||
```
|
||||
admin@example:/> show nacm
|
||||
...
|
||||
denied operations : 5
|
||||
denied data writes : 12
|
||||
...
|
||||
```
|
||||
|
||||
Increasing counters indicate permission denials are occurring.
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Leverage permit-by-default** - The factory configuration uses
|
||||
`write-default: "permit"` with targeted denials. This is "future proof" -
|
||||
new features work immediately without NACM updates.
|
||||
|
||||
2. **Protect sensitive items globally** - Use `group: ["*"]` rule-list to
|
||||
deny access to passwords, cryptographic keys, and similar sensitive data.
|
||||
Admin's permit-all rule (evaluated first) bypasses these denials.
|
||||
|
||||
3. **Leverage YANG annotations** - Many sensitive operations are already
|
||||
protected by `nacm:default-deny-all` in YANG modules (factory-reset,
|
||||
software upgrades, etc.). Only add explicit permit rules when needed.
|
||||
|
||||
4. **Order matters** - Rule-lists are evaluated in order. Place admin's
|
||||
permit-all rule first so it bypasses global denials.
|
||||
|
||||
5. **Use path-based denials** - For protecting specific data (like password
|
||||
hashes), use path rules. For protecting entire modules (like keystore),
|
||||
use module-name rules.
|
||||
|
||||
6. **Test thoroughly** - Always test user permissions after changes. NACM
|
||||
errors can be subtle (nodes may be silently omitted from read operations).
|
||||
|
||||
7. **Keep it simple** - The factory configuration uses only 6 rules for
|
||||
three user levels. Fewer rules are easier to understand and maintain.
|
||||
|
||||
8. **Document rules** - Use the "comment" field to explain why specific
|
||||
permissions are granted or denied.
|
||||
|
||||
## References
|
||||
|
||||
- [RFC 8341: Network Configuration Access Control Model (NACM)][1]
|
||||
- [RFC 7317: A YANG Data Model for System Management (ietf-system)][3]
|
||||
- [RFC 8808: A YANG Data Model for Factory Default Settings (ietf-factory-default)][4]
|
||||
- [RFC 8177: YANG Key Chain (ietf-key-chain)][5]
|
||||
- [System Configuration - Multiple Users][2]
|
||||
|
||||
[1]: https://www.rfc-editor.org/rfc/rfc8341
|
||||
[2]: system.md#multiple-users
|
||||
[3]: https://www.rfc-editor.org/rfc/rfc7317
|
||||
[4]: https://www.rfc-editor.org/rfc/rfc8808
|
||||
[5]: https://www.rfc-editor.org/rfc/rfc8177
|
||||
[6]: https://datatracker.ietf.org/doc/html/draft-ietf-netconf-tls-client-server
|
||||
+259
-40
@@ -72,72 +72,291 @@ admin@example:/config/system/authentication/user/admin/authorized-key/example@ho
|
||||
> so there is no need to use the `text-editor` command, `set` does the
|
||||
> job.
|
||||
|
||||
|
||||
## Multiple Users
|
||||
|
||||
The system supports multiple users and multiple user levels, or groups,
|
||||
that a user can be a member of. Access control is entirely handled by
|
||||
the NETCONF ["NACM"][3] YANG model, which provides granular access to
|
||||
configuration, data, and RPC commands over NETCONF.
|
||||
The factory configuration provides three hierarchical user group levels by
|
||||
default: **guest ⊂ operator ⊂ admin**. These levels work out-of-the-box
|
||||
with sensible permissions - operators can configure the system immediately,
|
||||
while sensitive items (passwords, cryptographic keys) remain protected.
|
||||
|
||||
By default the system ships with a single group, `admin`, which the
|
||||
default user `admin` is a member of. The broad permissions granted by
|
||||
the `admin` group is what gives its users full system administrator
|
||||
privileges. There are no restrictions on the number of users with
|
||||
administrator privileges, nor is the `admin` user reserved or protected
|
||||
in any way -- it is completely possible to remove the default `admin`
|
||||
user from the configuration. However, it is recommended to keep at
|
||||
least one user with administrator privileges in the system, otherwise
|
||||
the only way to regain full access is to perform a *factory reset*.
|
||||
The default levels provide different access to system resources and
|
||||
configuration:
|
||||
|
||||
- **Admin**: Full system access - can manage users, upgrade software,
|
||||
restart the system, and modify all configuration including network
|
||||
settings, routing, and firewall rules.
|
||||
|
||||
- **Operator**: Configuration access - can modify most system settings
|
||||
including network interfaces, routing, firewall, hostname, and more.
|
||||
*Cannot access* password hashes, cryptographic keys, or perform
|
||||
sensitive operations (factory reset, software upgrade).
|
||||
|
||||
- **Guest**: Read-only access - can view operational state and
|
||||
configuration but cannot modify anything or execute operations.
|
||||
|
||||
System access control is handled by the [ietf-netconf-acm][3] YANG model,
|
||||
usually referred to as [NACM](nacm.md), which provides granular access to
|
||||
configuration, data, and RPC commands. The hierarchical levels in the system
|
||||
are determined by:
|
||||
|
||||
1. **NACM permissions** - what the user can access
|
||||
2. **Shell setting** - which command-line interface the user can use
|
||||
|
||||
By default the system ships with a single user, `admin`, in the `admin`
|
||||
group. There are no restrictions on the number of users with admin
|
||||
privileges, nor is the `admin` user reserved or protected -- it can be
|
||||
removed from the configuration. However, it is strongly recommended to
|
||||
keep at least one user with administrator privileges, otherwise the only
|
||||
way to regain full access is to perform a *factory reset*.
|
||||
|
||||
For an overview of users and groups on the system, there is an admin-exec
|
||||
command:
|
||||
|
||||
```
|
||||
admin@example:/> show nacm
|
||||
enabled : yes
|
||||
default read access : permit
|
||||
default write access : permit
|
||||
default exec access : permit
|
||||
denied operations : 0
|
||||
denied data writes : 0
|
||||
denied notifications : 0
|
||||
|
||||
┌──────────┬─────────┬─────────┬─────────┐
|
||||
│ GROUP │ READ │ WRITE │ EXEC │
|
||||
├──────────┼─────────┼─────────┼─────────┤
|
||||
│ admin │ ✓ │ ✓ │ ✓ │
|
||||
│ operator │ ⚠ │ ⚠ │ ⚠ │
|
||||
│ guest │ ⚠ │ ✗ │ ✗ │
|
||||
└──────────┴─────────┴─────────┴─────────┘
|
||||
✓ Full ⚠ Restricted ✗ Denied
|
||||
|
||||
USER SHELL LOGIN
|
||||
admin bash password+key
|
||||
jacky clish password
|
||||
monitor false key
|
||||
|
||||
GROUP USERS
|
||||
admin admin
|
||||
operator jacky
|
||||
guest monitor
|
||||
```
|
||||
|
||||
The permissions matrix shows effective access for each NACM group:
|
||||
|
||||
- **✓ Full** (green) - unrestricted access
|
||||
- **⚠ Restricted** (yellow) - access with exceptions, use `show nacm group`
|
||||
for details
|
||||
- **✗ Denied** (red) - no access
|
||||
|
||||
For detailed information about a specific group's rules:
|
||||
|
||||
```
|
||||
admin@example:/> show nacm group operator
|
||||
members : jacky
|
||||
read permission : restricted
|
||||
write permission : restricted
|
||||
exec permission : restricted
|
||||
applicable rules : 4
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
permit-system-rpcs
|
||||
action : permit
|
||||
operations : exec
|
||||
target : ietf-system (rpc: *)
|
||||
comment : Operators can reboot, shutdown, and set system time.
|
||||
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
deny-password-access (via '*')
|
||||
action : deny
|
||||
operations : *
|
||||
target : /ietf-system:system/authentication/user/password
|
||||
comment : No user except admins can access password hashes.
|
||||
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
deny-keystore-access (via '*')
|
||||
action : deny
|
||||
operations : *
|
||||
target : ietf-keystore
|
||||
comment : No user except admins can access cryptographic keys.
|
||||
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
deny-truststore-access (via '*')
|
||||
action : deny
|
||||
operations : *
|
||||
target : ietf-truststore
|
||||
comment : No user except admins can access trust store.
|
||||
```
|
||||
|
||||
For user details:
|
||||
|
||||
```
|
||||
admin@example:/> show nacm user jacky
|
||||
shell : clish
|
||||
login : password
|
||||
nacm group : operator
|
||||
read permission : restricted
|
||||
write permission : restricted
|
||||
exec permission : restricted
|
||||
|
||||
For detailed rules, use: show nacm group <name>
|
||||
```
|
||||
|
||||
### Adding a User
|
||||
|
||||
Similar to how to change password, adding a new user is done using the
|
||||
same set of commands:
|
||||
Creating a new user starts with defining the user account in the system:
|
||||
|
||||
```
|
||||
admin@host:/config/> edit system authentication user jacky
|
||||
admin@host:/config/system/authentication/user/jacky/> change password
|
||||
admin@example:/config/> edit system authentication user jacky
|
||||
admin@example:/config/system/authentication/user/jacky/> change password
|
||||
New password:
|
||||
Retype password:
|
||||
admin@host:/config/system/authentication/user/jacky/> leave
|
||||
admin@example:/config/system/authentication/user/jacky/> leave
|
||||
```
|
||||
|
||||
An authorized SSH key is added the same way as presented previously.
|
||||
An authorized SSH key can be added the same way as described in the
|
||||
previous sections.
|
||||
|
||||
### Adding a User to the Admin Group
|
||||
|
||||
The following commands add user `jacky` to the `admin` group.
|
||||
By default, shell access is disabled (`shell false`). To allow CLI/SSH
|
||||
access, set the shell:
|
||||
|
||||
```
|
||||
admin@host:/config/> edit nacm group admin
|
||||
admin@host:/config/nacm/group/admin/> set user-name jacky
|
||||
admin@host:/config/nacm/group/admin/> leave
|
||||
admin@example:/config/> edit system authentication user jacky
|
||||
admin@example:/config/system/authentication/user/jacky/> set shell clish
|
||||
admin@example:/config/system/authentication/user/jacky/> leave
|
||||
```
|
||||
|
||||
Available shells:
|
||||
|
||||
- `bash` - Full Bourne-again shell (recommended for admins only)
|
||||
- `sh` - POSIX shell (recommended for admins only)
|
||||
- `clish` - Limited CLI-only shell (recommended for operators and guests)
|
||||
- `false` - No shell access (default)
|
||||
|
||||
> [!WARNING] Security Notice
|
||||
> For security reasons, it is strongly recommended to limit non-admin users
|
||||
> to the `clish` shell, which provides CLI access without exposing the
|
||||
> underlying UNIX system. Reserve `bash` and `sh` for administrators who
|
||||
> need full system access for debugging and maintenance.
|
||||
>
|
||||
> Note that shell and CLI access is not always necessary - the system
|
||||
> supports NETCONF and RESTCONF for remote management and automation.
|
||||
> Setting `shell false` for users who only need programmatic access
|
||||
> minimizes the attack surface and improves overall system security.
|
||||
|
||||
### Adding a User to a Group
|
||||
|
||||
To assign a user to a specific privilege level, add them to the
|
||||
corresponding NACM group:
|
||||
|
||||
**Operator user:**
|
||||
|
||||
```
|
||||
admin@example:/config/> edit nacm group operator
|
||||
admin@example:/config/nacm/group/operator/> set user-name jacky
|
||||
admin@example:/config/nacm/group/operator/> leave
|
||||
```
|
||||
|
||||
**Adding another admin:**
|
||||
|
||||
```
|
||||
admin@example:/config/> edit nacm group admin
|
||||
admin@example:/config/nacm/group/admin/> set user-name alice
|
||||
admin@example:/config/nacm/group/admin/> leave
|
||||
```
|
||||
|
||||
**Guest user:**
|
||||
|
||||
```
|
||||
admin@example:/config/> edit nacm group guest
|
||||
admin@example:/config/nacm/group/guest/> set user-name monitor
|
||||
admin@example:/config/nacm/group/guest/> leave
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> For technical details about NACM rule evaluation, module-name vs path
|
||||
> matching, and creating custom access control policies, see the
|
||||
> [NACM Technical Guide](nacm.md).
|
||||
|
||||
### Access Control Matrix
|
||||
|
||||
The following table shows what each user level can do based on the NACM rules
|
||||
and shell access configured for each user:
|
||||
|
||||
- **Admin**: `bash` — full system access
|
||||
- **Operator**: `clish` — CLI-only access without UNIX system exposure
|
||||
- **Guest**: `false` — no shell access
|
||||
|
||||
| Feature | Admin | Operator | Guest |
|
||||
|------------------------|-------|----------|-----------|
|
||||
| Network interfaces | ✓ | ✓ | Read only |
|
||||
| Routing (FRR) | ✓ | ✓ | Read only |
|
||||
| Firewall rules | ✓ | ✓ | Read only |
|
||||
| VLANs/bridges | ✓ | ✓ | Read only |
|
||||
| Containers | ✓ | ✓ | Read only |
|
||||
| Hostname/system config | ✓ | ✓ | Read only |
|
||||
| CLI/SSH access | ✓ | ✓ | ✗ |
|
||||
| System restart | ✓ | ✓ | ✗ |
|
||||
| Set date/time | ✓ | ✓ | ✗ |
|
||||
| System reboot | ✓ | ✓ | ✗ |
|
||||
| System shutdown | ✓ | ✓ | ✗ |
|
||||
| User management | ✓ | ✗ | Read only |
|
||||
| Keystore (certs/keys) | ✓ | ✗ | ✗ |
|
||||
| Truststore | ✓ | ✗ | ✗ |
|
||||
| Read passwords/secrets | ✓ | ✗ | ✗ |
|
||||
| NACM rules | ✓ | ✗ | ✗ |
|
||||
| Factory reset | ✓ | ✗ | ✗ |
|
||||
| Software upgrade | ✓ | ✗ | ✗ |
|
||||
|
||||
### Security Aspects
|
||||
|
||||
The NACM user levels apply primarily to NETCONF, with exception of the
|
||||
`admin` group which is granted full system administrator privileges to
|
||||
the underlying UNIX system with the following ACL rules:
|
||||
The three default user levels are implemented through a combination of NACM
|
||||
rules and UNIX group membership. Access control is permission-based, not
|
||||
name-based - the system detects user levels by examining their NACM
|
||||
permissions and shell settings.
|
||||
|
||||
**Admin users** have unrestricted NACM access with the following rule:
|
||||
|
||||
```json
|
||||
...
|
||||
"module-name": "*",
|
||||
"access-operations": "*",
|
||||
"action": "permit",
|
||||
...
|
||||
"action": "permit"
|
||||
```
|
||||
|
||||
A user in the `admin` group is allowed to also use a POSIX login shell
|
||||
and use the `sudo` command to perform system administrative commands.
|
||||
This makes it possible to use all the underlying UNIX tooling, which
|
||||
to many can be very useful, in particular when debugging a system, but
|
||||
please remember to use with care -- the system is not built to require
|
||||
managing from the shell. The tools available in the CLI and automated
|
||||
services, started from the system's configuration, are the recommended
|
||||
way of using the system, in addition to NETCONF tooling.
|
||||
Admin users are automatically added to the UNIX `wheel` and `frrvty`
|
||||
groups, granting them `sudo` privileges and access to FRR routing
|
||||
protocols. This makes it possible to use all the underlying UNIX
|
||||
tooling, which can be very useful for debugging, but please use with
|
||||
care -- the system is designed to be managed through the CLI and
|
||||
NETCONF, not directly via shell commands.
|
||||
|
||||
**Operator users** use the permit-by-default NACM model (`write-default:
|
||||
"permit"`), which means they can configure most system settings without
|
||||
explicit permit rules. This design is "future proof" - when new features
|
||||
are added, operators can immediately use them.
|
||||
|
||||
The following are explicitly denied to operators through global NACM rules:
|
||||
|
||||
- Password hashes (`/ietf-system:system/authentication/user/password`)
|
||||
- Cryptographic keys (`ietf-keystore` module)
|
||||
- Trust store certificates (`ietf-truststore` module)
|
||||
|
||||
Additionally, sensitive operations like factory reset, software upgrades,
|
||||
and system shutdown are protected by YANG-level `nacm:default-deny-all`
|
||||
annotations and remain restricted to administrators.
|
||||
|
||||
Operators are automatically added to the UNIX `operator` and `frrvty`
|
||||
groups, granting them `sudo` privileges for network operations and FRR
|
||||
access.
|
||||
|
||||
**Guest users** have read-only NACM access through an explicit deny rule
|
||||
that blocks all write and exec operations (`create update delete exec`),
|
||||
while `read-default: "permit"` allows viewing configuration and state.
|
||||
Guests receive no special UNIX group memberships. The shell setting
|
||||
determines whether guests can access the CLI (`clish`) or are restricted
|
||||
from shell access entirely (`false`).
|
||||
|
||||
All users, regardless of level, are denied access to password hashes and
|
||||
cryptographic key material through global NACM rules.
|
||||
|
||||
## Changing Hostname
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ nav:
|
||||
- System:
|
||||
- Boot Procedure: boot.md
|
||||
- Configuration: system.md
|
||||
- Access Control (NACM): nacm.md
|
||||
- Hardware Info & Status: hardware.md
|
||||
- Management: management.md
|
||||
- Syslog Support: syslog.md
|
||||
|
||||
Reference in New Issue
Block a user