Commit 0fc145b

Eric Bower  ·  2026-01-02 12:22:40 -0500 EST
parent c5afd39
chore: move marketing materials to pipe
1 files changed,  +2, -236
+2, -236
......@@ -1,6 +1,6 @@
11 {{template "base" .}}
22
3-{{define "title"}}pipe: authenticated pubsub over ssh{{end}}
3+{{define "title"}}pipe: pubsub without the infrastructure. stream data between machines using ssh.{{end}}
44
55 {{define "meta"}}
66 <meta name="description" content="authenticated *nix pipes over ssh" />
......@@ -21,246 +21,12 @@
2121 <canvas id="canvas" width="50" height="50"></canvas>
2222 <hr width="100%" class="m-0" />
2323 </div>
24- <h1 class="text-2xl font-bold text-center">Authenticated *nix pipes over ssh</h1>
24+ <h1 class="text-2xl font-bold text-center">PubSub without the infrastructure. Stream data between machines using ssh.</h1>
2525 <div class="text-center flex gap">
2626 <a href="https://pico.sh/getting-started" class="btn-link mt inline-block">GET STARTED</a>
2727 <a href="https://pico.sh/pipe" class="btn-link mt inline-block">DOCS</a>
2828 </div>
2929 </header>
3030
31-<article class="flex flex-col gap-2">
32- <div>
33- <p>
34- The simplest authenticated pubsub system. Send messages through
35- user-defined topics (aka channels). By default, topics are private to the authenticated
36- ssh user. The default pubsub model is multicast with bidirectional
37- blocking, meaning a publisher (<code>pub</code>) will send its message to all
38- subscribers (<code>sub</code>) for a topic. There can be many publishers
39- and many subscribers on a topic. Further, both <code>pub</code> and
40- <code>sub</code> will wait for at least one event to be sent or received on the topic.
41- </p>
42-
43- <h2 class="text-lg">Features</h2>
44-
45- <ol>
46- <li>Familiar *nix pipes API</li>
47- <li>Zero-install</li>
48- <li>Authenticated pubsub using ssh</li>
49- <li>Private pubsub by default</li>
50- <li>Public pubsub by topic (opt-in)</li>
51- <li>Multicast (many pubs to many subs)</li>
52- <li>Bidirectional (e.g. chat)</li>
53- <li>Paradigms for connecting to a topic:
54- <ol>
55- <li>Read (<code>sub</code>)</li>
56- <li>Write (<code>pub</code>)</li>
57- <li>Read & Write (<code>pipe</code>)</li>
58- </ol>
59- </li>
60- </ol>
61- </div>
62-
63- <div>
64- <h2 class="text-xl">A basic API</h2>
65- <p>Pipe some data into our ssh app and we will send it to anyone listening.</p>
66- <pre>ssh {{.Site.Domain}} sub mykey</pre>
67- <pre>echo "hello world!" | ssh {{.Site.Domain}} pub mykey</pre>
68-
69- <details>
70- <summary>Demo</summary>
71- <script
72- src="https://asciinema.org/a/679717.js"
73- id="asciicast-679717"
74- async="true"
75- data-theme="dracula"
76- data-loop="true"
77- data-speed="1.5"
78- data-idle-time-limit="2"
79- ></script>
80- </details>
81- </div>
82-
83- <div>
84- <h2 class="text-xl">Simple desktop notifications</h2>
85- <p>Want to quickly receive a notification when a job is done? It can be as simple as:</p>
86- <pre>ssh {{.Site.Domain}} sub notify; notify-send "job done!"</pre>
87- <pre>./longjob.sh; ssh {{.Site.Domain}} pub notify -e</pre>
88- </div>
89-
90- <div>
91- <h2 class="text-xl">File sharing</h2>
92- <p>Sometimes you need data exfiltration and all you have is SSH:</p>
93- <pre>cat doc.md | ssh {{.Site.Domain}} pub thedoc</pre>
94- <pre>ssh {{.Site.Domain}} sub thedoc > ./important.md</pre>
95-
96- <details>
97- <summary>Demo</summary>
98- <script
99- src="https://asciinema.org/a/679715.js"
100- id="asciicast-679715"
101- async="true"
102- data-theme="dracula"
103- data-loop="true"
104- data-speed="1.5"
105- data-idle-time-limit="2"
106- ></script>
107- </details>
108- </div>
109-
110- <div>
111- <h2 class="text-xl">Pipe command output</h2>
112- <p>
113- Send command output through our <code>pipe</code> command. The
114- <code>pipe</code> command is just like <code>pub</code> except it
115- is non-blocking and also acts like a <code>sub</code>. So a client
116- that can read and write to the topic.
117- </p>
118- <pre>ssh {{.Site.Domain}} sub htop</pre>
119- <pre>htop | ssh {{.Site.Domain}} pipe htop</pre>
120-
121- <details>
122- <summary>Demo</summary>
123- <script
124- src="https://asciinema.org/a/679712.js"
125- id="asciicast-679712"
126- async="true"
127- data-theme="dracula"
128- data-loop="true"
129- data-speed="1.5"
130- data-idle-time-limit="2"
131- ></script>
132- </details>
133- </div>
134-
135- <div>
136- <h2 class="text-xl">Chat</h2>
137- <p>Use our <code>pipe</code> command to have a chat with someone.</p>
138- <pre>ssh {{.Site.Domain}} pipe mychan -p</pre>
139- <p>
140- Now anyone with a <code>pico</code> account can subscribe to this
141- topic using the same command and start typing!
142- </p>
143-
144- <details>
145- <summary>Demo</summary>
146- <script
147- src="https://asciinema.org/a/679709.js"
148- id="asciicast-679709"
149- async="true"
150- data-theme="dracula"
151- data-loop="true"
152- data-speed="1.5"
153- data-idle-time-limit="2"
154- ></script>
155- </details>
156- </div>
157-
158- <div>
159- <h2 class="text-xl">Pipe reverse shell</h2>
160- <p>If you squint hard enough you can give users interactive access to your shell.</p>
161- <pre>mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | ssh {{.Site.Domain}} pipe myshell > /tmp/f</pre>
162- <pre>ssh {{.Site.Domain}} pipe myshell</pre>
163-
164- <details>
165- <summary>Demo</summary>
166- <script
167- src="https://asciinema.org/a/679704.js"
168- id="asciicast-679704"
169- async="true"
170- data-theme="dracula"
171- data-loop="true"
172- data-speed="1.5"
173- data-idle-time-limit="2"
174- ></script>
175- </details>
176- </div>
177-
178- <div>
179- <h2 class="text-xl">Simple CI/CD</h2>
180- <p>
181- I'm always looking for easy ways to simplify deploying apps
182- automatically. Having an authenticated, zero-install event system
183- seems handy for this purpose.
184- </p>
185- <pre>while true; do ssh {{.Site.Domain}} sub deploy-app; docker compose pull && docker compose up -d; done</pre>
186- <pre>docker buildx build --push -t myapp .; ssh {{.Site.Domain}} pub deploy-app -e</pre>
187- </div>
188-
189- <div>
190- <h2 class="text-xl">Pubsub interactions</h2>
191-
192- <h3 class="text-lg">Multiple subs</h3>
193- <p>
194- Have many subscribers, they will all receive the message.
195- </p>
196- <pre>ssh {{.Site.Domain}} sub foobar</pre>
197- <pre>ssh {{.Site.Domain}} sub foobar</pre>
198- <pre>while true; do echo "foobar1"; sleep 1; done | ssh {{.Site.Domain}} pub foobar</pre>
199-
200- <details>
201- <summary>Demo</summary>
202- <script
203- src="https://asciinema.org/a/679699.js"
204- id="asciicast-679699"
205- async="true"
206- data-theme="dracula"
207- data-loop="true"
208- data-speed="1.5"
209- data-idle-time-limit="2"
210- ></script>
211- </details>
212-
213- <h3 class="text-lg">Multiple pubs</h3>
214- <p>Have many publishers send messages to subscribers.</p>
215- <pre>while true; do echo "foobar1"; sleep 1; done | ssh {{.Site.Domain}} pub foobar</pre>
216- <pre>while true; do echo "foobar2"; sleep 1; done | ssh {{.Site.Domain}} pub foobar</pre>
217- <pre>ssh {{.Site.Domain}} sub foobar</pre>
218-
219- <details>
220- <summary>Demo</summary>
221- <script
222- src="https://asciinema.org/a/679698.js"
223- id="asciicast-679698"
224- async="true"
225- data-theme="dracula"
226- data-loop="true"
227- data-speed="1.5"
228- data-idle-time-limit="2"
229- ></script>
230- </details>
231-
232- <h3 class="text-lg">Multiple pubs and subs</h3>
233- <p>Have many publishers send messages to many subscribers.</p>
234- <pre>ssh {{.Site.Domain}} sub foobar</pre>
235- <pre>ssh {{.Site.Domain}} sub foobar</pre>
236- <pre>while true; do echo "foobar1"; sleep 1; done | ssh {{.Site.Domain}} pub foobar</pre>
237- <pre>while true; do echo "foobar2"; sleep 1; done | ssh {{.Site.Domain}} pub foobar</pre>
238-
239- <details>
240- <summary>Demo</summary>
241- <script
242- src="https://asciinema.org/a/679694.js"
243- id="asciicast-679694"
244- async="true"
245- data-theme="dracula"
246- data-loop="true"
247- data-speed="1.5"
248- data-idle-time-limit="2"
249- ></script>
250- </details>
251- </div>
252-
253- <div>
254- <h2 class="text-xl">Send a public message</h2>
255- <pre>echo "hello world!" | ssh {{.Site.Domain}} pub mychan -p</pre>
256- <p>Now anyone with a <code>pico</code> account can subscribe to this topic:</p>
257- <pre>ssh {{.Site.Domain}} sub mychan -p</pre>
258- </div>
259-
260- <div class="text-center mb-2">
261- <a href="https://pico.sh/getting-started" class="btn-link inline-block">GET STARTED</a>
262- </div>
263-</article>
264-
26531 {{template "marketing-footer" .}}
26632 {{end}}