Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions .github/workflows/deploy-catalogue-site.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Deploy app catalogue site

# Publishes the static app-store catalogue site to GitHub Pages. The page
# renders the live catalogue.json (copied alongside it, so the fetch is
# same-origin), and redeploys whenever the catalogue or the site changes.

on:
push:
branches: [main]
paths:
- "catalogue/**"
- ".github/workflows/deploy-catalogue-site.yml"
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

# Allow one concurrent deployment; let an in-progress run finish.
concurrency:
group: pages
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Assemble site
run: |
set -euo pipefail
mkdir -p _site
cp catalogue/site/index.html _site/index.html
# Copy the catalogue + detached signature so the page fetches
# them same-origin (no CORS dependency on raw.githubusercontent).
cp catalogue/catalogue.json _site/catalogue.json
cp catalogue/catalogue.json.sig _site/catalogue.json.sig
# Fail loudly if the catalogue is missing/empty.
test -s _site/catalogue.json

- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: _site

deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
66 changes: 66 additions & 0 deletions catalogue/apps/io.pilot.smolmachines/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"schema_version": 1,
"id": "io.pilot.smolmachines",
"display_name": "Smol Machines",
"tagline": "Fast, hardware-isolated microVMs on demand",
"description_md": "Smol Machines — the app-store front door for the smolmachines VM engine. It lets an agent spin up fast, hardware-isolated Linux microVMs on demand (sub-second boot, real hypervisor isolation — not shared-kernel containers), then run workloads in a disposable sandbox. Free to use. Portable .smolmachine artifacts run identically on macOS and Linux, locally or in the cloud.\n\nUse it to:\n- Run untrusted or AI-generated code safely, with networking off by default\n- Give an agent a real Linux shell — a stateful, isolated execution backend\n- Automate headless browsers (GPU-accelerated) for scraping, screenshots, and web tasks\n- Run GPU/compute jobs via Vulkan with container-like speed\n- Spin up disposable dev sandboxes — a clean VM per task, torn down after\n- Keep persistent dev VMs — installed packages survive restarts\n- Run CI-style jobs — build, test, lint in clean environments\n- Fan out parallel ephemeral workers thanks to sub-second boot\n- Analyze malware / suspicious files in a throwaway environment\n- Build once, run anywhere — same artifact local, cloud, or self-hosted\n\nDiscover the live method surface at runtime with smolmachines.help, which lists each method's parameters and latency class.",
"vendor": {
"name": "smol machines",
"url": "https://smolmachines.com",
"publisher_pubkey": "ed25519:3QJm6H6OdjtfrF+Es1lrRjfFmdtq2tGvVSWxia63vcI="
},
"homepage": "https://smolmachines.com",
"source_url": "https://github.com/smol-machines/smolvm",
"license": "Apache-2.0",
"categories": [
"dev",
"virtualization",
"security"
],
"keywords": [
"microvm",
"sandbox",
"vm",
"isolation",
"gpu",
"ci"
],
"size": {
"bundle_bytes": 5346146,
"installed_bytes": 9601119
},
"compat": {
"min_pilot_version": "1.0.0",
"runtimes": [
"go"
]
},
"methods": [
{
"name": "smolmachines.exec",
"summary": "Run any smolvm subcommand in a fast, hardware-isolated Linux microVM. Payload is {\"args\":[...]} — the verbatim smolvm argv. Command surface: `machine run` (ephemeral VM, one-off command), `machine create|start|exec|stop|delete|shell|status|ls|cp|update|monitor|prune` (persistent VMs; `exec` persists filesystem changes), `pack create|run` (portable .smolmachine artifacts), `serve` (HTTP API), `config`. Key flags: `--net` (networking is OFF by default), `--image <oci|./archive.tar|->`, `-v HOST:GUEST`, `-p HOST:GUEST`, `--gpu`, `--ssh-agent`, `--secret-env GUEST=HOST`. Example args: [\"machine\",\"run\",\"--net\",\"--image\",\"alpine\",\"--\",\"sh\",\"-c\",\"echo hi\"]. Not supported over IPC: interactive sessions (-it / `machine shell`) and long-running `serve`."
},
{
"name": "smolmachines.help",
"summary": "Discovery: every method with params, kind, and latency class."
}
],
"changelog": [
{
"version": "1.2.0",
"notes": [
"Released v1.2.0"
]
}
],
"links": [
{
"label": "Source",
"url": "https://github.com/smol-machines/smolvm"
},
{
"label": "Website",
"url": "https://smolmachines.com"
}
]
}
270 changes: 270 additions & 0 deletions cmd/control-agent/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
// SPDX-License-Identifier: AGPL-3.0-or-later

