Skip to content

Two-factor codes you own.

A native Mac app and the tess command line on one documented vault format. Offline, with no account.

$brew install ibrahemid/tap/tess

macOS 14 or later · Apache-2.0 · tess 1.1.0 for macOS and Linux · all install options

tess in a terminal: the live watch view with five accounts, codes and full countdown bars, then adding GitHub from a QR image, copying its code and printing it as JSON

Recorded from the real CLI against a throwaway vault.

Install

App version 1.0.2.

The app and the CLI are separate downloads. They share one vault once you open the CLI's file in the app, or set a recovery passphrase in the app's settings.

Homebrew
$brew trust ibrahemid/tap
$brew install ibrahemid/tap/tess
Homebrew 6 loads a third-party tap only after it is trusted. Formula: ibrahemid/homebrew-tap.
Script
$curl -fsSL https://raw.githubusercontent.com/ibrahemid/tessera/main/install.sh | sh
Downloads the release tarball for the current OS and CPU, verifies its sha256 against checksums.txt, and puts tess in /usr/local/bin or ~/.local/bin. Read install.sh first.
Tarballs
  • macOS, Apple silicon 75df08b715dc31a326d25061a64171423bce245cf6f5943753577470a0275568
  • macOS, Intel 84cd31b461cc868cdb219b3da47c7885fff70f9a6b501a69258d1b5aea5399f7
  • Linux, arm64 baf83665ca822a8f75882cc9e08178593d8ca65bbf8c6deb3d4158fbb4264346
  • Linux, x86_64 94144967eddcc5635ce2f1087ea51644fc7195b8482a7c28c12622804b933387
v1.1.0 · checksums.txt · all releases
From source
$go install github.com/ibrahemid/tessera/go/cmd/tess@latest
Go 1.26.2 or later.

Then tess vault init, tess add, tess watch. Vault path: ~/.local/share/tessera/vault.json. The full reference is on /cli.

A native Mac app on the same vault.

Live codes with countdown rings, one-click copy, on-screen QR scanning and Touch ID unlock. It opens a vault the CLI created, and the CLI keeps working on the same file.

  • TOTP, HOTP and Steam Guard.
  • Imports otpauth links, Google Authenticator exports, and files from Aegis, 2FAS, Raivo, andOTP, FreeOTP+, Stratum, Bitwarden, Proton Authenticator, Ente Auth, Apple Passwords and 1Password.
  • Folders, pinning, and a short handle per account that both surfaces share.
  • Copied codes are marked concealed for clipboard managers, and the window is excluded from screen capture.
Tessera's main window: a sidebar with All, Pinned and a Work folder, and five accounts with live codes and countdown rings Tessera's main window: a sidebar with All, Pinned and a Work folder, and five accounts with live codes and countdown rings

One vault, two implementations.

The Go CLI and the Swift app are separate codebases that must open each other's files byte for byte. The contract is written down, pinned to test vectors, and checked in CI on every push.

Canonical JSON

Before encryption the account list is serialized one way only: keys sorted by UTF-8 byte order, Go's string escaping with HTML escaping off, no whitespace, integers only. Both cores produce the same bytes, so cross-decrypt can diff them.

Shared vector suite

spec/testvectors.json pins envelopes, wraps, codes and the edge cases. The Go tests, the swiftc verifier and the XCTest suite all read the same file; a change to one core that the other cannot open fails the vectors.

CI cross-decrypt

Every push runs the Go suite, compiles TesseraCore with swiftc against the vectors, and runs swift test, which decrypts a Go-written vault with real argon2id.

The whole contract is on /vault-format.

Security you can read.

Each line links to the file that does it.

argon2id
A passphrase wraps the vault key through argon2id at 128 MiB, t=3, p=4 with a 16-byte salt. Go uses golang.org/x/crypto; Swift uses the vendored PHC reference implementation, checked against the same known answer. go/internal/vault/vault.go · swift/Sources/CArgon2
XChaCha20-Poly1305
A random 256-bit key encrypts the account payload with a fresh 24-byte nonce on every write. Each unlock method wraps that key separately, so adding or removing a method never re-encrypts the payload. spec/vault-format.md · swift/Sources/TesseraCore/XChaCha.swift
Secure Enclave wrap
The app wraps the key with a non-extractable Secure Enclave P-256 key (HKDF-SHA256 over a self key agreement). Require Touch ID adds the biometry access control. Set a recovery passphrase in Settings and the same file gains an argon2id wrap the CLI can open. swift/App/Sources/SecureEnclaveWrap.swift
No network entitlement
The app's entitlements are App Sandbox, user-selected files and app-scoped bookmarks. There is no network entitlement, so the app cannot open a connection. The CLI makes no network connections: it imports neither net nor net/http. swift/App/Resources/Tessera.entitlements · go/go.mod
Sandboxed
The Mac app runs in the App Sandbox and ships through the Mac App Store, where its privacy label reads Data Not Collected. The vault it shares with the CLI is reached through a bookmark you grant once. App Store listing · PrivacyInfo.xcprivacy

More on /security, including what to do if you find something.

Compared with the others

ThemTessera
ThemFree, open source, end-to-end encrypted sync across devices. Not on the Mac App Store.
TesseraLocal only, on the Mac App Store, with a command line.
ThemTied to a phone number and an account, closed source; the desktop app ended in August 2024.
TesseraNo account. A local file you own.
2FAS
ThemA phone app; on a Mac, a browser extension.
TesseraA native Mac app plus a command line.
Raivo
ThemOpen source on Apple platforms until it changed hands.
TesseraApache-2.0, a documented format, export in one command.
oathtool, pass-otp
ThemCommand-line tools with secrets in plain files or gpg, and no app.
TesseraThe same scriptability, an encrypted vault, Touch ID in the app, a window when you want one.

All of it, free.