PassTunnel

io.github.PassTunnel由 GitHub 帳號 PassTunnel 發布v1.7.0更新於 Oct 31, 2026

macOS OpenVPN/FortiGate VPN status, logs and diagnosis; read-only by default, never returns secrets

概覽

AI 產生的概覽

讓助理檢視 macOS 上 OpenVPN、FortiGate、Cisco AnyConnect 與 GlobalProtect 的 VPN 設定、狀態、日誌與診斷,預設為唯讀。

可以做什麼
  • 列出 VPN 設定檔及其類型、狀態、是否需要 Touch ID、自動重連與登入時連線設定
  • 讀取連線狀態:通道 IP、連線時間、最近錯誤與原因、輔助程式狀態
  • 讀取最近的 VPN 日誌內容或活動日誌,疑似憑證的內容會被遮蔽
  • 執行診斷:應用程式版本與位置、輔助程式狀態、內建工具能否啟動、網路狀況、各設定檔是否就緒及時鐘偏差
  • 僅在以 --allow-connect 啟動時連線或中斷設定檔
適用情境
適合透過 PassTunnel macOS 應用程式管理 VPN 的使用者,讓助理回答通道是否連通、依日誌說明連線失敗原因,或在聯絡 IT 前檢查設定與時鐘問題。
執行需求
本機 stdio 程序,由 passtunnel 命令列工具啟動,該工具來自 PassTunnel macOS 應用程式(macOS 13 以上、Apple 晶片;Cisco AnyConnect 與 GlobalProtect 設定檔需 macOS 15.4 以上)。需已安裝應用程式及其特權輔助程式;未宣告任何 API 金鑰或環境變數。
安裝前請注意
預設唯讀;以 --allow-connect 啟動後助理可連線與中斷 VPN 設定檔,要求 Touch ID 的設定檔仍會跳出確認。日誌與診斷內容經過遮蔽,伺服器不會提供密碼、密鑰或一次性驗證碼。帶 check_clock 的診斷會聯絡 Apple 的時間伺服器。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 PassTunnel,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

PassTunnel

Connect your VPN without ever typing a one-time code again.

PassTunnel is an open-source macOS app for OpenVPN, FortiGate SSL VPN, Cisco AnyConnect and Palo Alto GlobalProtect (experimental). It keeps your TOTP secret in the Keychain and fills in the current code (and your password) every time you connect.

[macOS 13+] [License: MIT] [Swift 5.10] [CI] [OpenSSF Scorecard] [OpenSSF Best Practices] [OpenSSF Baseline]

[PassTunnel main window: a sidebar of VPN profiles with their state and live code, and the selected profile with its current code, what the server receives and its activity]

Website · Features · Install · Quick start · Code format · Cisco AnyConnect · Palo Alto GlobalProtect · CLI · AI assistants · FAQ · Security · Project · Türkçe


Features

