Repository navigation
v0.17.0 - Hardening the stack
A hardening release on top of v0.16.0, plus a tidy-up of how the stack is built. It tightens the paid-request path, how secrets and wallets are stored and backed up, what the public storefront serves, and every command that can destroy a cluster. The dashboard now lives in this repo, and obol network status gets a proper redesign along with obol network stop / start. Several features change behaviour to get there: we're in v0 and would rather be safe by default than keep a risky path working.
Warning
This software is early alpha, you could lose what you put in. Please use caution when it comes to non-testnet assets. Back up before upgrading: obol stack export --file backup.tar.gz.
Install / Upgrade
# Fresh install
curl -fsSL https://stack.obol.org/v0.17.0 | bash
obol stack init && obol stack up
# Upgrade an existing stack
curl -fsSL https://stack.obol.org/v0.17.0 | bash
obol stack up
obol doctorRelease Highlights
Paid requests
- One payment, one request. A signed payment can only be used once. Sending the same payment again, or several copies at once, gets
409 payment_in_usebefore it reaches your service. If a request fails before settlement, the buyer can retry with the same payment. - Exact prices. Prices are parsed exactly, down to the token's own precision (6 decimal places for USDC, 18 for OBOL). Zero, negative and malformed prices are refused by the CLI and by the ServiceOffer schema. Per-MTok prices always round up to at least the smallest token unit.
- Buyers set a ceiling.
buy.py pay,pay-agentandgorefuse any quote above--max-price(default: 1 token, orOBOL_BUY_MAX_PRICE). Generated buy commands add the flag when an offer costs more. obol buyfollows only safe catalog links. A seller's catalog can only send you to its own origin or to a public https hostname.
Selling a host inference server
obol sell inference is now standalone-only. On a machine with a stack, it stops and prints the supported path instead:
obol model setup custom --endpoint http://<host>:<port>/v1 --model <id>
obol sell http <name> --upstream litellm --port 4000 --namespace llm --model <id> --per-mtok <price>That path pins the model, limits buyers to the chat, completions and embeddings endpoints, and only charges for replies that deliver something. Use --standalone to run the gateway on its own regardless. The standalone gateway now serves only its paid routes and /health; everything else returns 404.
Secrets, wallets and backups
- Keystores, passwords, tokens and the kubeconfig are always written owner-only (0600), even when a file already existed with looser permissions.
- Wallets survive export/import.
obol stack exportcaptures every agent wallet and names each one by address, warning loudly about any it couldn't capture.obol stack importre-creates each agent's keystore from the archive's wallet backup, checking it decrypts to the recorded address first (--passphrase, or a prompt), so a stack restored on a new machine comes up with its signing keys. The passphrase is checked before anything is restored: a wrong or missing one stops the import. obol stack importrestores files owner-only, won't overwrite existing agent data without--force, and is protected against oversized archives. Exports now include your hand-edited defaults.obol stack exportarchives are owner-only.
Storefront and public endpoints
- Branding text (display name, tagline, registration name) must be plain text: no angle brackets or control characters. The storefront page escapes everything it embeds.
- Job status pages report upstream failures generically; details go to the server logs.
- Sign-in links use the right scheme on local hosts.
Safer cluster commands
- Destroying a cluster always asks. Switching backends with
obol stack init --forceasks before deleting the old cluster (or needs--yes), even when nothing looks live or the cluster can't be reached. Ifobol stack downcan't stop a cluster, it no longer quietly deletes it. - Your edits to the defaults are kept.
obol stack upno longer overwrites hand-edited files under the defaults tree. When a new default ships for a file you changed, it's saved todefaults.obol-new/and you get a warning.obol stack up --reset-defaultstakes the new defaults and backs your edits up first. - k3s backend: obol only stops the k3s process it started, checked by PID and start time.
Truthful status
obol tunnel statussaysdegradedwhen the public URL isn't reachable.- Agents with a wallet are Ready only once their signer is running; purchases show
BuyerUnavailablewhile the buyer can't be reached. - ERC-8004 metadata and URI updates fail loudly if the transaction reverts, and recovering a previous registration checks the wallet still owns it.
Installer (obolup)
- Tools (kubectl, helm, k3d, helmfile, k9s, helm-diff) are installed by
obolfrom checksum-pinned downloads. - Without a terminal, the installer never waits on a prompt: it picks the safe option and prints the command for later.
- Ollama is installed only if you say yes (or set
OBOL_INSTALL_OLLAMA=true);--yesalone no longer installs it. - Steps that need sudo are skipped with exact instructions when sudo can't ask for a password.
- No "start the stack?" question when your stack is already running.
Node operations
obol network status is redesigned:
- The RPC gateway table shows, per chain, your local node and remote upstreams, and which one is actually serving requests right now.
- Syncing reth nodes show their pipeline stages (Headers, Bodies, Execution, …) with progress, instead of
syncing 0/0; Lighthouse shows its sync state and backfill. - Problems are reported once with a cause and a hint, e.g.
Restarting — OOMKilled 9× (last 3m ago). - A Grafana link per node, and exit code 3 when a node is degraded, so it's scriptable.
--watchredraws in place with rates and ETAs;-o json --watchstreams one JSON object per tick.
obol network status --watch
obol network stop ethereum/mainnet # scale to zero, keep the data, RPC falls back to remote
obol network start ethereum/mainnetExecution and consensus clients now request memory and CPU sized for their network and mode, so the scheduler (and you) can see a node's footprint. Override with --execution-memory / --consensus-memory at install, or executionMemory / consensusMemory in the node's values.yaml.
One repo
The dashboard (previously obol-stack-front-end) now lives in this repository under web/frontend and is built and released with the CLI. OBOL_DEVELOPMENT=true obol stack up builds it locally like the other images. CI runs one workflow that only checks the parts a change touches, and every embedded CRD is now applied to a real Kubernetes API server in CI.
Smaller wins
- Partial archives say what they keep -
obol network listandstatusshowarchive since cancun (block 19,426,587)orarchive, last 365d, and JSON gainsarchive_scope. obol doctorwarns about an exposed Ollama - on Linux, when Ollama listens on every interface, with a firewall rule to limit it to Docker.buy.py goworks on chat and agent offers again, andbuy.py pay --datasends a POST with the body.- One payment option per currency in 402 responses.
obol doctorcounts the default agent's wallet.
Breaking changes / Migration notes
obol sell inferencewith a stack now refuses. Re-create those offers with the LiteLLM recipe above. On upgrade, old cluster-routed inference offers aren't resumed;obol sell delete <name> -n <ns>cleans them up. If a gateway started by an older release is still running, obol tells you its PID so you can stop it.- Zero prices are rejected (
--per-request 0). Use free routes (--route path=/x,gate=free) for free endpoints. - One request per payment on verify-only routes. A payment verified through the ForwardAuth
/verifypath now opens exactly one request. - Hermes messaging gateway is closed by default (
GATEWAY_ALLOW_ALL_USERS=false). If you connect Telegram, Discord or another platform, set that platform's allowlist. stack importover existing agent data needs--force. An import whose wallet backup can't be decrypted now stops with nothing restored;--skip-walletsrestores everything else without those keys.- First
obol stack upafter upgrading backs up any defaults file that differs from the new version todefaults.bak.<timestamp>/once, then keeps your edits from then on. obolup.sh --yesno longer installs Ollama.- ServiceOffers accept at most 16 payment options (and 128 routes).
- Node pods restart once on their next
obol network syncto pick up the new resource requests. A mainnet node now requests roughly 14–18 GiB; on a small Docker VM it may stay Pending (status explains how to lower the request). obol network statusJSON adds fields;erpc.podis nowerpc.pods[].
Known issues
- Gloas on testnets: as in v0.16.0, use
--consensus-client teku,lodestar,nimbusorprysmon Sepolia and Hoodi. - Ollama on Linux still has to listen beyond localhost so the cluster can reach it;
obol doctorexplains how to firewall it. A tighter setup is planned.
What's Changed
- chore(deps): update obolup.sh dependency updates by @github-actions[bot] in #822
- ci: register the front-end image workflow (dispatch-only) by @OisinKyne in #887
- feat(frontend): bring obol-stack-front-end into monorepo by @OisinKyne in #888
Full Changelog: v0.16.0...v0.17.0
