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