One-time codes, handled

  • No more typing codes. The TOTP secret lives in the macOS Keychain; PassTunnel generates the code and sends it with your password when you click Connect. If 5 seconds or less are left in the current window, it waits for a fresh code instead of racing the clock (a setting, on by default). A code that was already sent is never sent again.
  • Any format your server expects. Append, prepend, password:code, password,code, or a custom template with any literal text, or send the code separately (OpenVPN static challenge, FortiGate OTP field, Cisco AnyConnect's second password field). See Configuring the code format.
  • Authenticator-style main window. The sidebar lists every profile with its state and live code; the selected one shows its code in large digits with a countdown ring, and what the server receives. Click the code to copy; the clipboard is cleared again after 1 minute (or 30 seconds, or 2 minutes, in Settings), unless you copied something else meanwhile. Codes can be hidden until you click them.
  • QR import. Drop a screenshot of your provider's QR code, choose an image or paste from the clipboard, or (macOS 14 and later) scan the QR code where it is on screen, for example in your browser, without saving a screenshot. Digits, period and algorithm (SHA-1/256/512) are read from the otpauth:// link. Pasting a Base32 secret or an otpauth:// link works too.
  • Auto-type (optional, off by default). With global shortcuts on, ⌃⌥C types the current code into the focused field (also in the menu bar panel), for web portals and other places that still ask for it. Needs Accessibility permission, which is only requested when you turn the feature on.
  • Confirm with Touch ID (optional, per profile). Touch ID or your Mac password before connecting and before showing codes (the command line can also set it to ask before connecting only); the saved secrets are then encrypted with a key in the Mac's Secure Enclave, so a one-click connect needs you, not just your unlocked Mac.

VPN client

  • OpenVPN, FortiGate SSL VPN, Cisco AnyConnect and Palo Alto GlobalProtect (experimental), using bundled, signed copies of openvpn, openfortivpn and openconnect. Nothing else to install. Cisco AnyConnect and Palo Alto GlobalProtect (password and one-time code) need macOS 15.4 or later; see Cisco AnyConnect and Palo Alto GlobalProtect.
  • Menu bar panel. Every pinned or active profile with its state, live code and a switch to connect or disconnect, plus copy and type for the current code. A colored badge (five palettes) marks a profile that needs attention, with a red dot when a connection dropped unexpectedly.
  • Stays connected. Optional auto-reconnect with backoff, a health check host inside the VPN, reconnect after wake, chosen profiles connected at login, and a reminder before a server-side session limit runs out.
  • Several VPNs at once, each with its own status, log and settings.
  • Shareable profiles. Export a .passtunnel file for your team. It never contains passwords, TOTP secrets or user names.
  • Command-line tool. passtunnel connect, passtunnel code -c, --json output, stable exit codes and shell completions: the same features as the app.
  • Works with AI assistants. passtunnel mcp is an MCP server, so Claude Code, Claude Desktop and other MCP clients can check your VPNs, read logs and diagnose problems. Read-only unless you allow connecting, and it never hands out passwords, secrets or codes.
  • No sudoers rule, no admin password at every connect. A small privileged helper, registered through macOS's own SMAppService and approved once, runs only the VPN tools signed and shipped inside the app, with sanitized configurations. See SECURITY.md.
  • English and Turkish user interface (follows your macOS language).

How it works

PassTunnel.app ──XPC──▶ PassTunnelHelper (root) ──▶ bundled openvpn / openfortivpn / openconnect  │  (code-signature checked)                             │  ├─ Keychain: password + TOTP secret                     └─ management socket (OpenVPN),  └─ ~/Library/Application Support/PassTunnel                log file, status ──▶ back to the app
  1. You click Connect. The app reads your password and TOTP secret from the Keychain, computes the current code and builds what the server expects (for example secret123456).
  2. The app hands the request to the privileged helper over XPC. The helper accepts only the signed PassTunnel app, checks that the profile folder belongs to you, sanitizes the OpenVPN config (or writes the openfortivpn config itself from typed fields) and starts the bundled tool, which it lets run only after checking the signature of the code that was actually loaded. For Cisco AnyConnect, the app signs in first (as you, not as root) and hands the helper only the resulting session cookie, which the helper uses to build the openconnect configuration itself.
  3. The app follows the connection state (OpenVPN through a management socket that only your user can open, FortiGate and Cisco AnyConnect through the log) and shows it in the window and the menu bar.

The full security model, including what is not protected, is in SECURITY.md. The code layout is described in docs/ARCHITECTURE.md.

Install

Requires macOS 13 Ventura or later on a Mac with Apple silicon. Cisco AnyConnect and Palo Alto GlobalProtect profiles need macOS 15.4 or later; on an older macOS the rest of the app works as usual.

Download

Download the disk image, open it and drag PassTunnel to Applications. Launch it from there: the helper can only be installed from the Applications folder. The app is signed with a Developer ID and notarized by Apple. What changed is in the release notes.

PassTunnel keeps itself up to date (Settings → Updates); updates are signed and checked before they are installed. After an update, the helper is updated automatically as soon as no VPN connection is active (only when PassTunnel runs from the Applications folder).

Homebrew

sh
brew trust passtunnel/tapbrew install --cask passtunnel/tap/passtunnel

Since Homebrew 6, casks from third-party taps load only once you trust the tap, hence the first line. The cask also links the passtunnel command. Updates arrive through the app itself, so brew upgrade leaves it alone unless you run brew upgrade --greedy.

Build from source

You need Xcode 15.3 or later (Swift 5.10, plus xcstringstool for the Turkish strings) and Homebrew, which provides the VPN tools that get bundled into the app:

sh
brew install openvpn openfortivpn openconnectgit clone https://github.com/passtunnel/passtunnel.gitcd passtunnelscripts/build-app.sh                  # → build/PassTunnel.app (ad-hoc signed)

build-app.sh builds a release binary, assembles the bundle, copies openvpn, openfortivpn, openconnect (Cisco AnyConnect, Palo Alto GlobalProtect) and their libraries in (scripts/bundle-tools.sh, with their license files), compiles the helper with the code-signature hashes of exactly these tools and libraries, and signs everything inside-out with the hardened runtime. An ad-hoc build signs the app without library validation: an ad-hoc signature has no Team ID, so macOS would otherwise refuse to load Sparkle.framework into it.

[!IMPORTANT] The helper only talks to an app, and only runs tools, signed with the project's Developer ID Team ID. An ad-hoc build is fine for the window, codes, QR import, profiles and the CLI, but cannot connect. To connect with your own build, set teamID in Sources/PassTunnelShared/Identifiers.swift to your Team ID and sign with your certificate:

sh
scripts/build-app.sh --sign "Developer ID Application: Your Name (TEAMID)"

Then move build/PassTunnel.app to /Applications before installing the helper.

Quick start

Without any profile, the window opens on Add your first VPN:

  1. Install the helper. The card at the bottom explains what it is for. Click Install Helper, then turn PassTunnel on in System Settings → General → Login Items (macOS asks once). You can also do this later from Settings → Helper.
  2. Add a VPN. Drop a file on the dashed area, or pick one of the other ways in.

[First run: Add your first VPN, with a drop area for .passtunnel and .ovpn files, three ways to add a profile and an Install the helper card]

Add a profile

Click + at the bottom of the sidebar (the same view, titled Add a VPN), or drop a file onto the window. The File menu has the same items:

You have…Do this
An OpenVPN file (.ovpn / .conf)Drop it on the dashed area or Choose File… (File → Import .ovpn…). You see a review of what is in the file before anything is saved; files it references (ca ca.crt, tls-auth ta.key 1, …) are embedded automatically.
A FortiGate gatewayEnter details by hand, choose FortiGate (File → New FortiGate Profile…), then enter host and port and Fetch fingerprint to pin the gateway certificate (SHA-256).
A .passtunnel file from a colleagueDouble-click it (or open it from AirDrop), or drop it on the window. Then add your own user name, password and TOTP secret.
A Cisco AnyConnect serverEnter details by hand, choose Cisco AnyConnect (File → New Cisco AnyConnect Profile…), then paste the address your IT team gave you, for example https://vpn.example.com/staff. See Cisco AnyConnect.
A Palo Alto GlobalProtect portal (experimental)Enter details by hand, choose Palo Alto GlobalProtect (File → New Palo Alto GlobalProtect Profile (Experimental)…), then enter the portal's address, for example vpn.example.com. See Palo Alto GlobalProtect.
A QR code for your authenticatorScan a QR code on screen (macOS 14 and later) or Use a QR image, or drop the screenshot onto the window or the editor.

Then open the profile editor (Edit in the toolbar):

  • First card (no heading): name, user name (leave empty to be asked each time) and password, saved in the Keychain. Under Advanced the password can be asked each time instead, or not used (certificate-only OpenVPN).
  • One-time code: Scan QR on screen (macOS 14 and later), choose the QR code image or paste the secret (or drop the screenshot on the card), and compare the live code with your phone before saving. Code format sets how the code is sent; Server receives shows the result, with the password masked. Under Advanced the code can be asked each time or not used.

[Profile editor: name, configuration, user name and password; the one-time code with its live code; the Append format and what the server receives, with the password masked; switches for Touch ID and reconnecting]

Secrets are written to the Keychain only when you press Save.

Connect

Click Connect. If the profile needs something that is not stored (for example, a password set to Ask each time), a small sheet asks for just that, with the code already filled in.

Select a profile in the sidebar and click Connect; a failure explains what went wrong and offers Try again. The menu bar panel does the same from anywhere: a switch per pinned or active profile, with its live code, and copy items for the current code (Type code too while auto-type is on):

[Menu bar panel, light: three profiles with state, code and a switch, then copy, open, settings and quit items]   [Menu bar panel, dark]

Optional global shortcuts (Settings → Shortcuts, off by default): ⌃⌥V connects or disconnects the default profile, ⌃⌥C copies the current code, or types it when auto-type is on.

[Settings, General: open at login, Dock icon, hide codes, clear copied code, connection and notification options, Touch ID timeout, appearance, command-line tool]

Configuring the code format

Servers disagree on how the one-time code should arrive. Choose it per profile in the editor's Code format popup.

With the password (Append, Prepend, password:code, password,code, Custom template): the code and password are joined into one password using a template. {password} and {otp} are replaced; any other text is sent as typed. The template must contain {otp}; {password} is optional.

With the password secret and the code 123456:

FormatTemplateSent as password
Append (default){password}{otp}secret123456
Prepend{otp}{password}123456secret
Password:code{password}:{otp}secret:123456
Password,code{password},{otp}secret,123456
Custom{password}#{otp}secret#123456
Custom (code only){otp}123456

Sent separately: the password and the code are sent on their own:

  • OpenVPN: as a static-challenge response (SCRV1:…). PassTunnel selects this automatically when the imported .ovpn contains static-challenge.
  • FortiGate: in openfortivpn's separate OTP field. This is the default for new FortiGate profiles.
  • Cisco AnyConnect: as the answer to the server's second password field. This is the default for new Cisco AnyConnect profiles; for a server that wants one field, choose a format that joins them.

As you change the format, the editor's Server receives shows the result with the profile's user name and the live code; the password is always masked.

Cisco AnyConnect

PassTunnel connects to servers that speak the Cisco AnyConnect protocol through the bundled openconnect, with a user name, a password and, if the server asks for one, a one-time code. It needs macOS 15.4 or later; the rest of the app still runs on macOS 13.

Add a profile. Click +, choose Enter details by hand, then Cisco AnyConnect (or File → New Cisco AnyConnect Profile…). In Server, paste the address as your IT team gave it, https://vpn.example.com[:port][/group]; PassTunnel fills in the host, port and user group from it. Group is the group the server offers at sign-in; leave it empty for the server's default. Add the user name and password, and the TOTP secret as for any other profile. Under Advanced, the profile can also ask for the password each time, or use TLS only (no DTLS).

The one-time code is sent as the answer to the server's second password field by default, which is what most AnyConnect servers ask for. If yours wants the code inside the password, choose Append, Prepend or a custom template in Code format (see above).

Trust the server. If the server's certificate is signed by an authority your Mac trusts, there is nothing to do. For a self-signed certificate or a private authority, Fetch Fingerprint in the editor reads the server's key and asks whether to trust it; compare the fingerprint with the one your IT team published first. Without it, the first connect stops at Server not trusted with the key shown and a Trust This Server… button that asks the same question. PassTunnel then saves only that key (pin-sha256:…) in the profile and accepts no other key from that server; if the server later presents a different one, it warns instead of connecting.

Not supported:

  • Sign-in through a web browser (SAML / single sign-on).
  • Host scan: Cisco Secure Desktop, HIP and TNCC. PassTunnel never runs it; the connect stops at Host scan required. Ask your IT team whether your account can sign in without it.
  • Client certificates and RSA SecurID tokens.
  • A server that sends you to a different host after the sign-in.

On the network. The server's routes and DNS servers are applied when the tunnel comes up and removed when it ends. Local networks stay local: a route from the server that lies inside a network your Mac is attached to (your home or office LAN) is skipped, so a server cannot take over part of it. When all traffic goes through the tunnel and the server assigns no IPv6 address, IPv6 is blocked so that it cannot bypass the tunnel.

On a Mac with macOS 13 to 15.3, Cisco AnyConnect is shown in the type list as Requires macOS 15.4 or later. An existing or imported profile is listed with the same note and can still be shared or deleted. On Linux, passtunneld uses the distribution's openconnect 9.01 or later (Ubuntu 22.04's 8.20 is too old); see docs/LINUX.md.

The command line has the same: passtunnel add --type anyconnect below.

Palo Alto GlobalProtect (experimental)

Experimental. GlobalProtect has only been tested against openconnect's own test server, not against real gateways. It connects exactly as designed, but please tell us how it works for you, whether it worked or not: that is how the label goes away.

PassTunnel connects to Palo Alto GlobalProtect through the bundled openconnect, with a user name, a password and, if the portal or gateway asks for one, a one-time code. It needs macOS 15.4 or later; the rest of the app still runs on macOS 13.

Add a profile. Click +, choose Enter details by hand, then Palo Alto GlobalProtect (or File → New Palo Alto GlobalProtect Profile (Experimental)…). In Server, enter the portal's address as your IT team gave it, [https://]host[:port] without a path (for example vpn.example.com). A portal usually names a gateway; if it lists several, the first connect stops at Choose a gateway and lists them, or set Gateway in the profile. Skip the portal signs in to one gateway directly. Add the user name and password, and the TOTP secret as for any other profile. Under Advanced, Use TLS only turns off ESP (the UDP tunnel) so the tunnel runs over HTTPS only.

The one-time code is answered to the portal or gateway that asks for it. When both ask and the portal gives no cookie to spare the second sign-in, PassTunnel waits for the next time window and answers the gateway with that code, so the same code is never sent twice. If your server wants the code inside the password, choose Append, Prepend or a custom template in Code format (see above).

