โ† All libraries

CandyWish

๐Ÿ” CandyWish

SSH server middleware framework

port of wish ssh middleware force-command multi-tenant

Build TUIs anyone can ssh user@host to run. Leans on the host's OpenSSH daemon (ForceCommand) rather than re-implementing the SSH wire protocol. sshd handles auth, ciphers, host keys, fail2ban, audit logs.

Install

composer require candycore/candy-wish

Quickstart

// /opt/wish/server.php โ€” invoked by sshd ForceCommand
require '/opt/wish/vendor/autoload.php';

use CandyCore\Wish\Server;
use CandyCore\Wish\Middleware\{Logger, Auth, RateLimit, BubbleTea};

Server::new()
    ->use(new Logger('/var/log/wish.jsonl'))
    ->use(new RateLimit(
        '/var/lib/wish/buckets.json',
        burst:      5,
        ratePerSec: 0.5,
    ))
    ->use(new Auth(users: ['alice', 'bob']))
    ->use(new BubbleTea(fn($session) => new MyApp($session)))
    ->serve();

What's in the box

ForceCommand entryEach connection forks a fresh PHP under sshd. Audit / rate-limit / ssh-cert all stay your existing stack.
Logger middlewareStructured JSONL session log to stdout / file.
Auth middlewareAllowlist by username; denied connections close cleanly.
RateLimit middlewareToken-bucket per username, persisted to JSON. Burst + rate configurable.
BubbleTea middlewareMount a CandyCore Program at the end of the chain.
Custom middlewareAnything implementing Middleware::handle($session, $next).

Source & demos

Try the quickstart โ†’