コンテンツにスキップ

user

目的: ローカルの Linux ユーザー(/etc/passwd)を宣言する。存在 (present)または不在(absent)、そして指定した項目 — uid、プライマリ グループ、シェル、ホームディレクトリの記録、補助グループ — だけを対象と します。指定しない項目は変更も監査もされません。

- id: app_group
type: group
with:
name: app
gid: 990
system: true
- id: app_user
type: user
depends_on: [app_group]
with:
name: app
uid: 990
group: app
groups: [systemd-journal]
shell: /usr/sbin/nologin
home: /var/lib/app
system: true
- id: app_state
type: directory
depends_on: [app_user]
with:
path: /var/lib/app
owner: app
group: app
mode: "0750"
パラメータ 必須 型 デフォルト 説明
name はい string — ユーザー名。静的。[a-z_][a-z0-9_-]*、最大 32 文字。
state いいえ string present present または absent。
uid いいえ integer 管理しない 必須の uid(1〜4294967294)。0 は不可。
group いいえ string 管理しない プライマリグループ(名前で指定)。事前に存在している必要があります(依存関係を参照)。
groups いいえ string のリスト 管理しない 補助グループ(名前)。追加のみ: ユーザーをこれらに追加し、どのグループからも削除しません。プライマリグループを重複して指定できません。
shell いいえ string 管理しない ログインシェルの絶対パス(/usr/sbin/nologin)。/etc/shells との照合は行いません。パスの規則は home と同じです。
home いいえ string 管理しない ホームディレクトリとして記録する絶対パス。記録のみを設定し、作成も移動も行いません。パスの規則を参照。
create_home いいえ boolean false ホームディレクトリを作成(useradd -m)。作成時のみ有効。false のときは -M を明示的に渡します。
system いいえ boolean false システムユーザーとして作成(useradd --system)。作成時のみ有効で、監査も後からの変更もしません。
password_hash いいえ { secret: <path> } 管理しない パスワードのハッシュ(パスワード自体ではない)。暗号化シークレットとして保持します。パスワードハッシュを参照。

未知のフィールドはスキーマエラーです。平文のパスワード、ロック、有効期限、SSH 鍵、 move_home、remove_home、force、non_unique のフィールドはありません。 これらはこのリソースの対象外です。

どちらもコロン区切りの /etc/passwd レコードに保存されるため、同じ規則が適用されます。 / そのものではない絶対パスで、空・.・.. の要素、連続または末尾の /、NUL、 : や ,、制御文字を含みません。規則に反するリテラルはスキーマエラーです(validate が 失敗します)。{{ }} 補間を使う値は評価後に検査され、結果が不正ならコマンドを実行する前に エラーになります。どちらの場合も、アカウントが黙って変更されることはありません。

項目を宣言しない場合、作成時にはディストリビューション既定の useradd が 適用されます(たとえば group を省略すると同名のプライベートグループ。同名のグループがすでにある場合、または group の依存先が作る場合は、拒否して group: の宣言を求めます)。 ホームディレクトリ自体は directory リソースで管理してください。

  • ローカルのみ。 ユーザーは getent -s files passwd で観測します。別の ID ソースだけが提供するユーザーはエラーです。それを覆い隠すローカル ユーザーを作ることはありません。group/groups に指定したグループも同様 です。
  • present でユーザーがいない → useradd を 1 回 ([--system] [-u uid] [-g group] [-G g1,g2] [-s shell] [-d home] (-m|-M) name)。 別のローカルユーザーが使用中の uid での作成は拒否されます。
  • present でユーザーがいる → 最大 1 回の usermod (-g、-s、-d、足りないグループだけの -a -G)。-m は渡さないため、 ホームディレクトリは移動しません。
  • 既存ユーザーの uid 不一致は拒否され、修復されません(usermod -u は ホーム外のファイルの所有者を直しません)。audit は uid の DRIFT を 報告します。
  • 補助グループのメンバーシップは追加のみです。すでに所属しているグループ や宣言していないグループには触れません。完全一致(exact)には対応して いません。
  • absent でユーザーがいる → -r も -f もなしの userdel name。ホーム ディレクトリとメールスプールは残り、その uid が所有するファイルも残ります (結果に明記されます。ファイルシステムは検索しません)。ディストリ ビューションの userdel が同名のプライベートグループも削除した場合は、 その旨が結果に記載されます。root、uid 0、この実行が使うアカウント、 セッションを実行・接続しているアカウントは拒否されます。実行中のプロセスが あるユーザーでは userdel/usermod が失敗し、失敗として報告されます。

