A proposal and reference implementation for continuous in-session identity verification in SSH.
OpenSSH verifies identity once. ZTSSH verifies identity for the entire life of the session.
SSH is trusted everywhere, but its trust model is still mostly login-time trust:
- user authenticates,
- session opens,
- trust persists until logout.
That model is increasingly weak against:
- stolen laptops,
- token theft after login,
- long-lived shells on production servers,
- session hijacking after initial authentication,
- lateral movement inside infrastructure.
ZTSSH proposes a simple change in philosophy:
authentication must not be a one-time event; it must be a continuous property of the session.
ZTSSH introduces a recurring challenge-response loop inside SSH sessions.
Every
- the server sends a fresh random challenge,
- the client proves liveness by signing it with a fresh ephemeral key,
- the client presents a very short-lived certificate,
- the server verifies certificate validity, issuer, signature, TTL and policy,
- the session continues or is terminated immediately.
In practice, that means a compromised identity stops being trusted quickly, even after the shell is already open.
ZTSSH uses a hierarchical CA model:
Root CA (offline)
↓ issues 24h server licence
Sub-CA embedded in each server
↓ issues 5 min client certificate
Client session
| Certificate | Issued by | Used by | Default TTL | Purpose |
|---|---|---|---|---|
IntermediateCertificate |
Root CA | Server Sub-CA | 24 hours | Authorize a server to certify clients |
ZtsshCertificate |
Server Sub-CA | Client | 5 minutes | Prove client identity continuously |
Client connects
→ receives short-lived client cert
→ opens session
Every challenge interval:
Server → IDENTITY_CHALLENGE(nonce, seq, deadline)
Client → optionally renews cert locally via Sub-CA
Client → IDENTITY_PROOF(cert, signature(challenge))
Server → verifies cert + signature + revocation state
Server → IDENTITY_ACK or SESSION_TERMINATE
This is critical.
ZTSSH does not require a central online CA during the session.
Each server has a local SubCa that can issue client certificates under a Root-issued licence.
That gives:
- no network dependency during revalidation,
- low latency,
- graceful operation during CA outages,
- better operational realism for production infra.
ZTSSH currently supports 3 levels of revocation:
- principal ban: ban a user globally,
- server revocation: invalidate a server licence,
- client certificate revocation: invalidate one badge immediately.
The repository contains a working Rust implementation covering Phases 1 through 5:
-
- Ed25519 keypairs
- zeroize-on-drop private key handling
IntermediateCertificateZtsshCertificate- nonce generation
-
- message constants
- binary message types
- protocol defaults
-
RootCaSubCaRevocationList- verification results
-
- TCP transport with length-prefixed framing
- handshake messages (ClientHello, ServerHello, CertRenewal)
- server-side challenge loop
- client-side proof generation and certificate renewal
-
rust/crates/ztssh-ca-cli →
ztssh-cabinaryinit— generate Root CA keypairauthorize-server— issue IntermediateCertificaterevoke-server/ban-principal— revocation managementgenerate-server-key— create Sub-CA keypairshow/export-revocation— inspect CA state
-
rust/crates/ztsshd →
ztsshdbinary- loads Sub-CA key + IntermediateCertificate
- accepts connections, issues client certificates
- runs periodic challenge-response loop
- verifies proofs, handles certificate renewal
-
rust/crates/ztssh-client →
ztsshbinary- connects to server, performs handshake
- responds to identity challenges
- automatic certificate renewal before expiry
-
- structured audit event system with typed events
tracing-based logging (textor JSON output)- all binaries emit machine-parseable audit trails
-
- TOML-configured policy engine
- principal allowlists/denylists, CIDR source-IP filtering
- per-principal rules (max sessions, allowed IPs)
- sliding-window rate limiter (per-IP, configurable window/limit)
- enforced at connection time in the transport layer (
--policyflag)
-
- filesystem-backed key storage with
Keystoretrait - restricted file permissions (0600 on Unix)
- zeroize-on-delete for private key material
- integrated in
ztssh-caCLI for structured key management - extensible to HSM/agent backends
- filesystem-backed key storage with
-
- SSH transport via
russh0.57 (ZTSSH protocol over SSH subsystem channels) - Ed25519 host key generation
- server handler with session channel and "ztssh" subsystem
- client handler with SSH connect + subsystem negotiation
- both binaries support
--mode tcp|sshto select transport
- SSH transport via
-
Rate limiting & connection throttling
- token-bucket rate limiter enforced per source IP in the accept loop
- configurable
max_connectionswith atomic counter RateLimitederror variant surfaced to audit events
-
Revocation enforcement in transport
- principal ban check at handshake time
- client certificate serial revocation check in proof verification
SignedRevocationList— Ed25519-signed CRL snapshots with wire serializationverify_and_extract()validates signer before accepting a CRL
- docs/INTEROP.md — interoperability with SSH ecosystems,
russhintegration plan, SIEM integration - docs/OPERATOR.md — operator guide: CA setup, server provisioning, logging, policy, monitoring, runbook
- docs/AUDIT.md — security audit preparation: threat model, attack surface, cryptographic checklist
- 143 tests passing (78 unit + 23 property-based + 17 security + 7 constant-time + 6 handshake + 6 end-to-end + 6 CRL/rate-limit)
cargo clippy -- -D warningsclean- 6 end-to-end integration tests (real server + real client, multi-cycle challenge-response, cert renewal, policy enforcement)
- structured audit logging via
tracing(text and JSON formats) - TOML-based policy engine with CIDR IP filtering, enforced at connection time
- filesystem key storage with zeroize-on-delete, integrated in CA CLI
- memory-safe Rust baseline
- no online CA dependency in the core architecture
- constant-time public key comparison via
subtle - 9 fuzz targets covering all parsers
- ProVerif formal model for authentication and secrecy properties
- reproducible build configuration
- operator documentation and security audit preparation guides
Automated demo scripts are available:
# Linux / macOS
./scripts/demo.sh
# Windows PowerShell
.\scripts\demo.ps1Or run it manually:
cd rust/
# 1. Initialize a Root CA
cargo run --bin ztssh-ca -- init
# 2. Generate a server Sub-CA key
cargo run --bin ztssh-ca -- generate-server-key --out server.key
# 3. Authorize the server (use the public key printed in step 2)
cargo run --bin ztssh-ca -- authorize-server \
--server-id srv-demo \
--pubkey <SERVER_PUBLIC_KEY_HEX> \
--out intermediate.cert
# 4. Start the server (5s challenge interval for demo)
cargo run --bin ztsshd -- \
--cert intermediate.cert \
--key server.key \
--challenge-interval 5
# 5. In another terminal, connect as a client
cargo run --bin ztssh -- alice@127.0.0.1:2222
# Or with explicit flags
cargo run --bin ztssh -- --connect 127.0.0.1:2222 --principal aliceYou should see the continuous challenge-response loop in action:
- server sends
IDENTITY_CHALLENGEevery 5 seconds - client signs and responds with
IDENTITY_PROOF - server verifies and sends
IDENTITY_ACK - certificates are renewed automatically before expiry
ZTSSH is interesting because it sits at the intersection of:
- SSH,
- zero trust architecture,
- applied cryptography,
- systems programming,
- defensive infrastructure.
This is not “just another SSH wrapper”. It is an attempt to define a new trust model for remote shell access.
If successful, the project can become:
- a reference protocol,
- a Rust SSH implementation with continuous auth,
- a research-grade security project,
- a deployable hardened alternative for critical infrastructure.
The roadmap below is designed to make contribution paths obvious.
- Rust workspace
- cryptographic primitives
- hierarchical CA model
- revocation logic
- protocol message definitions
- serialization and verification tests
- build TCP transport with length-prefixed framing (SSH integration via
russhplanned for Phase 3) - implement
ztsshclient binary - implement
ztsshdserver binary - implement offline
ztssh-caCLI - add local demo: connect, challenge, renew, terminate
- fuzz all parsers and wire formats
- property-based tests for protocol state machine
- replay and downgrade resistance tests
- formal modelling in ProVerif or Tamarin
- constant-time review of sensitive operations
- reproducible builds
- interoperability story with existing SSH ecosystems
- agent/key storage strategy
- observability and audit logs
- policy engine (with transport-layer enforcement)
- documentation for operators
- third-party security audit preparation
- end-to-end integration tests
- automated demo scripts
-
russhSSH transport integration (ZTSSH protocol over SSH subsystem channels) - channel multiplexing (ZTSSH as SSH subsystem alongside shell/exec)
- signed revocation list distribution (Ed25519-signed CRL snapshots with wire format)
- rate limiting and connection throttling in policy engine
- revocation enforcement in transport (principal ban + cert serial check)
-
--mode tcp|sshflag on both binaries - full bidirectional protocol bridge over SSH channel (data ↔ ZTSSH framing)
- HSM / hardware token backend for
Keystoretrait - SSH agent protocol integration (ssh-agent forwarding)
- TLS or Noise encryption for the TCP transport (pre-SSH phase)
- CI/CD pipeline (GitHub Actions)
- cross-platform CI builds and release artifacts
- packaging (Debian/RPM/Homebrew/Scoop)
- benchmark harness (latency per challenge cycle, throughput under load)
- third-party security audit execution
- SIEM integration (Splunk, Elastic, Datadog exporters)
High-value entry points for contributors:
- finish the bidirectional SSH channel ↔ ZTSSH framing bridge,
- HSM keystore backend — PKCS#11 or YubiKey integration,
- CRL distribution endpoint — serve signed revocation snapshots over HTTPS,
- benchmark harness — measure challenge-response latency,
- cross-platform CI — build + test on Linux/macOS/Windows,
- Debian/RPM packaging,
- protocol diagrams and docs cleanup.
A project white paper is available in docs/WHITEPAPER.md.
The white paper is intentionally written in a concise, protocol-first style inspired by early foundational internet and cryptography papers.
cd rust
cargo build
cargo test
cargo clippy -- -D warningsSee SECURITY.md.
See CONTRIBUTING.md.
AGPL-3.0-or-later. See LICENSE.