Trust the server. As for Cisco AnyConnect, a certificate signed by an authority your Mac trusts needs nothing. Otherwise Fetch Fingerprint pins the portal's key, and the gateway, which is often another host, is pinned with Trust This Gateway… on the failure card (it shows the gateway's key, and the portal's if none is pinned yet, and asks first). Compare the fingerprints with the ones your IT team published.

Not supported:

  • Sign-in through a web browser (SAML / single sign-on). The connect stops at Single sign-on required before anything is sent.
  • Host information profile (HIP). PassTunnel never runs a HIP script. The connection goes on without a report, and the gateway may limit what you can reach or end the session; PassTunnel shows a notice that access may be limited. Ask your IT team if that happens.
  • Client certificates.
  • Pulse/Ivanti and other types (see the roadmap).

On the network. The gateway's routes and DNS are applied when the tunnel comes up and removed when it ends, with the same rules as Cisco AnyConnect: routes inside a network your Mac is attached to stay local, and IPv6 is blocked in a full tunnel when the gateway assigns no IPv6 address.

On a Mac with macOS 13 to 15.3, the type is shown as Requires macOS 15.4 or later; existing profiles can be shared and deleted but not connected. On Linux, passtunneld uses the distribution's openconnect 9.11 or later for GlobalProtect (9.01 or later for Cisco AnyConnect); see docs/LINUX.md. The command line has the same: passtunnel add --type globalprotect below.

Command line

Install the passtunnel command from Settings → General → Command-line tool. It is a symlink to the app binary in /usr/local/bin, or in ~/.local/bin if that folder is not writable. Profile IDs are derived from the profile name (Work → work).