password_hash には暗号化シークレットが必要です。

- id: app_user
type: user
with:
name: app
password_hash: { secret: secrets/app-password-hash.age }

Sinter は平文のパスワードを見ず、password フィールドもありません。手元のツール (mkpasswd -m sha-512、openssl passwd -6 など)でハッシュを作り、その 1 行を sinter secrets encrypt で保存して参照します。ハッシュは秘密情報 (オフラインで解読され得る)なので、レシピには書かず、表示もしません。

  • 受け付ける値: $y$(yescrypt)または $6$(sha512crypt)のハッシュ 1 つだけ ($6$[rounds=N$]salt$hash、N は 1000〜999999999)、256 バイト以下。文字は [./0-9A-Za-z] のみ、末尾の改行は 1 つまで。それ以外(DES、$1$、$5$、bcrypt、平文のパスワード、余分な 空白、先頭の ! や *)は値を表示せずに拒否します。
  • salt: $6$ の salt は [./0-9A-Za-z] の 1〜16 文字で、crypt(5) より厳格です。 openssl passwd -6 -salt 'my_salt' で作ったハッシュは拒否されるため、salt はツールに 生成させてください。
  • EL9: RHEL / Rocky / AlmaLinux 9 では $y$ を拒否します(shadow-utils と libxcrypt が yescrypt なしでビルドされているため)。$6$ を使ってください。他のプラットフォームは 確認しません。yescrypt を検証できないディストリビューション(サポート対象より古いもの) では $y$ ハッシュは保存されてもログインできません。
  • --sudo が必須です。 /etc/shadow は root だけが読めます。--sudo がないと plan / apply / audit は失敗し(audit は ERROR)、「変更なし」とは決して 報告しません。この確認の前にシークレットは開きません。
  • 常に sensitive(sensitive: の指定に関わらず)で、これはリソース全体に及び、 パスワードだけではありません。plan の差分は伏せられ、ノートとエラーは固定文(アカウント名は [redacted] と表示され、拒否の理由は一般的な文言)で、ツールの stderr は出しません。 audit はドリフトした項目(uid、shell、groups、password_hash など)の名前は示しますが、 すべての項目で両側が [redacted] になり、値は出ません。したがって password_hash を 宣言したユーザーでは、観測値・宣言値の id、パス、グループ名はどの出力にも現れません。
  • validate は復号しません。 参照と age ファイルの存在だけを確認します。plan / apply / audit は sinter secrets と同じ identity 探索で 復号します。鍵が使えなければそのリソースは失敗し(audit は ERROR)、「変更なし」には なりません。
  • state: absent とは併用できません(スキーマエラー)。

適用と観測の方法:

  • 保存されているフィールドは、sudo 配下の getent -s files shadow <name> で読み、 宣言したハッシュとメモリ上で比較します。先頭の !(ロック)は比較で無視するため、 宣言したハッシュをすでに持つロック済みのアカウントは準拠とみなされ、ロックされたままです。 shadow レコードが読めない・ない、またはローカルファイルにないアカウントはエラーです。
  • 不一致のときだけ、sudo -n 配下で /usr/sbin/chpasswd -e を実行し、name:hash を 標準入力で渡します(コマンドラインには載せず、usermod -p もシェルも使いません)。 ハッシュがすでに一致していれば何も書きません。書き込みのたびに最終変更日(パスワード エージング)が更新されます。
  • 新しいユーザーは先に作成(useradd)してからパスワードを設定します。アカウントを 作成・変更した後でパスワードの設定が失敗した場合は、その旨を結果に示します (change は changed、失敗)。再実行で完了します。
  • 宣言したハッシュは強制されます: ユーザーが変更したパスワードは次の apply で 置き換えられます。
  • ロックされたアカウント: 異なるハッシュでロックされたアカウント(!<hash>)は 拒否します。chpasswd -e はフィールドを置き換え、黙ってロックを解除してしまうため です(ロック用のフィールドはまだありません)。パスワードが全くない状態(空のフィールド、!、 !!、*、!* などのマーカー)には、そのままハッシュを設定します。つまり !! のアカウントは パスワードが有効になります。
  • コントローラは比較のため、アカウントの現在のハッシュを一時的にメモリに保持します。 これは宣言したハッシュと同じく秘密情報であり、隠さず文書化しています。この password_hash の動作は 2026-10-04 に実機受入検証されました(Ubuntu 26.04 の sudo-rs を含む)。対応プラットフォームを参照。

依存関係は明示的です。推測は行いません。参照の解決が保留されるのは、アカウントを作る リソースが、依存する側のリソース自身の depends_on に直接挙げられていて、その state が present(既定)と評価される場合だけです。ほかの依存関係の連鎖を介してしか たどれないリソースや、absent のリソースが作るアカウントは考慮されず、未知のアカウントの plan エラーはそのままです。保留は plan だけにあり、apply は依存関係の順に実行して アカウントを実際に検索します。

  • group/groups が group リソースで作られるグループを指す場合、その リソースを自身の depends_on に挙げる必要があります。plan では、そのような ユーザーは失敗せず保留(apply まで unknown)され、それに依存する すべても同様です。依存関係のないグループ欠落は、その旨を示す plan エラー です。
  • owner/group が user/group リソースで作られるアカウントを指す file・directory・template は、そのリソースを自身の depends_on に 挙げていれば plan で保留されます。depends_on がなければ、まだ存在しない 所有者の plan は従来どおり未知のアカウントのエラーで失敗します。

宣言したすべての項目に一致するユーザーは何も変更しません。収束後の 2 回目の apply は useradd/usermod/userdel を実行しません。

audit は宣言した項目 — state、uid、group、groups、shell、home、 password_hash — を個別にドリフトとして報告します。通常のユーザーでは値を表示しますが、 password_hash を持つユーザー(常に sensitive)では、すべての項目で両側が [redacted] になり、 password_hash には値がありません。別の ID ソースだけが提供するアカウントは ERROR です。create_home と system は作成時のオプションで、監査されません。

  • アカウントコマンドの失敗は、変更の可能性あり・検証不明の失敗です。失敗した コマンドの後は再観測しません。終了コード 0 の場合は再観測し、宣言した状態に ならなければ検証失敗です。
  • 拒否(番号振り直し、保護対象アカウント、使用中の ID、グループ欠落、外部 提供のアカウント)はコマンド実行前に行われ、plan では plan エラーです。
  • 失敗したユーザーに依存するリソースは実行されません。

プラットフォームに関する補足

Section titled “プラットフォームに関する補足”

/usr/sbin/useradd、usermod、userdel、chpasswd と getent を argv のみ・シェルなしで 使います。上記の password_hash の動作は 2026-10-04 に Ubuntu 24.04 / 26.04、 Rocky Linux・RHEL・AlmaLinux 9 / 10 の実機で受入検証されました。このリソースの useradd / usermod / userdel の各次元は実機では検証しておらず、スクリプト 化された fake ターゲットでのみ立証されています。

group · directory · リソース