アプリが管理者権限で動いているか確認する

is_elevated クレートと geteuid で、アプリが管理者(root)権限で動いているかを判定する。管理者として再起動する方法と NSIS の installMode との関係も示す。

システム情報 対象: Tauri 2.x 更新日: 読了目安: 約6分 sys-021
目次
  1. 前提条件
  2. 1. フロントエンドから実装する (TypeScript)
  3. 2. バックエンドから実装する (Rust)
  4. 管理者権限で再起動する
  5. 動作確認
  6. よくあるエラーと対処法
  7. OS ごとの違いと注意点
  8. 関連レシピ

Program Files 配下への書き込み、1024 未満のポートの bind、サービスの登録は、Windows なら管理者(UAC で昇格したプロセス)、macOS / Linux なら root でないと失敗します。操作の直前に権限を確認し、無ければ「管理者として起動し直してください」と案内するだけで問い合わせがかなり減ります。判定はフロントからはできないので Rust 側で行います。Windows は is_elevated クレート、Unix 系は nix の geteuid() を使い、cfg で分岐させます。

前提条件

クレートは OS ごとに分けて依存に入れます。is_elevated は Windows 専用で、通常の [dependencies] に書くと macOS / Linux のビルドが通りません。プラグインと権限設定は不要です。

src-tauri/Cargo.toml:

[target.'cfg(windows)'.dependencies]
is_elevated = "0.1"

[target.'cfg(unix)'.dependencies]
nix = { version = "0.31", features = ["user"] }

1. フロントエンドから実装する (TypeScript)

import { invoke } from '@tauri-apps/api/core';

async function ensureAdmin(): Promise<boolean> {
  const elevated = await invoke<boolean>('is_admin');
  if (!elevated) {
    document.getElementById('warn')!.textContent =
      'この操作には管理者権限が必要です。アプリを管理者として起動し直してください。';
  }
  return elevated;
}

document.getElementById('install-service')!.addEventListener('click', async () => {
  if (await ensureAdmin()) await invoke('install_service');
});

2. バックエンドから実装する (Rust)

src-tauri/src/lib.rs:

#[cfg(windows)]
fn elevated() -> bool {
    is_elevated::is_elevated() // TokenElevation を見る。UAC で昇格していれば true
}

#[cfg(unix)]
fn elevated() -> bool {
    nix::unistd::geteuid().is_root() // 実効ユーザー ID が 0 なら root。sudo 経由でも true
}

#[tauri::command]
fn is_admin() -> bool {
    elevated()
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![is_admin])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

クレートを増やしたくない場合、Unix は libc::geteuid() == 0(unsafe が必要)、Windows は windows クレートで OpenProcessToken → GetTokenInformation(TokenElevation) を呼べば同じことができます。

管理者権限で再起動する

昇格は「起動時」にしか決められません。実行中のプロセスを後から昇格させる API は無いので、自分自身を昇格付きで起動し直してから終了します。

  • Windows: ShellExecuteW の動詞 runas で自分の exe を起動すると UAC ダイアログが出ます。手軽には Start-Process -FilePath <exe> -Verb RunAs を PowerShell 経由で実行し、その後 app.exit(0) します。常に管理者で起動させたいアプリは、tauri_build::WindowsAttributes::app_manifest() で requestedExecutionLevel="requireAdministrator" を含むマニフェストを埋め込みます。
  • macOS: GUI アプリ全体を root で動かす仕組みはありません。特権が必要な処理だけを osascript -e 'do shell script "..." with administrator privileges' に切り出すか、ヘルパーツールを別途インストールします。
  • Linux: pkexec <exe> で Polkit の認証ダイアログが出ますが、root で起動した WebKitGTK アプリは環境によって警告が出ます。macOS 同様「特権が必要な処理だけを外に出す」設計が無難です。

動作確認

通常のターミナルから npm run tauri dev を実行すると is_admin は false、管理者として開いた PowerShell(Windows)や sudo npm run tauri dev(macOS / Linux)から実行すると true になります。ビルド後の exe を右クリックして「管理者として実行」でも確認できます。

よくあるエラーと対処法

  • macOS / Linux で is_elevated に関するビルドエラー: is_elevated を [dependencies] に直接書いています。[target.'cfg(windows)'.dependencies] へ移します。
  • nix::unistd::geteuid が見つからない: nix の user フィーチャーが無効です。features = ["user"] を付けます。
  • 管理者アカウントなのに false: Windows の管理者アカウントでも、UAC を通らずに起動したプロセスは制限付きトークンで動きます。判定しているのはアカウント種別ではなくプロセスの昇格状態なので、正しい挙動です。
  • NSIS で installMode: "perMachine" にしたのに false: installMode は「インストーラーが管理者権限を要求するか」の設定で、インストール後のアプリ実行には影響しません。アプリ自体を昇格させるには前述のマニフェストが必要です。

OS ごとの違いと注意点

  • Windows: UAC を無効にした環境では、管理者アカウントのプロセスは常に昇格状態になります。runas での再起動は毎回 UAC ダイアログが出るので、必要な操作の直前だけにします。
  • macOS: geteuid() が 0 になるのは sudo でターミナルから起動した場合だけです。App Store 配布アプリはサンドボックスの制約で root 実行自体が想定されていません。
  • NSIS の installMode: currentUser(既定。管理者不要でユーザーフォルダに入る)、perMachine(Program Files に入るためインストール時のみ管理者が必要)、both(インストール時に選択)の 3 択です。perMachine にすると、アプリ実行時に自分のインストール先へ書き込めなくなる点に注意してください。

関連レシピ

参考リンク(公式ドキュメント)

Web Ninja

この記事を書いた人

Web Ninja ウェブエンジニア (Web Engineer)

会社員ネットワークエンジニアから独立してかれこれ 25 年以上 Web エンジニアとして活動中。普段は JavaScript と Node.js を自在に操り、時には C++ や Perl といった古流の技も嗜みます。近年は Tauri × Rust という新たな武器を手に、デスクトップアプリ開発の最前線を駆け抜けています。「作りたい」を「作れる」に変えるための、実践的な「技」をお届けします。

お問い合わせ: tauri.ninja@gmail.com

内容の誤り・動かないコードを報告する