sh
passtunnel                          # status of all profilespasstunnel connect                  # connect the default profilepasstunnel connect work             # connect a specific profilepasstunnel code work -c             # print the live code and seconds left, copy it (for 1 min by default)passtunnel status work --json       # exit code 3 when not connectedpasstunnel disconnect --all
passtunnel import ~/Downloads/work.ovpn --name Workpasstunnel secret work password     # prompts without echopbpaste | passtunnel secret work totp      # Base32 secret or otpauth:// link from stdinpasstunnel set work otp_mode=totp otp_template=prependpasstunnel set work otp_template='{password}:{otp}'passtunnel set work auto_reconnect=true health_host=10.0.0.1
passtunnel add Lab --type fortipasstunnel set lab host=203.0.113.10 port=443 username=sam
passtunnel add Corp --type anyconnect --server https://vpn.example.com/staff   # Cisco AnyConnect, macOS 15.4 or laterpasstunnel set corp username=sam authgroup=Employeespasstunnel set corp server_cert=pin-sha256:…    # trust the server's key (compare it first)
passtunnel add Gp --type globalprotect --server vpn.example.com   # Palo Alto GlobalProtect (experimental), macOS 15.4 or laterpasstunnel set gp username=sam gateway=Gateway1
passtunnel log work -fpasstunnel log work --activity                # what PassTunnel did: connecting, codes, sign-in, dropspasstunnel helper statuspasstunnel diagnose --check-clock             # what would stop a connect; is the clock off?passtunnel completion zsh > ~/.zfunc/_passtunnel

passtunnel set ID key=value… accepts the same settings as the editor; passtunnel help set lists the keys and passtunnel help lists all commands.

For scripts: every command takes --json (results on stdout, errors as {"error":{"code":…,"message":…}}), --no-input (never ask on the terminal; also PASSTUNNEL_NO_INPUT=1) and --no-auth-prompt (fail instead of showing Touch ID); connect --wait --timeout 90 bounds the wait. Exit codes: 0 ok, 1 error, 2 usage, 3 not found or not connected, 4 confirmation cancelled or not possible, 5 helper missing or outdated, 6 connection failed, 7 timeout. The objects and codes are described in docs/CLI-JSON.md.

sh
passtunnel connect work --timeout 90 --no-input --jsonpasstunnel status --json | jq '.[] | select(.state == "connected") | .id'

Use with AI assistants (MCP)

passtunnel mcp runs a Model Context Protocol server on standard input and output, so an AI assistant can answer “is my VPN up?”, read the log of a failed connection and tell you what is wrong.

[Install in Cursor] [Install in VS Code]

[passtunnel MCP server – quality and maintenance score on Glama] [Listed on mcpservers.org]

