Status: pre-1.0, no independent security review. Do not use it to guard production or sensitive systems without one. See
[SECURITY.md].
Tessera is a consent-gated remote access broker for "give Alice access to my local postgres, just for this debug session, with a paper trail, end it when we're done."
tessera share -port 5432
mints an 8-character code. Alice runs tessera join CODE
, you see a prompt at your terminal showing who is asking and why, type
y
, and her local 127.0.0.1:13000
now forwards to your 5432
for as long as either side holds the session. Every request, approval, and session close lands in an append-only audit log.
Not a VPN, not a stable public URL, not a persistent account. The whole point is that nothing lives between sessions: no token your teammate keeps, no port left open, no record other than the audit line you wrote.
The name is the Roman tessera hospitalis, a token given to a guest as proof of a trusted, welcomed relationship.
curl -fsSL https://raw.githubusercontent.com/emmayusufu/tessera/main/install.sh | bash
On first run, you'll be prompted to link to a coordinator (skip with TESSERA_SKIP_LINK=1
).
Pulls the latest release binary for your OS and architecture. Falls back to go install
if no release is published for your platform. Override the install location with TESSERA_BINDIR
.
If you'd rather build manually:
git clone https://github.com/emmayusufu/tessera && cd tessera && make build
Pair programming across networks. You want a teammate to hit your local dev server onlocalhost:3000
. They runtessera join
, you typey
in your terminal, they reach it; Ctrl-C ends it.Support sessions. A customer can't reproduce a bug. They runtessera share
, send you the code, you join, they watch and approve at their terminal. When the call's over, the share dies.Database debugging. A contractor needs to look at your staging postgres for fifteen minutes; you share the port, they connect, you see every request flow through the audit log.One-off shell access. Same shape withtessera share -shell
for a PTY attached to your machine. Read theSECURITY.mdsection on what-shell
actually exposes before you use it.
Three small Go binaries. The agent dials out to the coordinator, so the host's resource never accepts an inbound connection and nothing is exposed until the host approves a specific request.
flowchart LR
CLI["tessera (guest CLI)"]
CO["coordinator<br/>(broker)"]
AG["agent"]
RES[("host resource<br/>db / web / rdp")]
H(("host terminal"))
CLI -- "mTLS" --> CO
AG -- "mTLS, dials out" --> CO
AG --> RES
H -- "types y/n at the prompt" --> CO
coordinator: runs on a public host. Accepts mutual-TLS connections from agents and guests, relays approved streams (as opaque ciphertext, since inner TLS terminates at the endpoints), and writes the audit log. Opens no access on its own.agent: runs on the host's side as a background service. Dials out to the coordinator and waits. Accepts nothing inbound. On an approved stream it connects to the approved localhost:port
and pipes.tessera: the guest CLI. Requests access, waits for approval, then forwards a local port through the coordinator to the resource.
sequenceDiagram
participant G as Guest
participant K as Coordinator
participant H as Host
participant A as Agent
participant R as Resource
A->>K: register (dials out)
G->>K: request access (target, reason)
K-->>H: prompt over mTLS (tessera share)
H->>K: y / n at the terminal
K-->>G: approved + session
G->>K: open stream (session)
K->>A: open data (target)
A->>R: dial target
Note over G,A: inner TLS end to end. Coordinator sees only ciphertext.
G->>R: tunneled traffic
Not permanent. A session lives only while it is held: either party ends it instantly, it dies on disconnect, an idle stream times out after 30 minutes, and every request, approval, session open and close is written to an append-only audit log.
make build
cd bin
./tessera ca --coordinator-name localhost
./coordinator -listen :8443 -http :8080 &
./agent -coordinator localhost:8443 -share-id demo -allow 127.0.0.1:5432 &
./tessera connect -coordinator localhost:8443 -share-id demo \
-target 127.0.0.1:5432 -reason "troubleshoot" -local 127.0.0.1:15432
The coordinator needs to run on a host with a public address. Two ways: Docker or a bare binary. Pick whichever feels lighter to maintain. The flags and env vars are the same in both.
For step-by-step instructions (systemd unit, compose, operator token, upgrade path), see deploy/DEPLOYING.md. The bits below are the short version.
The image is a single 18 MB static binary on distroless. One image holds all
three binaries (coordinator, agent, tessera). Compose runs the coordinator by
default; the others are available via --entrypoint
if you want to run them in containers too.
docker build -t tessera .
mkdir -p certs && cd certs
docker run --rm -v "$PWD:/work" -w /work --entrypoint /usr/local/bin/tessera \
tessera ca --coordinator-name tessera.example.org
cd ..
docker compose up -d
docker compose logs -f coordinator
The compose file mounts ./certs/
read-only and keeps the audit log in a named
volume. For HTTPS on the redeem/peek endpoints (recommended in production so
the guest's private key stays confidential in transit), mount your Let's
Encrypt directory and add the -http-cert
/ -http-key
flags to the command list.
./coordinator -http-cert fullchain.pem -http-key privkey.pem
The host approves at their terminal where tessera share
is running: every
inbound request prints a prompt and waits for y
or n
. No web page, no out-of-band link.
Require an operator token for operator actions (revoke). Generate one when you deploy the coordinator, then save it once on the host:
tessera token <token-hex>
That writes it to ~/.config/tessera/operator-token
. After that, tessera share
auto-reads it, so you don't have to re-export it per shell. For ad-hoc curl:
curl -X POST -H "Authorization: Bearer $(cat ~/.config/tessera/operator-token)" \
https://tessera.example.org/s/<sessionID>/revoke
When no token is configured on the coordinator, revoke is disabled.
You still need a public host (a $5 VPS is fine), a DNS A record pointing at it, open inbound ports 8443 and 8080 on its firewall, and a TLS cert for the HTTP endpoints if you want HTTPS (recommended in production to keep the redeem response, which carries a guest private key, confidential in transit). Docker doesn't change any of that. It just makes "run the coordinator process" boring.
Releases are produced by GitHub Actions on tag push. Each tag publishes 12 binaries (tessera, agent, coordinator for linux/{amd64,arm64} and darwin/{amd64,arm64}) plus a multi-arch container image to GHCR.
Confirm what landed:
gh release view v0.3.0 --json assets --jq '.assets[] | "\(.size) \(.name)"'
docker run --rm --entrypoint /usr/local/bin/tessera \
ghcr.io/emmayusufu/tessera:0.3.0 version
docker buildx imagetools inspect ghcr.io/emmayusufu/tessera:0.3.0
If the version baked into the image doesn't match the tag, the release
pipeline didn't run cleanly: check the workflow at .github/workflows/release.yml
and the run logs in the GitHub Actions tab.
Live coordinators also expose /healthz
on the HTTP port. Point any uptime monitor at it:
curl https://your-coordinator/healthz
A change in the version string is the cheapest signal that a redeploy actually went through.
- A session is bound to the approved guest's certificate. A different enrolled guest cannot ride someone else's session, even with the ID.
- Revoke force-closes in-flight streams, it does not just block new ones.
- Traffic is end-to-end encrypted: guest and agent run an inner TLS session directly through the coordinator, which relays only ciphertext (a test asserts a plaintext marker never appears on the relay path).
- The agent only reaches targets on its
-allow
list, which is required. - Approval happens at the host's terminal over the same mTLS channel that carries everything else. There is no web endpoint to phish or MITM. Operator actions (revoke) require an operator bearer token.
Tessera is tiny and single-purpose. Teleport's free Community Edition does far more (SSH, Kubernetes, databases, RDP, web, SSO, session recording, RBAC) and is production-grade and audited; if you can run it, use it. The one thing Tessera gives you that Teleport gates behind its paid Enterprise tier is the request and human-approve, just-in-time access flow. Tessera also runs with no cluster or SSO to operate, and is MIT-licensed rather than AGPL. Verify Teleport's current edition split before relying on that distinction.
v1: generic TCP forward to one approved host:port
(covers a database, an internal web portal, an RDP desktop) or interactive shell, request, approve-at-terminal, mutual revoke, audit log.
Not yet built: replayable session recording, RBAC, persistence.
Tessera only makes sense as a consent-based tool: the host always approves,
access is scoped to a session, and everything is audited. It is not a backdoor.
Serve the redeem/peek endpoints over HTTPS (-http-cert
/-http-key
) in production so the guest's bundle (which contains a private key) is not sniffable in transit. For real production use, get the design security-reviewed first.
make test # go test ./...
make race # go test -race ./...
make lint # staticcheck + golangci-lint
make fmt # gofmt + goimports
See CONTRIBUTING.md for the toolchain.
brew install pre-commit # or: pip install pre-commit
pre-commit install # wires .git/hooks/pre-commit
After install, every git commit
runs gofmt, go vet, go test, plus a few project-specific checks (no em-dashes in tracked files or commit messages, no AI/Claude attribution in commit messages, no work-email leakage).
To run all hooks manually without committing:
pre-commit run --all-files
MIT