AuthCompanion sets up two independent macOS authentication tools with one command:
pinentry-companionapproves GPG signing with Touch ID or Apple Watch.pam-companionapprovessudowith Touch ID or Apple Watch.
AuthCompanion 0.1 is a Swift command-line tool. It coordinates the two released components but does not duplicate their authentication or configuration code.
brew install CasualDeveloper/tap/authcompanion
authcompanion status
authcompanion plan
sudo -v
authcompanion setup --yesThe Homebrew formula installs both component formulas as dependencies. Run
AuthCompanion as your login user, without sudo. Authorize sudo directly
before setup. AuthCompanion invokes only sudo -n commands, which tell sudo to
fail instead of requesting a password. Component input is also connected to
/dev/null. AuthCompanion never reads or stores your administrator password.
Setup performs these operations in order:
- Read pinentry-companion's passive plan.
- Ask pam-companion to validate its setup with
--dry-run. - Configure or adopt pinentry-companion's GPG setup.
- Configure pam-companion and verify its health.
- Verify the visible PAM policy and module postcondition.
The related privileged commands reuse the short-lived authorization created by
sudo -v. If it is missing or expires, AuthCompanion stops and asks you to run
sudo -v again instead of presenting its own password prompt.
If GPG already points to a different pinentry and you intend to replace it, review the plan and use the explicit takeover form:
authcompanion setup --take-over --yesauthcompanion status
sudo -v && authcompanion doctor
sudo -v && authcompanion restore --yesstatus and plan are passive. They do not invoke sudo, write files, reload
GPG, access the Keychain, or show an authentication prompt.
Restore asks pam-companion to restore its recorded system state before asking pinentry-companion to restore the current user's recorded GPG state. A failure at the privileged boundary therefore leaves the working GPG configuration untouched.
Each component owns its own state:
- pinentry-companion owns the current user's GPG configuration record;
- pam-companion owns the machine PAM transaction and its root-only rollback record;
- AuthCompanion stores no third lifecycle database.
If PAM fails after pinentry setup, AuthCompanion asks PAM to recover and then
restores pinentry. If PAM was already committed when its health check fails,
AuthCompanion restores PAM first and then pinentry. It reports
manualRequired if either component cannot prove its rollback.
authcompanion status [--format json]
authcompanion plan [--format json]
authcompanion setup --yes [--take-over] [--format json]
authcompanion restore --yes [--format json]
authcompanion doctor [--format json]
authcompanion --version
authcompanion --help
JSON responses use schema version 1 and contain exactly one document on
standard output. Exit status 0 means success or a non-blocking warning, 1
means an operational error or conflict, and 2 means the invocation is
invalid.
AuthCompanion resolves only the fixed Homebrew opt locations for the two
formulas, verifies that they resolve inside their respective Cellars, and
requires the supported component versions. It never searches PATH, accepts
an executable override, or builds a shell command.
- macOS 14 or newer
pinentry-companion0.2.0pam-companion0.1.1- Swift 6.3.3 for release archives
- macOS Command Line Tools for builds and packaging
- Xcode, or another toolchain containing XCTest, only for the test suite
swift build -c releaseThe Swiftly toolchain can build the product but does not include XCTest on this machine. Run tests with an installed Xcode explicitly:
DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer \
xcrun swift test -Xswiftc -warnings-as-errorsThe project does not currently use an Apple Developer Program membership. Release binaries are universal, ad hoc signed with the hardened runtime, and not notarized. The Homebrew formula pins the archive SHA-256 digest. Releases also include checksums and GitHub build-provenance attestations.
Create and verify a local candidate without changing authentication state:
swiftly run ./Scripts/package-release.sh --allow-dirty
./Scripts/verify-release.sh dist/authcompanion-0.1.2.tar.gzSee RELEASING.md for the release and single live setup gate.
AuthCompanion was developed with Codex and GPT-5.6 as engineering tools. Codex helped inspect the existing component code, implement and test the Swift 6 PAM module and orchestration CLI, and exercise the packaging, release, recovery, and rollback paths. GPT-5.6 was used to reason through the security model and failure cases, especially partial PAM commits, configuration drift, and how to prove that a rollback completed.
The architecture and product decisions remained human-led, and every Touch ID,
Apple Watch, GPG-signing, and sudo path was verified on real Mac hardware.
Neither Codex nor GPT-5.6 is part of the shipped product: AuthCompanion makes no
model calls at runtime.
AuthCompanion has no daemon, network service, telemetry, or credential store. The component tools delegate device-owner authentication to macOS.
Licensed under the Apache License 2.0. See LICENSE.