Skip to content

broker push: sanitize machine names for base64 caller ids + start pushed VMs#60

Merged
Alexgodoroja merged 9 commits into
mainfrom
fix/smol-owner-name
Jul 2, 2026
Merged

broker push: sanitize machine names for base64 caller ids + start pushed VMs#60
Alexgodoroja merged 9 commits into
mainfrom
fix/smol-owner-name

Conversation

@Alexgodoroja

Copy link
Copy Markdown
Collaborator

Follow-up to #58 found by live install e2e: smol.push returned 400 for a caller whose base64 key contains +// in the first 8 chars (used in the cosmetic machine name). ownerName now sanitizes name portions to the cloud's [A-Za-z0-9_-] charset; the isolation tag env.PILOT_OWNER keeps the exact caller id (the cloud accepts +// in env values). Unit-tested; validated live against the deployed broker.

A caller id is base64 (may contain '+' '/' '='), but the smol cloud restricts
machine names to [A-Za-z0-9_-]. ownerName now sanitizes the name portions while
the isolation tag (env.PILOT_OWNER) keeps the exact caller id (the cloud accepts
'+'/'/' in env values, verified). Fixes a 400 on push for callers whose key has
'+' or '/' in the first 8 chars.
@Alexgodoroja Alexgodoroja changed the title broker: sanitize cloud machine names for base64 caller ids broker push: sanitize machine names for base64 caller ids + start pushed VMs Jul 2, 2026
Alex Godoroja added 4 commits July 2, 2026 15:51
smol.push now starts the created cloud machine (POST /v1/machines/<id>/start) so
a pushed VM runs in the cloud and accrues usage; a start failure is non-fatal
(the machine still exists). refcloud implements the start action; e2e accepts
200 (started) or 201 (created).
smol.push accepts {net:true} to create the cloud machine with network mode
'open' (mirroring smolvm's --net); default stays off (network blocked).
- derived key binds a per-user rotation counter (rot); bumping one user's rot
  revokes their old key WITHOUT touching others and WITHOUT resetting credit
  (credit is keyed by the caller, not the key)
- ProvisionStore gains Get + Rotate (sqlite migrates rot in); provision returns rot
- serveKey (GET /_key), serveRotate (POST /_rotate) — signature-authed, so a
  leaked key alone can't rotate or lock out the owner
- cloud methods (push/list) accept the derived key as a Bearer credential OR a
  signature, so an agent can use its key directly; identity routes require the sig
- tests: rotate→new key, old key 401, credit preserved, bearer push/list, leaked
  key can't rotate
…ethods

- <ns>.help now groups methods by plane (local vs cloud), labels each cloud
  method's credit cost, and includes a pricing block (cost model + free credits +
  the cloud rate card) so an agent sees cost before a paid call
- scaffold Config.Pricing + Method.Plane(); submission gains a pricing block
- adapter: cloud.go refreshes $APP/secrets.json when a response carries a new key
  (rotate/key), so the cached key always matches the broker
- io.pilot.smol submission: add smol.key (get) + smol.rotate methods + pricing
  (rates procured from the live smol console)
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

A/B report — io.pilot.smol (vanilla vs Pilot)

Equivalent commands run two ways: the vanilla CLI binary vs the Pilot adapter (socket mode). CI runs non-VM commands only (GitHub runners have no KVM). Full HTML report (commands, outputs, timings, adapter-generated help): download from the run artifacts.

Command Vanilla ms Pilot ms Δ Exit match
Version 7 9 +2
Top-level help 7 10 +3
machine --help 6 9 +3
pack --help 6 9 +3
config --help 6 9 +3

Alex Godoroja added 4 commits July 2, 2026 16:28
…o); comprehensive help

- meter.go: a loop attributes each running machine's cost (resources × rate card
  × elapsed) to its owner in micro-USD and STOPS the owner's machines at zero —
  agents get exactly what they pay for. ProvisionSpec gains rate card + interval;
  cmd/broker runs the meter; servePush gates on positive credit
- smol.push starts the VM (already) and is now billed by usage, not flat per-push
- help: smol.exec documents the FULL smolvm CLI surface (all machine/pack/serve/
  config commands + flags + defaults + behaviors) so smol.help alone is enough to
  use/debug the app; pricing shows the usage model + $5 free credit + rate card
- deploy/smol-broker/apps.json: seed $5 (micros), rate card, 60s meter interval
- tests: meter drains-and-stops + partial-charge-keeps-running
…okenmint

Restore internal/broker coverage above the 78% gate: full masterKeyProvider
surface (push+start/artifact/list/AllOwned/Stop), RunMeter one-tick
drain+stop, store Get/Rotate on mem+sqlite, and the dormant tokenmint data plane.
- fakeProvider is now mutex-guarded (RunMeter drives it concurrently) — full
  -race suite is clean
- e2e-provision.sh adds the key lifecycle: smol.key, bearer-credential use,
  leaked-key-can't-rotate, rotate-preserves-credit, old-key-revoked
- go test -race ./... green; e2e-provision (14 checks) + e2e-broker pass
@Alexgodoroja Alexgodoroja merged commit 948c3c4 into main Jul 2, 2026
7 checks passed
@Alexgodoroja Alexgodoroja deleted the fix/smol-owner-name branch July 2, 2026 23:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant