Tenjin

A media server that is yours: own libraries, own user management, optional relay for access from anywhere.

Version 0.1.0 · In development

Windows · macOS · Linux · Android · Android TV · Fire TV

Tenjin desktop client: start page with continue-watching row and libraries

Every server is its own trust anchor

A media server owns a key pair, issues tokens and decides about permissions on its own. The relay verifies tokens only against the server's public key; accounts, permissions and user data live exclusively on the media server.

Server identity

On first start the server generates an Ed25519 key pair. The server ID is the fingerprint of the public key; clients pin it at pairing. Ed25519

Initial setup without a web UI

The server writes a one-time setup code to console and log and announces itself via mDNS on the LAN. The user enters the code in the client, creates the admin account and pins the server key. Headless: tenjin-server --setup. mDNS · setup code

Relay identity

The relay is reachable under a domain name and carries a public certificate, for example from Let's Encrypt. Servers register with a registration code and keep an outbound control connection; no port forwarding is needed. Let's Encrypt · registration code

Login and tokens

Password verification always happens end-to-end between client and media server, even in relay mode C; the login request is passed through there. A PAKE scheme (OPAQUE) is planned so the password never reaches the server in plain text.

Login and tokens, also via the relayClientRelay (path B)Media serverConnection to server IDpassed throughPassword verification always end-to-end between client and server;the relay sees only encrypted packets.Login (PAKE), device identifierAccess token (approx. 15 min) + refresh token (bound to the device)Tokens are signed with the server key (Ed25519);claims: srv, sub, libs, age, bw, streams, dev, expAPI call with access tokenResponseRenewal with refresh tokennew token pair, old refresh token invalid (rotation)If a replaced refresh token reappears after the grace period,the server revokes all tokens of the device and warns in the activity log.Connection via relay with tokenVerify signature offline against the server's public keypassed through
Login and tokens · UML sequence diagramOpen full size

The server issues a short-lived access token (about 15 minutes) and a device-bound refresh token. The refresh token is replaced on every renewal. If a replaced token reappears after a grace period, the server revokes all tokens of the device and warns in the activity log. Detection, grace period and validity (default 30 days) are configured by the administrator. The relay issues no tokens of its own.

Claim Content
srv Server ID of the issuer
sub Local user ID
libs Granted library IDs
age Age rating limit
bw Maximum bitrate locally and remotely
streams Maximum concurrent streams
dev Device ID
exp Expiry time

Tokens are signed with the server key; the relay verifies them offline. Quick Connect signs in TVs and other devices without a keyboard: the device fetches a six-digit code, a signed-in phone or computer approves it, and the device receives its own token pair.

Quick Connect: signing in without a keyboardTVMedia serverPhone (signed in)Request a codesix-digit code, valid for a limited timeShow the codeEnter and approve the codeBind the code to the phone's accountRedeem the code with its own secretown token pair for the TVFrom outside the home the relay address is enough;there are no fixed relay addresses in the program.
Quick Connect · UML sequence diagramOpen full size

Three paths, three levels of trust

Path B (default): the relay sees

  • Server ID and device ID of the connection
  • Timestamps, packet sizes, data volume
  • The token signature, which it verifies offline

Path B: the relay does not see

  • Passwords or credentials
  • Titles, images, streams, progress
  • Session keys of the QUIC connection

Path C (relay termination) has to be enabled explicitly by the relay administrator per server, and the server administrator can refuse it for their server. Only then does the relay see contents, for example to cache or transcode streams.

Account linking and sync

Anyone with accounts on two servers can link them: server 1 generates a random 128-bit sync ID and a link secret, the client hands both to server 2, and both servers exchange a key for this pairing. Favourites and progress then travel end-to-end between the servers via the relay; the relay sees only the pseudonymous sync ID.

Further measures

  • Brute-force protection: delay and lockout after failed attempts; audit log for logins and admin actions.
  • Secrets (API keys, SMB, NFS and WebDAV credentials) are stored encrypted, with the key in the operating system's key store: DPAPI (Windows), Keychain (macOS), key file with permissions 0600 (Linux, QTS).
  • Image addresses carry no tokens and are cached only when versioned; a changed image has a new address.
  • The player fetches streams through a local proxy of the client; tokens stay in the client.
  • The relay control channel is outbound; no port has to be opened on the media server.

Status and limits

Tenjin 0.1.0 is a development build: the database schema and the protocol may still change before 1.0. An external security review is still outstanding; the measures above describe the concept and the current state of implementation. Anyone who does not trust the relay operator runs the relay themselves or stays with path A.