// Command control-agent is a headless reference node for Pilot's optional
// hosted control plane. It runs the same enterprisecontrol runtime as the Web4
// daemon without opening a Pilot transport, making signed fleet operations
// usable beside any agent harness. It intentionally exposes no remote shell.
package main

import (
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"flag"
"fmt"
"os"
"os/signal"
"path/filepath"
"syscall"
"time"

"github.com/pilot-protocol/common/actionhook"
"github.com/pilot-protocol/common/authority"
"github.com/pilot-protocol/pilotprotocol/internal/enterprisecontrol"
)

type evidenceEvent struct {
Event string `json:"event"`
CommandID string `json:"command_id,omitempty"`
Detail string `json:"detail,omitempty"`
PID int `json:"pid"`
RuntimeVersion string `json:"runtime_version"`
ObservedAt int64 `json:"observed_at"`
}

type diagnosticRecord struct {
Version uint16 `json:"version"`
CommandID string `json:"command_id"`
Hostname string `json:"hostname"`
PID int `json:"pid"`
UID int `json:"uid"`
RuntimeVersion string `json:"runtime_version"`
PolicyRevision uint64 `json:"policy_revision"`
StartedAt int64 `json:"started_at"`
ObservedAt int64 `json:"observed_at"`
}

func main() {
controlPath := flag.String("enterprise-control", "", "path to the signed enterprise control attachment")
runtimeVersion := flag.String("runtime-version", "pilot-control-agent/1.0.0", "reported runtime version")
nodeID := flag.Uint("node-id", 1001, "reported Pilot node ID")
poll := flag.Duration("poll-interval", 2*time.Second, "fleet control poll interval")
evidenceDirectory := flag.String("evidence-dir", "", "owner-only directory for tangible lifecycle and diagnostic evidence")
flag.Parse()
if *controlPath == "" || *evidenceDirectory == "" || *poll < 250*time.Millisecond || *poll > time.Minute || *nodeID == 0 || *nodeID > uint(^uint32(0)) {
fatalf("enterprise-control, evidence-dir, a node ID, and a 250ms-1m poll interval are required")
}
if err := os.MkdirAll(*evidenceDirectory, 0o700); err != nil {
fatalf("create evidence directory: %v", err)
}
controls, err := enterprisecontrol.Load(*controlPath)
if err != nil {
fatalf("load enterprise controls: %v", err)
}
started := time.Now().UTC()
if err := appendEvidence(*evidenceDirectory, evidenceEvent{Event: "startup", PID: os.Getpid(), RuntimeVersion: *runtimeVersion, ObservedAt: started.Unix()}); err != nil {
fatalf("record startup: %v", err)
}
if err := runTangibleHook(context.Background(), controls, *evidenceDirectory); err != nil {
fatalf("run tangible action hook: %v", err)
}

ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer cancel()
ticker := time.NewTicker(*poll)
defer ticker.Stop()
for {
lifecycle, err := synchronize(ctx, controls, uint32(*nodeID), *runtimeVersion, started, *evidenceDirectory)
if err != nil && ctx.Err() == nil {
_, _ = fmt.Fprintf(os.Stderr, "pilot-control-agent: synchronize: %v\n", err)
}
switch lifecycle {
case "restart":
if err := appendEvidence(*evidenceDirectory, evidenceEvent{Event: "restart_requested", PID: os.Getpid(), RuntimeVersion: *runtimeVersion, ObservedAt: time.Now().UTC().Unix()}); err != nil {
fatalf("record restart: %v", err)
}
executable, err := os.Executable()
if err != nil {
fatalf("resolve executable: %v", err)
}
if err := syscall.Exec(executable, os.Args, os.Environ()); err != nil {
fatalf("restart process: %v", err)
}
case "shutdown":
if err := appendEvidence(*evidenceDirectory, evidenceEvent{Event: "shutdown_requested", PID: os.Getpid(), RuntimeVersion: *runtimeVersion, ObservedAt: time.Now().UTC().Unix()}); err != nil {
fatalf("record shutdown: %v", err)
}
return
}
select {
case <-ctx.Done():
_ = appendEvidence(*evidenceDirectory, evidenceEvent{Event: "signal_shutdown", PID: os.Getpid(), RuntimeVersion: *runtimeVersion, ObservedAt: time.Now().UTC().Unix()})
return
case <-ticker.C:
}
}
}

