Skip to content

core.user

← Module catalog

soul-sidesoulstack.systemsystemroot required

Manage local OS users: account creation and removal.

core.user brings the set of local accounts to the required composition via useradd / userdel. present has present-or-create semantics: if the user already exists, the step reconciles nothing (uid/shell/home/groups are not changed) and reports changed=false, while the optional parameters apply only at creation (usermod is not called). Requires root.

Requirements

  • Rootrequired
  • Sidesoul-side
  • Collectionsoulstack.system
  • Categorysystem
Capabilitiesrun_as_rootexec_subprocess
Backend detection

useradd / userdel — a busybox-compatible subset of flags; on Alpine this is the shadow package or busybox's built-in commands, both of which understand the flags used.

States

core.user.present — The user exists (created via useradd if it is missing).

Changes when

The user did not exist and was created.

Stays unchanged when

The user already exists — uid/shell/home/groups/system/group are not reconciled.

Parameters

ParamTypeRequired / defaultDescription
namestringrequiredUser name.
uidintoptionalExplicit uid (useradd -u). Applies only on creation.
shellstringoptionalLogin shell (useradd -s). Applies only on creation.
homestringoptionalHome directory (useradd -d). Applies only on creation.
groupslist<string>optionalSupplementary groups (useradd -G). Applies only on creation.
systembooloptionalSystem account (useradd -r) for service accounts. Only on creation.
groupstringoptionalPrimary group (useradd -g); must already exist. Only on creation.

Example — System service account (primary group created BEFORE)

# The primary group is created BEFORE the user (core.user -g requires an existing one).
- name: Ensure the app system group exists
module: core.group.present
params:
name: appsvc
system: true
- name: Ensure the app system user exists
module: core.user.present
params:
name: appsvc
system: true
group: appsvc
shell: /usr/sbin/nologin
home: /var/lib/appsvc

Output

FieldTypeDescription
namestring
existstrue
createdbool

Notes

  • present — present-or-create: an existing user is not reconciled (uid/shell/home/groups/system/group are not checked or changed), the optional parameters are applied only at creation — usermod is not called. To rebuild an account, remove it via absent and create it again.
  • home is passed with the -M flag: the module does not create the home directory. The primary group (group) must exist beforehand — create it via core.group BEFORE the user.
  • The module validates the shape of the input without tightening useradd's constraints: name/group/groups follow shadow-utils NAME_REGEX (^[a-z_][a-z0-9_-]*\$?$, length ≤ 32), uid is in the range [0, 2147483647], shell/home is an absolute path (file and directory existence is not checked). The positional name is preceded by -- (useradd -- <name>), and argv is built directly without sh — this cuts off arg-injection and plainly malformed input.

Security & defaults

  • The shape of the input is checked, not whether its meaning is privileged. uid: 0 creates a second root-equivalent account; groups: ["sudo"] / ["wheel"] / ["docker"] gives its holder an effective path to root — both values are valid by format. Format validation cuts off injection but not "dangerous yet valid" meaning: this is not authorization.
  • Privileged values are part of the attack surface: if uid/groups/name come from input.* / register.* / soulprint.*, they must be trusted — set by the Destiny/scenario author, not by external input. For a service account, pin safe values — system: true, no sudo/wheel/docker, shell /usr/sbin/nologin.
  • present — present-or-create: you cannot lower the privileges of a previously created account with a repeated present (uid/groups are not reconciled). Revoking privileges is only possible by recreating through absent.
  • required_capabilities [run_as_root, exec_subprocess] is a declaration for soul-lint's static check against the host's allowed_capabilities, not a runtime privilege escalation: useradd/userdel run with the soul agent process's privileges (as root).

See also