heliograph
View as markdown

What might come next, and what never will

Three questions arrive constantly: "could it go over X", "could it run on Y" and "could I drive it from Z". This page answers all three for every candidate anyone has raised, with a verdict and the reason, so that an estate can tell in one read whether it is waiting for something or whether the answer is no.

Nothing here is a promise of a date. What is built is on transports and hosts, and those two pages state both sides of every claim. This one is about what is not built.

verdictmeans
donext, or near enough free
laterreal value, waiting on something named
mayberevisited when an engagement asks for it
neverdecided against, and the reason travels with it

Two contracts decide most of it

A candidate that fails either is not a near miss, it is a different product.

A transport implements ten functions on the station side, seven of them on the capture path, and its tp_check proves a write rather than a read. Read access is not write access, and the expensive failure is an hour-long step that captures a perfect log and cannot deliver it.

A host needs five things: a process that can run bash, outbound reach to one transport, a restart policy, a non-root account, and somewhere to write a file it then hands off. No VNet, no inbound port, no persistent disk.

The constraint that shapes the rest is that nothing is ever installed on the far side. A transport that needs a client library is a transport that needs a change request, which is the thing this exists to avoid.

Transports

candidateverdictwhy
artifact repository - Artifactory, Nexus rawdoThe largest population of any candidate. An estate that refuses a git host and refuses a storage account still has an artifact repository, because that is how software gets into the estate at all - an approved egress path with an owner, a change record and a credential model already attached. It is a plain HTTP PUT and GET with a token, so the station needs nothing it does not already have
Google Cloud StoragedoThe object store transport signs SigV4, and GCS accepts SigV4 on its S3-compatible API. This may already work and be documented nowhere. One round trip decides it
OCI registrylaterAn estate that runs containers permits registry traffic by definition, and a registry has been a general artifact store since ORAS. Three HTTP calls and a sha256, so no new station dependency. It follows the artifact repository because that proves the same HTTP shape first
Microsoft Graph - SharePoint, OneDrivelaterThe only reach into an estate whose one sanctioned egress is Microsoft 365. A file share does not cover it, because that needs a mount and this is an API. It costs an OAuth refresh path nothing here has yet, and a second upload route for logs over 4MB
ServiceNow or Jira attachmentsmaybeIn a change-controlled estate the ticket is already where the operator is pasting half a terminal, so the log would land in the audit record rather than beside it. Two problems: a ticket is not a queue, and anyone who can attach a file could queue a request
AMQP, MQTT, KafkamaybeReal value where an estate already runs a broker. No pure-bash client exists for any of them, so the station would gain its first dependency and stop being readable before it is run
animated QR, screen to cameramaybeThe one channel left when removable media is banned and a screen is the only way out - a remote desktop session with the clipboard turned off is the ordinary case. A version 40 QR holds 2953 binary bytes per frame, which makes it three orders of magnitude faster than data over sound. It is asymmetric, though: a request is a few hundred bytes and fits in a single static code, while sending a log back needs the station to render animated frames, and that is a package and a display it does not have. The bundle covers the same population wherever a file can cross
data over sound - ggwave and similarnever8 to 16 bytes per second. A 50KB log is 53 minutes of uninterrupted clean audio, and this is a tool whose first rule is that a log is never truncated. It is also a C library needing an audio backend, so it breaks nothing is ever installed on the far side, and no container, pod, cloud container group or VM in the host table has a speaker or a microphone. Ultrasonic egress from an isolated machine is a documented attack technique, which puts it in the same bin as DNS
LoRa and Meshtasticnever84 bytes per second on the default preset and 2.7KB/s at the fastest, before packet headers, mesh hops and a 10% hourly duty cycle limit in Europe. It also needs a radio, and in most estates an unauthorised transmitter is a larger incident than an unauthorised network connection
rclone, Syncthing, croc, magic-wormholeneverEach is a binary or a daemon on the far side, which is the one thing this refuses. croc and magic-wormhole are also the relay again but worse, because both ends have to be online at the same moment and heliograph is store-and-forward on purpose. The useful version of this is a docs line: an operator who already runs rclone has a file share or an object store, and those transports work through it without heliograph needing to know
WebDAVneverThe right protocol for the job, and no population that has WebDAV and not one of the five above
Vault, Parameter Store, App ConfigurationneverA captured log does not fit in a parameter, and chunking one across secrets is a transport built to be abused by whoever finds it next
emailneverIt genuinely works in a mail-only air gap. It also carries a large operational burden - size limits at every relay, SPF and DKIM alignment, base64 inflation - for a small population
chat - Slack, TeamsneverCaptured logs in a chat system is a compliance problem, not a feature
DNSneverA covert channel. Shipping one would get the product banned from exactly the estates it is for
raw TCP, reverse tunnelneverA persistent reverse connection is a C2 channel by any blue team's definition, and not being one is a large part of why this class of tool is permitted at all. See security

Stations