func synchronize(ctx context.Context, controls *enterprisecontrol.Runtime, nodeID uint32, runtimeVersion string, started time.Time, evidenceDirectory string) (string, error) {
reconciliation, err := controls.ReconcileFleetControl(ctx, runtimeVersion)
if err != nil {
return "", err
}
if reconciliation.Found {
if err := controls.ReportFleetControlAcknowledgement(ctx, reconciliation, runtimeVersion); err != nil {
return "", err
}
}
status := enterprisecontrol.FleetNodeStatus{
NodeID: nodeID, AgentVersion: runtimeVersion, UptimeSeconds: uint64(time.Since(started).Seconds()),
PolicyRevision: controls.CurrentPolicyRevision(ctx),
}
if err := controls.ReportFleetStatus(ctx, status); err != nil {
return "", err
}
commands, err := controls.FleetCommands(ctx)
if err != nil {
return "", err
}
for _, command := range commands {
outcome, detail, lifecycle := executeCommand(ctx, controls, command, runtimeVersion, started, evidenceDirectory)
if err := controls.ReportFleetCommandResult(ctx, command.ID, outcome, detail); err != nil {
return "", err
}
if err := appendEvidence(evidenceDirectory, evidenceEvent{Event: "command_result", CommandID: command.ID, Detail: string(command.Kind) + ":" + outcome + ":" + detail, PID: os.Getpid(), RuntimeVersion: runtimeVersion, ObservedAt: time.Now().UTC().Unix()}); err != nil {
return "", err
}
if outcome == "succeeded" && lifecycle != "" {
if err := controls.MarkLifecycleCommandApplied(command); err != nil {
return "", err
}
return lifecycle, nil
}
}
return "", nil
}

func executeCommand(ctx context.Context, controls *enterprisecontrol.Runtime, command authority.FleetCommand, runtimeVersion string, started time.Time, evidenceDirectory string) (string, string, string) {
switch command.Kind {
case authority.FleetCommandRefreshPolicy:
if err := controls.RefreshRollout(ctx); err != nil {
return "failed", "rollout_refresh_failed", ""
}
return "succeeded", "policy_refreshed", ""
case authority.FleetCommandExportReceipts:
if !controls.HasReceiptExport() {
return "rejected", "receipt_export_unconfigured", ""
}
if err := controls.ExportReceiptsOnce(ctx); err != nil {
return "failed", "receipt_export_failed", ""
}
return "succeeded", "receipts_exported", ""
case authority.FleetCommandReloadControl:
if err := controls.Reload(); err != nil {
return "failed", "control_reload_failed", ""
}
return "succeeded", "control_reloaded", ""
case authority.FleetCommandSyncState:
if !controls.HasFleetStateSync() {
return "rejected", "state_sync_unconfigured", ""
}
if _, err := controls.SyncFleetState(ctx); err != nil {
return "failed", "state_sync_failed", ""
}
return "succeeded", "state_synchronized", ""
case authority.FleetCommandDiagnostics:
if controls.HasFleetStateSync() {
if _, err := controls.SyncFleetState(ctx); err != nil {
return "failed", "diagnostics_sync_failed", ""
}
}
if err := writeDiagnostics(evidenceDirectory, command.ID, runtimeVersion, controls.CurrentPolicyRevision(ctx), started); err != nil {
return "failed", "diagnostics_write_failed", ""
}
return "succeeded", "diagnostics_written", ""
case authority.FleetCommandRestartRuntime:
if controls.LifecycleCommandAlreadyApplied(command) {
return "rejected", "already_applied", ""
}
return "succeeded", "restart_accepted", "restart"
case authority.FleetCommandShutdownRuntime:
if controls.LifecycleCommandAlreadyApplied(command) {
return "rejected", "already_applied", ""
}
return "succeeded", "shutdown_accepted", "shutdown"
default:
return "rejected", "command_not_allowlisted", ""
}
}

