Precompiled Synchronicity socket programs. Sources live in src/, deployable
BPF ELF objects in objects/; both are committed. No compiler is needed to use
them. These run inside Synchronicity's socket runtime, not the Linux kernel.
| Program | Behavior | Access |
|---|---|---|
echo |
Echoes binary streams with backpressure; 30-second idle timeout | Any caller able to connect; 16 concurrent streams |
whoami |
Prints authenticated origin, device key and peer kind, then closes | Any caller able to connect; 8 concurrent streams |
tcp-proxy |
Bidirectional TCP forwarding to 127.0.0.1 on a configured port |
Same peer allowlist as SSH; 32 concurrent connections |
ssh-shell |
Interactive /bin/bash with PTY; read/write SFTP under files |
Configured origins or node public keys; 4 concurrent connections, one session per connection |
Built against the SDK revision in UPSTREAM.md. Review the capabilities shown when activating a socket. Existing Synchronicity membership/delegation checks still apply to every connection.
Run on the serving node, using an existing space such as code:
synch fetch https://raw.githubusercontent.com/AFK-surf/sykit/main/objects/echo.o code/echo.sock
synch socket activate code/echo.sockFrom a connected node:
printf 'hello\n' | synch socket connect nas:code/echo.sockTo inspect a connecting node's authenticated peer-key, deploy whoami:
synch fetch https://raw.githubusercontent.com/AFK-surf/sykit/main/objects/whoami.o code/whoami.sock
synch socket activate code/whoami.sockConnect with synch socket connect nas:code/whoami.sock for identity diagnostics.
Its peer-key output is hex; the SSH allowlist below uses z-base-32.
Set allowed_peers to a comma-separated list of authenticated peer origins
and/or node public keys:
- Origins use
host@domain, as shown bysynch id. Matching uses the authenticated origin, never connection metadata. ASCII case is normalized and trailing domain dots are removed; wildcards are not supported. - Public keys use the 52-character, unpadded z-base-32 node ID printed by
synch id(alphabetybndrfg8ejkmcpqxot1uwisza345h769, not RFC 4648 base32). Either case is accepted; hex and=padding are rejected.
Spaces, tabs and newlines around entries are allowed. Quote values containing whitespace. Use at most 16 peers and 1023 bytes of configuration. Empty or malformed entries invalidate the entire list, even after an entry matches. Missing configuration or a caller absent from the list rejects the connection before SSH starts.
synch fetch https://raw.githubusercontent.com/AFK-surf/sykit/main/objects/ssh-shell.o code/ssh.sock
synch socket activate code/ssh.sock --config 'allowed_peers=laptop@example.com,BASE32_NODE_PUBLIC_KEY'A single origin or key needs no comma. allowed_node_key is no longer read;
existing activations must switch to allowed_peers when deploying this version.
An origin rule follows whichever node key the membership system authenticates
for that name, including key rotation. A public-key rule pins one device key
regardless of its origin. Verify the peers and the origin's membership authority
before granting shell access.
For a tree-backed allowlist, create a text file with one origin or public key per line, for example:
laptop@example.com
workstation@example.com
BASE32_NODE_PUBLIC_KEY
Publish it into the serving node's tree and configure its path:
synch put ssh-allowlist.txt code/ssh-allowlist.txt
synch socket activate code/ssh.sock --config allowlist=code/ssh-allowlist.txtConfigure exactly one of allowed_peers or allowlist. With allowlist, the
server reads the selected tree file for every new connection; changing its
contents requires no socket rebuild. Each connection reads one object snapshot.
Existing SSH sessions are not revoked by later changes. Protect writes to this
path: anyone who can change this file can grant shell access as the daemon's
OS account. Consider this when selecting a path writable through SFTP.
Files may contain up to 64 KiB and 1,024 nonblank peer entries, with at most 1,023 bytes per line before the LF. CRLF, blank lines, surrounding whitespace and a final line without a newline are supported. Comments and comma-separated entries are not supported in files. The entire file must be valid; missing, unreadable, oversized, malformed or incompletely read files deny access. Reading has a 10-second total deadline. Both source settings together also deny access; a failed file read never falls back to inline peers.
From an allowed node:
ssh -tt -o 'ProxyCommand=synch socket connect %h:code/ssh.sock' nas
sftp -o 'ProxyCommand=synch socket connect %h:code/ssh.sock' nasKeep normal SSH host-key verification enabled. The inner SSH exchange accepts
none only after the outer authenticated node passes the gate. The SSH
username does not select an OS user: the shell runs as the Synchronicity daemon
account, with that account's host access. Anyone controlling an allowed node
and able to use its Synchronicity identity can obtain that access.
SFTP can recursively read, create, replace and delete within the declared
files tree scope; writes commit on close, bounded to 16 MiB per commit. This
scope limits SFTP, not the shell's filesystem access. The serving node must
have /bin/bash and the intended files space. SSH exec commands, environment
requests and forwarding are rejected; use an interactive PTY for the shell.
SSH connections use the runtime's configured deadlines and resource limits.
To change the executable or SFTP scope, edit the source defaults and rebuild; review the resulting manifest. Do not grant untrusted callers write access to an activated socket path: replacing its bytes deploys a new program immediately. Activation configuration stays on the serving node; it is not embedded in the published object.
tcp-proxy forwards an authenticated Synchronicity stream to a TCP service on
the serving node. It uses the same allowed_peers or tree-backed allowlist
settings described above, and checks authorization before connecting upstream.
synch fetch https://raw.githubusercontent.com/AFK-surf/sykit/main/objects/tcp-proxy.o code/tcp-proxy.sock
synch socket activate code/tcp-proxy.sock --config 'allowed_peers=laptop@example.com' --config upstream_port=8080Or use a tree allowlist:
synch socket activate code/tcp-proxy.sock --config allowlist=code/tcp-allowlist.txt --config upstream_port=8080From an allowed node, expose the service to local applications:
synch socket connect nas:code/tcp-proxy.sock --listen 127.0.0.1:18080For an HTTP service, open http://127.0.0.1:18080. The proxy carries arbitrary
TCP bytes; it does not terminate TLS, interpret HTTP, or send a PROXY-protocol
header. Applications using the local listener share the forwarding node's
identity. The two stream directions drain independently, so a half-close does
not truncate a pending reply.
upstream_port is required and must be decimal 1–65535. The committed object
pins its upstream host to 127.0.0.1; its manifest declares that host with all
ports permitted, while activation config selects one port. Caller metadata and
payload cannot override either. To use a different host, change UPSTREAM_HOST
in src/tcp-proxy.c, rebuild, and review its changed egress declaration.
Allowlisted nodes receive full protocol access to the selected service, so
protect the activation config, socket path and any allowlist file.
The runtime's idle and resource limits apply. Program exit codes are 0 for clean completion, 1 for denied authorization, 2 for invalid/missing port config, and 3 for connection or forwarding failure.
./scripts/test.sh
./scripts/build.sh
./scripts/build.sh --checkRequires Docker, or CONTAINER_ENGINE=podman. The Dockerfile pins the Ubuntu
image digest, compiler host to linux/amd64, and signed Ubuntu package snapshot
to 20260901T000000Z. ARM hosts need amd64 emulation; Docker Desktop includes
it. Outputs target little-endian BPF v3 and work on supported Synchronicity
hosts regardless of their CPU architecture. Compilation uses clang 18, fixed
paths and locale, no debug data, and 16 KiB stack frames. Builds compile only
checked-in inputs and extract /artifacts from the exact image produced by
that build. The test script requires a C compiler and Python 3.
--check rebuilds into a temporary directory and compares every byte and the
complete output file set with objects/. Commit changed .c, headers, .o
and SHA256SUMS together. Checksums detect changes; obtain this repository from
a trusted source. CI checks authentication and artifact reproducibility.
For runtime integration tests against a local Synchronicity checkout, see
tests/runtime.rs and scripts/test-runtime.sh.
See SECURITY.md for the security review, regression coverage and trust assumptions.