candidateverdictwhy
AWS ECS Fargatedo, with an account to prove it onThe plainest gap in the product. There are five Azure templates and no AWS ones, while the comparison page argues against AWS SSM Run Command - so a reader arriving from that argument finds nothing to deploy. It maps onto the Container Instances template: same image, same environment, same transport selection. The condition is real: every Azure template here has been deployed live and torn down, and shipping an AWS one that has never started a station would be a row that looks authoritative and is not
AWS EC2do, with an account to prove it onMaps onto the Azure VM template, and its cloud-init.sh already exists. Same condition as Fargate
GitLab CIdoOne file, against the pattern pipelines already establishes, loop guard included. GitLab is the git host of choice across a large part of the regulated market
Kubernetes CronJobdoThe same image with --once, beside the Deployment containers already ships. It is what an estate that will not run a long-lived pod will accept
Arista EOSdoBash on an Arista switch is documented and supported, in every command mode but EXEC, with awk and egrep present. That is the host contract met with no new code - a proving exercise and a page. It waits on one of the curl-only transports, because git is usually absent and installing it is out of the question
AWS LambdalaterThe timer-not-a-loop pattern the Azure Function App already uses, ported
Cisco IOS-XE Guest ShelllaterA Linux container bundled with the image, enabled with guestshell enable, surviving a reload once enabled. Cisco's own warning is that a script producing high-volume output exhausts container memory and should redirect to a file, which is the capture contract doing its job on a device nobody wrote it for
NVIDIA Cumulus LinuxlaterDebian. It is a server that forwards packets
Google Cloud Run and Compute EnginelaterThe same shape as the AWS work, behind it because AWS is the larger gap
Ansible AWXlaterNot a host but a way to plant one. An ops team runs AWX precisely so that nobody needs SSH, and launching a job template is a permission somebody already has. The honest limit: AWX does not remove SSH, it moves it to the control plane
F5 BIG-IPmaybeBash beside tmsh, and a narrower population than the switches
JenkinsmaybeA third pipeline definition, once GitLab CI shows the pattern generalises
Termux on AndroidmaybeBash, GNU coreutils, a runit service manager and a start-on-boot addon: four of the five host contract points already present. Low commercial value and high evidential value, because a phone in a cabinet on a factory floor is a real station
Synology and QNAPmaybeDocker already covers it. A paragraph in the docs, not a template
OpenWrt, ESXi shell, appliancesmaybeThese have BusyBox ash and no bash, so supporting them means a third station implementation in POSIX sh - after bash and the PowerShell one that is not finished. Writing one file twice already produced six disagreements about the same file. A third comes after the second is done
z/OS UNIX System ServicesmaybeBash is maintained for it, and a mainframe is exactly the change-controlled, nobody-gets-a-login estate this is for. It is research rather than a plan because the whole capture contract is a byte-for-byte claim about a text file, and EBCDIC is a platform where even git converts encodings underneath you
IBM i PASE, AIX, SolarismaybeThe softer landing of the same family: ASCII throughout, bash from the package manager, and line endings as the documented hazard
microcontrollersneverNo process, no shell, no filesystem. Three of the five host contract points are absent, which makes it a different product rather than a port
iOS as a stationneverNo unattended background execution, and no shell an estate would sanction

Control nodes

The near side is the half a person actually touches, and two facts bound what can be one. The binary is already built static for six targets - Linux, macOS and Windows, on both amd64 and arm64. And only the git transport needs anything installed: the CLI shells out to git for that one, while the relay, the file share, the object store and the bundle are the binary and nothing else. A machine with no git can still drive an estate.

candidateverdictwhy
the near side without the CLIdoIt already works and is documented nowhere. A request is a key: value text file, so a laptop that permits git and refuses new binaries is a control node today - write the file, push it, read the log back out of the repository. It is the mirror of the bootstrap without a CLI on the far side
Android, through TermuxdoThe arm64 Linux binary is already built and git is a Termux package, so this is a check and a paragraph rather than a port. An on-call phone that can publish a step and read back a timestamped log is worth more than it sounds at 2am
ChromeOSdoCrostini is Linux. One line, once somebody has actually checked it
Claude Code on the webdoA far better fit than a remote MCP connector, because a cloud sandbox is a real shell - the CLI is a static binary, so it installs and runs with no protocol work at all. What stops it is not architecture: every web session gets a fresh sandbox behind an Anthropic-managed proxy allowlist, so a private git host, an internal artifact repository and the relay's own domain are all refused with blocked-by-allowlist, and a GitHub-hosted transport repository is the one combination likely to work today. Then two things the docs must say rather than gloss: the control credential would live in somebody else's cloud, and the estate directory is wiped between sessions
Homebrew, winget, scooplaterNot capability, distribution. Install covers a release binary, npm and an MCP bundle; these three are the gap
remote MCP, over Streamable HTTPlaterThe only route to a web or mobile control node. Claude's custom connectors reach a server from Anthropic's cloud even on Desktop, so a connector must be publicly reachable - and that endpoint would hold the transport credential, and on the relay the signing identity as well. A party able to forge a request has code execution inside every estate at once, which is the hazard the relay is built to refuse. It is possible only as a courier, with signing left on a device that holds the key. That is design work, not plumbing
a CI job as the control nodelaterSend a step on a schedule and fail the build on what the log says: continuous verification of a machine nobody can log into. No new code, one example workflow, and a genuinely new use of the near side
FreeBSDmaybeOne line in the target list, and no evidence anybody has asked
iOS and iPadOS nativelyneverNo way to ship a binary or run git. Reachable only through remote MCP, so it is that row rather than its own
a hosted web control planeneverTo be useful it must hold every estate's transport credential and signing key, which makes whoever operates it able to run commands inside every connected estate. That is precisely what the relay is architected not to be, and building one beside it would spend the claim

Where this is decided

The reasoning behind every row, including the sources and the open questions each candidate still has, is in the survey. What is being built now is in PLAN.md.

If your estate is a maybe and you need it, say so in an issue. A named engagement is exactly what moves a row up this page, and it is more useful than a vote.