ToolWhat it does
list_profilesProfiles with type, state, whether connecting asks for Touch ID, auto-reconnect, connect at login
get_statusState, tunnel IP, since when, last error and why (sign-in rejected, server unreachable or not found, …; whether the sign-in was sent); whether the helper is installed and current
get_logsThe last lines (up to 500) of a profile's VPN log, with anything that looks like a credential redacted; with source: "activity", what PassTunnel did instead (connecting, code waits, sign-in accepted or rejected, drops), without passwords or code digits
diagnoseApp version and location, helper state, whether each bundled VPN tool starts on this macOS version (run with --version), whether the Mac is online and over what network (the system's own view, nothing is contacted), and per profile whether config, server and saved credentials are in place and the last clock measurement; with check_clock, also asks Apple's time server how far the clock is off
connect, disconnectOnly with --allow-connect

Read-only by default. Without --allow-connect the assistant can look, not act. With it, it can connect and disconnect profiles; a profile with Confirm with Touch ID still shows the Touch ID prompt on your Mac, and nothing happens until you confirm. There is no tool for codes, passwords or secrets, and none that creates, changes or deletes profiles. The server gets the same access as the passtunnel command; see SECURITY.md for what that means, including prompt injection.

Claude Code (uses your shell's PATH; the passtunnel command comes with the Homebrew cask, or from Settings → General → Command-line tool):

sh
claude mcp add passtunnel -- passtunnel mcp                   # read-onlyclaude mcp add passtunnel -- passtunnel mcp --allow-connect   # may also connect and disconnect

Without the passtunnel command, use the app binary directly:

sh
claude mcp add passtunnel -- /Applications/PassTunnel.app/Contents/MacOS/PassTunnel mcp

Claude Desktop: download PassTunnel-mcp-<version>.mcpb from the latest release and double-click it; Claude Desktop opens the MCP bundle and installs it. Its setting Allow connect and disconnect (off by default) adds --allow-connect. The bundle holds only a launcher for the server built into the app, so PassTunnel must be installed in /Applications; without it the server stops with an install hint. The same bundle is the package of PassTunnel's MCP Registry entry, io.github.PassTunnel/passtunnel.

Or configure it by hand. Claude Desktop starts servers without your shell's PATH, so give the full path. In ~/Library/Application Support/Claude/claude_desktop_config.json:

json
{  "mcpServers": {    "passtunnel": {      "command": "/Applications/PassTunnel.app/Contents/MacOS/PassTunnel",      "args": ["mcp"]    }  }}

The Cursor and VS Code buttons above add the same read-only entry. Add "--allow-connect" to args to allow connecting. Other MCP clients work the same way: the command is the app binary (or passtunnel), the argument mcp. Diagnostics go to stderr. The server speaks MCP 2026-07-28 and, for clients that start with an initialize handshake, 2025-11-25 back to 2024-11-05.

Sharing profiles

⋯ → Share… (or passtunnel export work -o work.passtunnel) writes a .passtunnel file with the connection settings, appearance, code format and, for OpenVPN, the configuration file.

It never contains your password, your TOTP secret or your user name; a user name and password or proxy credentials embedded in the OpenVPN configuration are removed too. The recipient double-clicks it (or opens it from AirDrop) and adds their own. The embedded OpenVPN configuration can contain certificates and keys, so the file is written with 0600 permissions; share it the way you would share the .ovpn itself.

FAQ

Why does PassTunnel need a privileged helper?

Creating a tunnel interface and changing routes and DNS requires root. Instead of asking for your admin password at every connect or adding a sudoers rule, PassTunnel registers a small launchd daemon with SMAppService, which you approve once in System Settings → General → Login Items. The helper accepts requests only from the signed PassTunnel app, only runs the openvpn, openfortivpn and openconnect that come with it (from a root-owned copy, together with their libraries), lets them run only after checking their signature, and rejects dangerous OpenVPN directives. Details in SECURITY.md.

Where are my password and TOTP secret stored?

In your login Keychain, as generic passwords with the service name PassTunnel (accounts <profile-id>/password and <profile-id>/totp). They do not sync to iCloud Keychain; Migration Assistant and backups carry them to a new Mac like the rest of your login keychain. A user name and password embedded in an imported .ovpn are moved there too. Profile settings and OpenVPN configurations are in ~/Library/Application Support/PassTunnel/, readable only by your user. Nothing is sent anywhere except to your VPN server.

Which VPN types are supported?

OpenVPN (OpenVPN 2.x client configurations: user/password, certificate-only and static-challenge setups), FortiGate SSL VPN (through openfortivpn) and Cisco AnyConnect (through openconnect, with a password and a one-time code; macOS 15.4 or later) and Palo Alto GlobalProtect (experimental, also through openconnect, with a password and a one-time code; macOS 15.4 or later; please report how it works). Pulse/Ivanti is on the roadmap. Other types can be added as new backends; see Contributing.

Why is Cisco AnyConnect or Palo Alto GlobalProtect greyed out?

The bundled openconnect needs macOS 15.4 or later, so on an older macOS the type is shown as Requires macOS 15.4 or later and a Cisco AnyConnect or GlobalProtect profile can be listed, shared and deleted but not connected or edited. PassTunnel itself still runs on macOS 13, with OpenVPN and FortiGate as usual.

My Cisco AnyConnect server asks me to sign in in a browser, or reports a host scan.

PassTunnel signs in with a user name, password and one-time code only. Sign-in through a web page (SAML / single sign-on) is not supported, and neither is the server's host scan (Cisco Secure Desktop, HIP, TNCC): PassTunnel never downloads or runs it, stops the connection and shows Host scan required. Ask your IT team whether your account can sign in with a password and code, or whether another group on the server skips the host scan (the profile's Group).

My GlobalProtect portal asks for a browser sign-in, or the connection says access may be limited.

PassTunnel signs in with a user name, password and one-time code only. A portal or gateway that signs in through a web page (SAML / single sign-on) is refused before anything is sent (Single sign-on required). When the gateway asks for a host information report (HIP), PassTunnel never sends one: the connection goes on, the gateway may limit what you can reach, and the window says so. Ask your IT team whether your account can sign in with a password and code and without the report. GlobalProtect is experimental, so a report of what you saw helps.

My .ovpn file is rejected. Why?

The helper runs OpenVPN as root, so it refuses directives that would run scripts, load plugins, or read and write arbitrary files. When you import a file, lines whose only effect PassTunnel takes care of itself (scripts such as up and down with script-security 2, log, management, daemon, …) are skipped: you see them before the profile is added, and they stay in the saved configuration as comments. Lines with a role in security (tls-verify, plugin, config, a ca file that is not next to the .ovpn, …) still refuse the file, and the error lists every one. Files referenced at import time are embedded automatically. The complete lists are in SECURITY.md.

My .p12 certificate does not load ("unsupported", "RC2-40-CBC"). Why?

Older PKCS#12 files are encrypted with RC2, which OpenSSL 3 and 4 only read through their legacy provider. PassTunnel's OpenVPN loads no OpenSSL providers or modules (they would come from paths outside the app), so such a file cannot be used as it is. Re-export it once with modern encryption, using OpenSSL 3 (for example Homebrew's, brew install openssl@3; macOS's own /usr/bin/openssl is LibreSSL and has no -legacy option):

sh
OPENSSL="$(brew --prefix openssl@3)/bin/openssl""$OPENSSL" pkcs12 -legacy -in old.p12 -nodes -out temp.pem   # asks for the old password"$OPENSSL" pkcs12 -export -in temp.pem -out new.p12          # asks for a new passwordrm temp.pem                                                  # holds the unencrypted key

Then use new.p12 in the configuration (or import the .ovpn again so it is embedded).

Does it work without a TOTP code?

Yes. Set the one-time code to None for a plain user/password or certificate-only VPN, or to Ask each time if you use a hardware token or SMS.

How do I uninstall PassTunnel completely?
  1. Disconnect all profiles.

  2. Remove the helper: Settings → Helper → Remove Helper…, or passtunnel helper uninstall. Do this before deleting the app.

  3. Turn off launch at login: Settings → General → Open at login, in the menu bar. Check that nothing is left under System Settings → General → Login Items.

  4. Quit PassTunnel and move PassTunnel.app to the Trash.

  5. Delete your data:

    sh
    rm -rf ~/Library/Application\ Support/PassTunnel     # profiles, configs, logs, preferencesdefaults delete com.furkanprlk.passtunnel 2>/dev/null # open-at-login questionrm -f /usr/local/bin/passtunnel ~/.local/bin/passtunnel   # CLI symlink, if installed
  6. Delete the Keychain items: open Keychain Access and search for PassTunnel, or run

    sh
    while security delete-generic-password -s PassTunnel >/dev/null 2>&1; do :; done

    (Deleting a profile inside the app also removes its Keychain items.)

With Homebrew, brew uninstall --zap --cask passtunnel also deletes your data and the Keychain items (steps 5 and 6). A plain brew uninstall --cask passtunnel keeps both.

The helper's runtime folder /var/run/passtunnel is root-owned and cleared at restart.

Building and testing

sh
swift build                 # debug build of the app, CLI and helperswift test                  # unit testsscripts/build-app.sh        # full app bundle in build/PassTunnel.app
# The portable library (PassTunnelKit) for iOSxcodebuild -scheme PassTunnelKit -destination 'generic/platform=iOS Simulator' build

Releases (signing, notarization, the Sparkle feed and the Homebrew cask) are described in docs/RELEASING.md.

Tests never touch your real data: they point PASSTUNNEL_HOME at a temporary folder and use a throwaway Keychain service via PASSTUNNEL_KEYCHAIN_SERVICE.

Screenshots. The app can render its main screens to PNG files offscreen, with sample profiles, a temporary support folder and a temporary Keychain service. Nothing is shown on screen and no VPN, helper or system setting is touched:

sh
swift buildPASSTUNNEL_RENDER=/tmp/passtunnel-shots "$(swift build --show-bin-path)/PassTunnel"

This writes the main window (light/dark, first run, every profile state, hidden and locked codes, the import review, the error states), the credential sheet, the menu bar panel, the status item's badges for every palette, every Settings tab, the profile editor states and the design system's tokens and components. The images in docs/images come from it.

Contributing

Issues and pull requests are welcome. Please open an issue first for larger changes.

Work happens on dev: one branch per issue, a pull request into dev with a Conventional Commits title (feat: …, fix: …), squash-merged. Merging dev into main releases. The workflow, title rules and checks are in CONTRIBUTING.md.

  • Read docs/ARCHITECTURE.md (targets, storage, helper protocol, security rules) and docs/APP.md (app and CLI behavior).
  • Adding a VPN type means adding a backend: a new VPNType case, the profile fields it needs, a helper request whose configuration is rendered from typed fields or strictly validated, a tool bundled and signature-checked like openvpn/openfortivpn, and state tracking in ConnectionManager. Never let the helper run a client-supplied path or raw config.
  • User-facing strings go through String(localized:) with a Turkish translation in Sources/PassTunnel/Resources/Localizable.xcstrings.
  • A change to behavior the phone apps share (codes, otpauth links, OpenVPN configs, share files, slugs, profile merging) updates the golden cases in fixtures/ too.
  • No third-party Swift dependencies besides Sparkle (updates) and swift-crypto (CryptoKit's API on Linux). Run swift test before sending a PR.

Project

PassTunnel is maintained by one person, in the open.

  • GOVERNANCE.md: how decisions are made, who does what, who holds which access, and the current bus factor.
  • ROADMAP.md: what is planned for the next year, and what is not.
  • CODE_OF_CONDUCT.md: the Contributor Covenant, and how to report conduct problems.
  • SECURITY.md: what is protected and what is not, supported versions, how to report a vulnerability and how reports are handled, and the cryptography used.
  • docs/ASSURANCE.md: the assurance case (threat model, trust boundaries, design principles, weaknesses countered).
  • CONTRIBUTING.md: the workflow, coding standards, test policy and how to report bugs.

License

PassTunnel is released under the MIT License. Copyright © 2026 Furkanprlk.

The app bundles openvpn (GPL-2.0), openfortivpn (GPL-3.0) and their libraries (OpenSSL, LZO, LZ4, pkcs11-helper), and openconnect (LGPL-2.1) with its libraries (GnuTLS, nettle, GMP and others, mostly LGPL). They are separate programs distributed alongside PassTunnel under their own licenses. See THIRD_PARTY_NOTICES.md. Their full license texts are inside the app in Contents/Resources/licenses and under Settings → Helper → Show Licenses….

PassTunnel is not affiliated with OpenVPN Inc., Fortinet, Cisco or Palo Alto Networks. OpenVPN, FortiGate, Cisco AnyConnect and Palo Alto GlobalProtect are trademarks of their respective owners.


Türkçe

PassTunnel, Apple silicon Mac'lerde macOS 13 ve üzeri için açık kaynaklı bir VPN uygulamasıdır. OpenVPN, FortiGate SSL VPN, Cisco AnyConnect ve Palo Alto GlobalProtect (deneysel) bağlantılarını tek tıkla açar (Cisco AnyConnect ve GlobalProtect için macOS 15.4 ve üzeri gerekir; parola ve tek kullanımlık kod ile oturum açılır, tarayıcıyla (SAML) oturum açma desteklenmez; GlobalProtect sizin için nasıl çalıştığını bildirirseniz sevinirim). TOTP anahtarınız Anahtar Zinciri'nde (Keychain) durur; PassTunnel bağlanırken o anki tek kullanımlık kodu ve parolanızı sizin yerinize gönderir. Telefondan kod bakıp yazmanız gerekmez.

Kodun nasıl gönderileceğini profil başına seçebilirsiniz: parolanın sonuna veya başına eklenmiş, parola:kod gibi ayraçlı, kendi şablonunuzla ya da ayrı bir alan olarak. Ana pencere bir authenticator uygulaması gibi canlı kodları gösterir. Menü çubuğundaki panelde her profilin durumu ve kodu görünür, bağlantı koparsa renkli bir rozet uyarır. QR kodu ekran görüntüsünden okunur. Profilleri kimlik bilgisi içermeyen .passtunnel dosyalarıyla ekibinizle paylaşabilir, aynı işlemleri passtunnel komut satırı aracıyla da yapabilirsiniz. passtunnel mcp ile Claude gibi yapay zekâ asistanları VPN durumunu okuyabilir ve sorunları teşhis edebilir (varsayılan olarak yalnızca okur; parola, anahtar ya da kod vermez). İsterseniz profil başına “Bağlanmadan önce Touch ID iste” seçeneğini açın: PassTunnel bağlanmadan ve kodları göstermeden önce Touch ID ya da Mac parolanızla onay ister ve kayıtlı parola ile TOTP anahtarını Mac'in Secure Enclave'indeki bir anahtarla şifreler. Arayüz Türkçe ve İngilizcedir ve macOS dilinizi izler.

Kurulum: İmzalı ve notarize edilmiş disk görüntüsünü indirin, açın ve PassTunnel’ı Uygulamalar klasörüne sürükleyin (sürüm notları) ya da Homebrew ile kurun: brew trust passtunnel/tap, ardından brew install --cask passtunnel/tap/passtunnel (Homebrew 6 ve sonrası, üçüncü taraf bir tap'teki cask'ı ancak o tap'e güvendiğinizde yükler). Uygulama kendini güncel tutar (Ayarlar → Güncellemeler). Kaynaktan derlemek için yukarıdaki Build from source bölümüne bakın.

İlk açılışta, VPN araçlarını yönetici yetkisiyle çalıştıran küçük yardımcıyı (helper) kurmanız istenir. Bunu Sistem Ayarları → Genel → Giriş Öğeleri'nden bir kez onaylarsınız. Yardımcı yalnızca uygulamanın içindeki imzalı openvpn ve openfortivpn kopyalarını çalıştırır; sudoers kuralı gerekmez. Güvenlik modeli için SECURITY.md, diğer her şey için bu belgenin İngilizce bölümlerine bakın.

Proje: yönetim modeli için GOVERNANCE.md, yol haritası için ROADMAP.md, davranış kuralları için CODE_OF_CONDUCT.md, güvence analizi için docs/ASSURANCE.md, katkı kuralları için CONTRIBUTING.md (belgeler İngilizcedir).

來源:README.md,提交 47f7cfc

工具

0
SourceWeft 曾在隔離沙箱中以無憑證方式啟動該軟體包一次,以列出其工具,但未能完成:該軟體包類型無法在沙箱中執行。

版本歷史

11
  1. v1.7.0最新Oct 31, 2026
  2. v1.6.1Oct 30, 2026
  3. v1.6.0Oct 29, 2026
  4. v1.4.1Oct 26, 2026
  5. v1.4.0Oct 26, 2026
  6. v1.3.0Oct 25, 2026
  7. v1.2.0Oct 24, 2026
  8. v1.1.4Oct 23, 2026
  9. v1.1.3Oct 22, 2026
  10. v1.1.2Oct 21, 2026
  11. v1.1.1Oct 21, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分