func runTangibleHook(ctx context.Context, controls *enterprisecontrol.Runtime, evidenceDirectory string) error {
hook := controls.ActionHook()
if hook == nil {
return fmt.Errorf("managed action hook is not configured")
}
target := filepath.Join(evidenceDirectory, "hook-side-effect.txt")
if _, err := os.Stat(target); err == nil {
return nil
} else if !errors.Is(err, os.ErrNotExist) {
return err
}
content := []byte("Pilot managed action hook released this tangible file write.\n")
digest := sha256.Sum256(content)
envelope, err := actionhook.NewEnvelope("file.write", "workspace:control-agent/hook-side-effect.txt", hex.EncodeToString(digest[:]), "pilot.control-agent", map[string]string{"content_type": "text/plain"}, time.Now().UTC())
if err != nil {
return err
}
preflight, err := hook.BeforeAction(ctx, envelope)
if err != nil {
return err
}
if err := preflight.RequireUnconstrained(); err != nil {
return err
}
if err := os.WriteFile(target, content, 0o600); err != nil {
return err
}
if err := hook.AfterAction(ctx, envelope, preflight, actionhook.ObservedResult{Status: actionhook.StatusSucceeded, ObservedAt: time.Now().UTC().Unix()}); err != nil {
return err
}
return appendEvidence(evidenceDirectory, evidenceEvent{Event: "managed_hook_side_effect", Detail: "file.write:allow", PID: os.Getpid(), RuntimeVersion: "pilot-control-agent/1.0.0", ObservedAt: time.Now().UTC().Unix()})
}

func writeDiagnostics(directory, commandID, runtimeVersion string, policyRevision uint64, started time.Time) error {
hostname, err := os.Hostname()
if err != nil {
return err
}
record := diagnosticRecord{Version: 1, CommandID: commandID, Hostname: hostname, PID: os.Getpid(), UID: os.Getuid(), RuntimeVersion: runtimeVersion, PolicyRevision: policyRevision, StartedAt: started.Unix(), ObservedAt: time.Now().UTC().Unix()}
return writeSecureJSON(filepath.Join(directory, "diagnostics-"+commandID+".json"), record)
}

func appendEvidence(directory string, event evidenceEvent) error {
path := filepath.Join(directory, "control-events.jsonl")
file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600)
if err != nil {
return err
}
encodeErr := json.NewEncoder(file).Encode(event)
closeErr := file.Close()
return errors.Join(encodeErr, closeErr)
}

func writeSecureJSON(path string, value any) error {
encoded, err := json.MarshalIndent(value, "", " ")
if err != nil {
return err
}
encoded = append(encoded, '\n')
if err := os.WriteFile(path, encoded, 0o600); err != nil {
return err
}
return os.Chmod(path, 0o600)
}

func fatalf(format string, arguments ...any) {
_, _ = fmt.Fprintf(os.Stderr, "pilot-control-agent: "+format+"\n", arguments...)
os.Exit(1)
}
Loading
Loading