自分のMac / Linuxアプリに、RoamSwitchの診断機能をそのまま
RoamSwitchKit(Mac)と roamswitch-linux-kit(Linux)は、RoamSwitch本体が計算しているセキュリティ診断結果を、Swift / Rustコードから直接参照できる無償・オープンソースのクライアントです。ARP監視やポートスキャンを自作することなく、「今のネットワークは安全か」を自分のアプリに組み込めます。
🔒 なぜ安全なのか
- 読み取り専用: ロックダウン切替・ポート隔離・デバイス取り出しなどの操作系APIは一切存在しません。組み込んだアプリがユーザーの許可なくRoamSwitchの設定を変更することはできません。
- 完全ローカル: RoamSwitch本体に同梱されたバイナリ(macOS: RoamSwitchMCPServer / Linux: roamswitch-mcp)をサブプロセスとして起動し、標準入出力のみで通信します。テレメトリは一切送信しません。外部のホストへ通信するのは、オプトイン(Mac では Pro 限定)の run_npm_audit_signatures(npm レジストリ)だけです。run_active_vuln_scan(既定で無効)は 127.0.0.1 へのプローブ、Mac の get_exposed_ports は公開ポートごとに 127.0.0.1 へ HTTP GET を1回送ってヘッダを確認するだけです。ゲートウェイの MAC アドレスを調べるとき、Mac の診断系ツールは LAN 内のゲートウェイに ICMP ping を通常1発(MAC を引けないときは数発まで)送ることがあります。Linux の get_security_report と verify_security_findings は LAN に何も送らず、ゲートウェイはキャッシュを参照するだけです(get_guard_status など、ゲートウェイの MAC を引き直す別のツールは ping を1発送ることがあります)。
- 無償・オープンソース: MITライセンスで公開されており、誰でも自由にソースコードを確認・組み込めます。
パッケージマネージャーに1行追加
Package.swiftのdependenciesに追加するだけです。macOS 12+、Swift 5.9+、RoamSwitch 1.3.0以降のインストールが前提です。
dependencies: [
.package(url: "https://github.com/lafine1211/RoamSwitchKit.git", from: "1.0.0")
]
Cargo.tomlのdependenciesに追加するだけです。安定版Rust(2021 edition、tokio非同期ランタイム)、roamswitch-mcpバイナリを含むRoamSwitch for Linuxのインストールが前提です。
[dependencies]
roamswitch-linux-kit = { git = "https://github.com/lafine1211/roamswitch-linux-kit", tag = "v0.1.0" }
メソッドで診断結果を取得
import RoamSwitchKit
let client = try RoamSwitchClient()
let report = try await client.securityReport()
print(report.score, report.grade)
let ports = try await client.exposedPorts()
for port in ports.ports where port.overallRisk == "high" {
print(port.processName, port.port)
}
let status = try await client.guardStatus()
print(status.activeSecurityLevelLabel, status.isCurrentNetworkTrusted)
let urlReport = try await client.auditURLSafety(url: "https://apple.com.login-verify.xyz")
print(urlReport.score, urlReport.riskLevel) // e.g. 20, "dangerous"
use roamswitch_linux_kit::RoamSwitchClient;
let client = RoamSwitchClient::new(None, None)?;
let report = client.security_report().await?;
println!("{} ({})", report.score, report.grade);
let ports = client.exposed_ports(false).await?;
for port in ports.ports.iter().filter(|p| p.overall_risk.as_deref() == Some("high")) {
println!("{} {}", port.process_name, port.port);
}
let status = client.guard_status().await?;
println!("{} {}", status.active_security_level_label, status.is_current_network_trusted);
let url_report = client.audit_url_safety("https://apple.com.login-verify.xyz").await?;
println!("{} {}", url_report.score, url_report.risk_level); // e.g. 20, "dangerous"
読み取り専用のメソッド
securityReport()
FileVault・SIP・Gatekeeper・ファイアウォール・Wi-Fi暗号強度・ARPスプーフィング・外部公開ポートなど18項目を総合診断したスコアと改善アドバイスを取得します。
exposedPorts(includeLocalOnly:)
現在リッスン中の全ポートを一覧化し、外部公開されているものは既知の危険サービス(Redis/MongoDB等やOllama/LM Studio等のローカルAI推論サーバー)判定を含む詳細な監査結果を取得します。Mac では、公開ポートごとに 127.0.0.1 へ HTTP GET を1回送ってヘッダを確認します。
guardStatus()
未知ポート自動遮断・ARPスプーフィング自動対応・USBストレージガード・Bluetoothガード・Web/Mailダウンロード保護(Pickle AIモデル保護含む)・DNS脅威保護の有効状態と、現在の保護レベルを取得します。
auditURLSafety(url:)
不審なメールリンクや短縮URLを引数に取り、フィッシング詐欺・Unicodeホモグラフ偽装・有名ブランド偽装サブドメイン・高リスクTLDを完全端末内(Zero Telemetry)で高速解析・スコアリングします。
その他の読み取り専用メソッド
| メソッド | 概要 |
|---|---|
auditSecurityLogs(hours:) | 直近のセキュリティログ(Sudo認証失敗・SSH総当たり試行・Gatekeeper遮断・XProtect検知など)を集計し、APIキーやトークンなどの機密情報を自動マスキングした上で、ログパターンをテンプレート化した新規パターン検知・頻度異常(統計的スパイク)検知の結果も返します。Linux では、journal を読めなかったとき(タイムアウトなど)は、集計の 0 件を「何も起きていない」とせず、journalReadComplete が false になり、journalError に理由が入ります。 |
activeVulnScan() | 127.0.0.1 限定・非破壊の実証型脆弱性検証。外部ホストには接続しませんが、ネットワークリクエストを送るツールのため、既定は無効・設定でのオプトインが必要です。 |
packageCveScan() | インストール済みパッケージ(Mac: Homebrew / Linux: dpkg・dnf・zypper・pacman)をローカルのCVEマップと照合します。通信は一切行いません。Linux では、パッケージの一覧を取得できなかった・タイムアウトしたときは「該当なし」とせず、complete が false になり、incompleteReason に理由が入ります(完了できなかった結果は問題なしではありません)。 Linux の Ubuntu(20.04・22.04・24.04・26.04)では、Ubuntu 専用のデータで、ソースパッケージ名とソースの版を使い、Ubuntu が修正版を公開済みの CVSS 7.0 以上の CVE だけを照合します。そのため「該当なし」は、既知の CVE が無いという意味ではありません。結果には ecosystem と release が加わり、検知ごとに binary(導入済みのバイナリ名)が入ります。Ubuntu Pro でしか直らない修正には proOnly が付きます。Ubuntu の派生(Linux Mint、Pop!_OS など)と未対応の版は、complete が false になって incompleteReason に理由が入り、Debian のデータには切り替えません。 |
packageCveScanLanguages(watchedFolders:) | npm / PyPI / crates.io などの依存ロックファイルを、同じローカルCVEマップと照合します。通信は一切行いません。 |
canaryStatus() | ランサムウェア・カナリア(おとりファイル)の設置状況と、直近50件までの検知インシデントを返します。 |
portAnomalyIncidents() | ポート異常ガードのベースライン取得状況・自動遮断中のポート・直近50件までのインシデントを返します。 |
runtimeThreatStatus() | XProtectのマルウェア検知によるAir-Gap隔離の有無と、その発動元インシデントを返します。Air-Gapの理由を調べるなら最初に確認すべきツールです。 |
notificationHistory() | RoamSwitchが送信した通知(セキュリティログ監査の異常、ClickFix検知など)の履歴を、直近1週間ぶん・最新順で返します。 |
各戻り値の型定義(フィールド一覧)はGitHubのREADMEと AGENTS.md に、Swiftの型宣言そのままの形で掲載しています。
security_report()
LUKS/dm-cryptディスク暗号化・UEFI Secure Boot・AppArmor/SELinux・sudo/SSH設定・ARPスプーフィング・外部公開ポートなど27項目を総合診断したスコアと改善アドバイスを取得します。
exposed_ports(include_local_only)
現在リッスン中の全ポートを一覧化し、外部公開されているものは既知の危険サービス(Redis/MongoDB等やOllama/LM Studio等のローカルAI推論サーバー)判定を含む詳細な監査結果を取得します。Mac では、公開ポートごとに 127.0.0.1 へ HTTP GET を1回送ってヘッダを確認します。
guard_status()
未知ポート自動遮断・ARPスプーフィング自動対応・USBストレージガード・Bluetoothガード・Web/Mailダウンロード保護(Pickle AIモデル保護含む)・DNS脅威保護の有効状態と、現在の保護レベルを取得します。
audit_url_safety(url)
不審なメールリンクや短縮URLを引数に取り、フィッシング詐欺・Unicodeホモグラフ偽装・有名ブランド偽装サブドメイン・高リスクTLDを完全端末内(Zero Telemetry)で高速解析・スコアリングします。
その他の読み取り専用メソッド
| メソッド | 概要 |
|---|---|
server_security_report() | Server Edition の 34 項目プロファイル(カーネル強化・コンテナ隔離・カーネルCVE露出・eBPF LSM)で総合診断します。 |
run_active_vuln_scan() | 127.0.0.1 限定・非破壊の実証型脆弱性検証。外部ホストには接続しませんが、ネットワークリクエストを送るツールのため、既定は無効・設定でのオプトインが必要です。 |
audit_secrets(text) | テキスト・ファイル・ディレクトリからAPIキーや秘密鍵の漏洩を検出します(検出値はマスクして出力)。 |
audit_security_logs(hours) | 直近のセキュリティログ(Sudo認証失敗・SSH総当たり試行・Gatekeeper遮断・XProtect検知など)を集計し、APIキーやトークンなどの機密情報を自動マスキングした上で、ログパターンをテンプレート化した新規パターン検知・頻度異常(統計的スパイク)検知の結果も返します。Linux では、journal を読めなかったとき(タイムアウトなど)は、集計の 0 件を「何も起きていない」とせず、journalReadComplete が false になり、journalError に理由が入ります。 |
get_app_help(query, topic) | RoamSwitchの全機能仕様・内部動作・全通知メッセージ・トラブルシューティングを網羅した公式ナレッジを端末内で瞬時に検索し、的確な解説とアドバイスを返します。 |
quarantine_status() | マルウェア隔離Vaultの中身(元のパス・検出された脅威名・隔離日時・サイズ)を返します。 |
canary_status() | ランサムウェア・カナリア(おとりファイル)の設置状況と、直近50件までの検知インシデントを返します。 |
package_cve_scan() | インストール済みパッケージ(Mac: Homebrew / Linux: dpkg・dnf・zypper・pacman)をローカルのCVEマップと照合します。通信は一切行いません。Linux では、パッケージの一覧を取得できなかった・タイムアウトしたときは「該当なし」とせず、complete が false になり、incompleteReason に理由が入ります(完了できなかった結果は問題なしではありません)。 Linux の Ubuntu(20.04・22.04・24.04・26.04)では、Ubuntu 専用のデータで、ソースパッケージ名とソースの版を使い、Ubuntu が修正版を公開済みの CVSS 7.0 以上の CVE だけを照合します。そのため「該当なし」は、既知の CVE が無いという意味ではありません。結果には ecosystem と release が加わり、検知ごとに binary(導入済みのバイナリ名)が入ります。Ubuntu Pro でしか直らない修正には proOnly が付きます。Ubuntu の派生(Linux Mint、Pop!_OS など)と未対応の版は、complete が false になって incompleteReason に理由が入り、Debian のデータには切り替えません。 |
package_cve_scan_languages(watched_folders) | npm / PyPI / crates.io などの依存ロックファイルを、同じローカルCVEマップと照合します。通信は一切行いません。 |
verify_fim() | 約150箇所のクリティカルなシステムファイルを再ハッシュし、ベースラインと比較して改ざんを検証します。root で実行したときは、結果に追加のフィールド recentIntrusionContext も含まれます。直近の変更ごとに、変更したプロセス(アカウント・実行ファイル・コマンド)と、そのプロセスが属する SSH ログイン(接続元・ログイン時刻・認証方法)、または調べられなかった理由が入ります。 |
get_port_anomaly_incidents() | ポート異常ガードのベースライン取得状況・自動遮断中のポート・直近50件までのインシデントを返します。 |
get_ebpf_incidents() | eBPFランタイムガードの現在の隔離状態と、発動理由となったインシデント履歴を返します。Server Edition では、各記録に検知から対処までの時間(ミリ秒。detect_to_receive_ms、receive_to_action_ms、detect_to_action_ms)が加わり、結果には Falco のハートビートの状態(heartbeat)も含まれます。 |
SSH 総当たりガード(Server Edition と、sshd が動いている Client Edition)の状態と記録を返す get_ssh_guard_incidents() は、RoamSwitch 内部のクレート(roamswitchkit)にはありますが、公開している roamswitch-linux-kit への反映はこれからです。
各戻り値の型定義(フィールド一覧)はGitHubのREADMEに、Rustの型宣言そのままの形で掲載しています。
こんな組み込み方ができます
以下はSwift(Mac)での例です。roamswitch-linux-kit(Linux)でも同名のメソッド(snake_case)で同様に実装できます。
同期・バックアップアプリ
信頼できないネットワークに接続した際、バックグラウンド同期を一時停止する。
let status = try await client.guardStatus()
if !status.isCurrentNetworkTrusted {
syncEngine.pauseBackgroundSync()
}
パスワードマネージャー
未信頼ネットワークでは自動ロックまでの時間を短縮するなど、保護レベルに応じて挙動を変える。
let status = try await client.guardStatus() let lockTimeout: TimeInterval = status.isCurrentNetworkTrusted ? 300 : 30 vault.setAutoLockTimeout(lockTimeout)
開発者向けツール・自動化
開発サーバーやローカルAI推論サーバー(Ollama/LM Studio等)が0.0.0.0で待受を始めた際に警告する、Shortcuts等でネットワーク信頼度に応じたワークフローを組む。
let ports = try await client.exposedPorts(includeLocalOnly: false)
for port in ports.ports where [3000, 5173, 8000, 11434, 1234].contains(port.port) {
print("⚠️ Dev/AI server exposed on port \(port.port)")
}
メール・チャットアプリでのリンク事前チェック
受信したメッセージ内のリンクを表示前に自動スキャンし、危険なものだけを警告表示する。
let result = try await client.auditURLSafety(url: link)
if result.riskLevel == "dangerous" || result.riskLevel == "suspicious" {
showWarningBanner(for: link, score: result.score)
}
右クリックメニュー・Shortcutsでの安全性チェック
Finderの「サービス」メニューやmacOS Shortcutsに組み込み、コピーしたURLをワンアクションで検査する。
// macOS Shortcuts (App Intent) や Services メニューのハンドラから呼び出す
let report = try await client.auditURLSafety(url: pasteboardURL)
return "\(report.riskLevel.uppercased()) (\(report.score)/100)"
IT資産管理・MDMダッシュボード
社内の複数Macからスコアを収集し、管理者向けダッシュボードで一覧・アラート化する。
let report = try await client.securityReport() try await mdmAPI.reportScore(deviceID: deviceID, score: report.score, grade: report.grade)
SDKについて
Q. 無料で使えますか?
A. はい。RoamSwitchKit(Mac)とroamswitch-linux-kit(Linux)はどちらもMITライセンスで無償公開しています。RoamSwitch本体(診断エンジン)のインストールが前提ですが、SDK自体に費用はかかりません。
Q. ユーザーの設定を変更できますか?
A. いいえ。読み取り専用で、ロックダウン切替やポート隔離などの操作系APIは一切実装されていません。組み込んだアプリがユーザーの許可なくRoamSwitchの保護設定を変更することはできません。
Q. RoamSwitchがインストールされていない場合は?
A. 対応するエラー(Mac: RoamSwitchClientError.appNotInstalled / Linux: RoamSwitchClientError::AppNotInstalled)が返されます。この場合は機能を非表示にするなど、穏やかに処理することを推奨しています。
Q. 自社製品にRoamSwitch本体を同梱・再配布したい場合は?
A. SDK連携(本ページの内容)は無償のままご自由にお使いいただけますが、RoamSwitch本体の同梱・再配布にはOEMライセンスが必要です。OEM・パートナー連携についてはこちらからご相談ください。