Skip to content

About

CLI-first AWS Client VPN for macOS. Small, source-first, agent-friendly.

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

32 Commits

Folders and files

Repository files navigation

awsvpn

Connect to a SAML/SSO AWS Client VPN endpoint from your macOS terminal.

sudo awsvpn connect dev

A terminal running awsvpn connect dev. It stops the previous tunnel, verifies the AWS-signed VPN engine against Apple team 94KV3E626L, starts it, opens a SAML sign-in in the browser, captures the assertion, and reports a connected split-tunnel with its assigned IP and endpoint.

awsvpn starts the AWS-signed VPN engine installed by the official AWS VPN Client, then returns control to your shell. Use it from a terminal, script, or agent without a menu bar app or a manually opened browser tab.

Why awsvpn

VPN clients run as root, change DNS and routes, and handle a bearer credential. awsvpn keeps the privileged part small and inspectable:

  • It runs the AWS-signed acvc-openvpn binary from the official AWS VPN Client. Before root executes it, awsvpn verifies its Apple signature and pins AWS's team identifier, 94KV3E626L.
  • It keeps the SAML assertion in memory. The assertion never appears in a file or process argument; awsvpn passes it to OpenVPN over its management socket.
  • It vendors its small dependency set and builds from source. Each connection uses sudo; install-privilege is an explicit opt-in for automation.

Read the security model before using it on a system you care about.

Requirements

Install

With Homebrew:

brew install lucassarcanjo/tap/awsvpn

Or with the Go toolchain:

go install github.com/lucassarcanjo/aws-vpn-cli@latest

Or from a clone:

git clone https://github.com/lucassarcanjo/aws-vpn-cli && cd aws-vpn-cli
make install

Every route builds from source. The Homebrew formula lives in Formula/awsvpn.rb and is published to lucassarcanjo/homebrew-tap on each tagged release; brew compiles it locally rather than fetching a binary.

Usage

awsvpn list                     # profiles from AWS VPN Client + imports
sudo awsvpn connect dev         # connect by name
sudo awsvpn connect             # choose a profile
awsvpn status                   # state, IP, endpoint, DNS, tunnel mode, uptime
sudo awsvpn disconnect          # remove routes and restore DNS
awsvpn logs -f                  # follow the connection log
awsvpn import ./client.ovpn     # register a config outside the AWS client
awsvpn version
sudo awsvpn install-privilege   # opt-in NOPASSWD rule; connect/disconnect then
                                # elevate themselves, no `sudo` prefix needed
awsvpn uninstall-privilege      # revoke that rule

awsvpn reads profiles from the AWS VPN Client without changing its store and merges them with imported profiles. It supports one active connection; a new connection replaces the current tunnel.

connect with no profile name opens a picker: type to filter the list the forgiving way fzf does — pd finds prod — then ↑/↓ to move, Enter to connect, Esc to cancel. Backspace widens the search and ctrl-u clears it. With fzf installed you get its picker instead, and a list too tall for the window falls back to a typed prompt.

While connect waits for single sign-on, press Enter to re-open the page or c then Enter to copy the link — useful when open hands it to a browser you aren't signed in with. connect -v streams the raw connection log instead of the progress summary.

list and status take --json for scripts and agents. status reports connected, connecting, stale, or disconnected. Colour follows the terminal and respects NO_COLOR.

Other flags: import --name sets the profile name, install-privilege --yes skips the confirmation prompt, and connect --allow-unverified-binary skips the signature check — only for a signing-identity change you have verified yourself.

If the tunnel drops

A successful connect registers a supervisor: a root LaunchDaemon that watches the tunnel's management channel for the rest of the session. If the connection drops and cannot come back on its own within a minute — or comes back needing a fresh browser sign-in, which no background daemon should attempt — the supervisor tears the tunnel down, restores your DNS and routes, and posts a desktop notification. A laptop that sleeps through an outage wakes up with working networking rather than traffic pointed into a dead tunnel.

The supervisor exists only while a connection does: disconnect (and the next connect) removes it. If it cannot be started, connect says so and the tunnel still comes up — you just clean up by hand.

Security

  • awsvpn verifies the AWS VPN binary immediately before it runs as root.
  • It binds the SAML callback to 127.0.0.1:35001 before opening your browser and aborts if another process already owns the port.
  • Root-owned runtime state lives in /var/run/awsvpn; imported profiles remain in your home directory.
  • Nothing of awsvpn runs as root between connections: the drop supervisor is registered on connect and removed on disconnect.
  • The fixed AWS callback port, running the wrapper as root, the root supervisor while connected, and a passwordless sudo rule each carry residual risk.

See the full threat model and connection flow.

Development

make test
make vet
make vuln        # requires: go install golang.org/x/vuln/cmd/govulncheck@latest
make build

License

MIT. See LICENSE.

awsvpn is an independent project. It is not affiliated with, endorsed by, or sponsored by Amazon Web Services or Apple. AWS, the AWS logo, and macOS are trademarks of their respective owners.

About

CLI-first AWS Client VPN for macOS. Small, source-first, agent-friendly.

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages