Skip to content

Releases: askalf/agent

v3.4.3

14 Jun 13:00
e45b5d7

Choose a tag to compare

Documentation

  • --help now lists every connect flag. The built-in help and the README options table were missing --install, --insecure, and the Cloudflare Access service-token flags (--cf-access-id / --cf-access-secret) added in 3.4.0–3.4.1 — they worked but were undiscoverable. Added them, plus an example for connecting through Cloudflare Access.
  • README documents the security layer. Added a Security section covering the default dangerous-command blocklist, output sanitization, the ~/.askalf/audit.log audit trail, and the optional ~/.askalf/policy.json (requireApproval, trustedAgents, blockedPatterns, allowedPaths) — shipped in 3.4.0 but never documented in the README. Corrected the "5-minute subprocess timeout" line (shell tasks are capped at 5 min, Claude Code tasks at 10).

v3.4.2

12 Jun 00:20
4983be8

Choose a tag to compare

Fixed

  • --url is now required instead of defaulting to wss://askalf.org. askalf is self-hosted — every deployment runs its own forge — so there is no valid universal default. The old default pointed at the marketing site (not a forge), so a connect <key> without --url silently dialed the wrong host and failed with an opaque WebSocket error. connect now exits with a clear "Missing --url" message (and an example) when no URL is given. The --from-config path used by the installed service is unaffected (it reads the saved URL). Help text, usage strings, and README updated to match.

v3.4.1

11 Jun 00:52
122b99e

Choose a tag to compare

Added

  • Cloudflare Access service-token support. When the bridge URL sits behind a Cloudflare Access application (e.g. a self-hosted forge exposed via cloudflared), the WebSocket upgrade is 302-redirected to the SSO login at the edge unless the request carries a valid service token — so a remote agent could never connect, only same-host agents reaching the bridge over loopback. The agent now sends CF-Access-Client-Id / CF-Access-Client-Secret headers (alongside the bridge bearer auth) when configured via --cf-access-id / --cf-access-secret flags or the CF_ACCESS_CLIENT_ID / CF_ACCESS_CLIENT_SECRET environment variables. The secret is persisted to agent.json encrypted at rest like the API key (the id is not sensitive); connect --from-config (used by the installed service) restores both, so the autostart service needs no environment wiring. Keeps the Access application fully gated — no per-path bypass required.

v3.4.0

10 Jun 01:05
bdae135

Choose a tag to compare

Security

  • Approval gate and audit logging are now wired into the execution path. requestApproval() and logAudit() existed in the security module but were never called by handleTask, so requireApproval/trustedAgents policy had no effect and no audit log was ever written despite the documented promise. Every dispatched task is now screened, optionally gated on approval, and recorded to ~/.askalf/audit.log (input field encrypted, chmod 600) with a blocked / denied / success / failed result.
  • Refuse to send the API key over unencrypted ws:// to a non-loopback host. The bearer token (and every task payload) previously travelled in cleartext over plaintext WebSocket connections. The agent now rejects such connections unless you explicitly pass --insecure (persisted to config for service installs) for a trusted private network. Loopback is exempt. wss:// remains the default.
  • Fix command injection in Claude-mode execution on Windows. runClaude spawned with shell:true and a raw args array, so Node concatenated arguments without quoting and a task prompt containing shell metacharacters (& | < > ^ …) could break out into a second command. It now routes through cmd.exe with full two-layer (cmd.exe + CommandLineToArgvW) argument escaping and windowsVerbatimArguments.
  • Validate server-pushed OAuth credentials before writing. task.credentials is now required to be a well-formed JSON object before it overwrites ~/.claude/.credentials.json, so a malformed payload can no longer brick the device's local claude login.
  • Hardened the allowedPaths boundary check. The previous startsWith test let /srv/data-evil pass for an allowed /srv/data (no separator boundary) and let ../-traversal escape entirely (paths were never normalized). Candidate paths are now normalized (collapsing ./..) and matched on a real path boundary before being permitted.
  • Removed a stale, insecure duplicate bridge.ts at the repository root — a pre-security-layer copy lacking input validation and the model allowlist. src/bridge.ts is the only bridge.
  • SECURITY.md corrected to describe the actual execution model (tasks run with the agent user's full privileges; there is no OS sandbox) instead of overstating isolation, and to document the approval gate, audit log, and transport guard.

v3.3.1

28 May 14:49
b919d7d

Choose a tag to compare

Changed

  • README rewritten — honest, building-in-public voice; drops the legacy "thinks/heals/remembers/evolves" + "nervous system / immune system" marketing copy. Fixes two factual errors (subprocess timeout is 5 min not 10; reconnect uses backoff). Ships to npm with this release.
  • package.json description refreshed to match — plain description of what the connector does, no version-coupled marketing.

No runtime behavior change.

v3.3.0 — fix #15 (stable encryption keyfile)

22 May 16:28
7797d9f

Choose a tag to compare

Closes #15. After upgrade, every askalf-agent device becomes restart-safe — systemctl restart, host reboots, Docker churn, VPN reconnects, Wi-Fi MAC randomization all stop corrupting the on-disk apiKey.

Fixed

  • agent.json apiKey unreadable after restart on hosts with churning network interfaces (#15). The pre-3.3 config-encryption key was derived from a hash that included every currently-up non-loopback interface's MAC address, so any Docker container start/stop, VPN connect/disconnect, or Wi-Fi MAC-randomization event silently changed the key. The agent then wrote a blob it could never decrypt again, and loadConfig returned the still-encrypted ciphertext as the Bearer token, producing AUTH_FAILED with no useful diagnostic.

Changed

  • Config-at-rest encryption now uses a stable random 32-byte keyfile at ~/.askalf/keyfile (chmod 600), generated once on first need. Survives every restart, container churn, and network reconfiguration.
  • loadConfig distinguishes "valid encrypted blob, wrong key" from "legacy plaintext format". Pre-3.3 a single catch-all swallowed both cases as "return as plaintext" — that was the silent-corruption mode. Wrong-key failures now surface a clear re-pair error pointing at #15.
  • On first run after upgrade, the legacy machine-derived key is tried as a one-shot migration. If it decrypts successfully (your network state happens to still match what it was at write time), the config is transparently re-saved under the stable keyfile and you never see this again. If both keys fail, you get the re-pair message instead of silent failure.

Upgrade path

npm i -g @askalf/agent@3.3.0

If the legacy key still works on your host, the upgrade is transparent — you'll see a one-line [agent] migrated agent.json from legacy machine-key encryption to stable keyfile notice and nothing else. If it doesn't, you'll see a clear re-pair error pointing at the recipe in #15 — one INSERT + one file write, ~30 seconds per device.

Either way, future restarts won't need this dance again.

v3.2.1 — fix WS subprotocol crash

12 May 19:32
d8ed5c5

Choose a tag to compare

Patch release

Single substantive fix on top of v3.2.0:

  • #14 — drop apiKey from WS subprotocol per RFC 6455 / ws@8.20.0 strict validation. Fixes the reconnect crash that hit fleet devices on agent restart against forge >=3.1.

Tracking

Issue #15 documents a separate bug — per-process apiKey re-encryption corrupting agent.json on shutdown. Recovery recipe in the issue. Larger fix coming in a future release.

Install

```
npm install -g @askalf/agent@3.2.1
```

v3.2.0 — model-in-dispatch

11 May 14:17
2422bab

Choose a tag to compare

What's new

The dispatcher can now control which Claude model runs on each device by including a model field in the task payload. When present, the agent invokes claude with --model <value>; otherwise it falls back to the device's local default (existing behavior, fully backward compatible).

This closes a real cost cliff: previously claude defaulted to whatever the device's local CC was configured to. One device defaulting to Opus caused 7-10x cost concentration on routine healthchecks compared to identical work on Haiku-default devices. With this version, the platform controls the model regardless of local defaults.

Compatibility

  • Old platform releases that don't send model → behavior unchanged
  • Malformed model strings rejected before reaching the CLI (no arg injection)

v3.1.6 — fix Claude prompt invocation (API-key auth path)

10 May 20:15

Choose a tag to compare

Fixes PR #11: agent now passes the Claude prompt as a positional arg instead of stdin, so installs that route Anthropic calls through an upstream gateway via ANTHROPIC_API_KEY work end-to-end (previously "Not logged in · Please run /login").

v3.1.5

07 Apr 14:13

Choose a tag to compare

Security: API keys no longer exposed in service files or process args. Hardened input validation patterns. Fixed crypto key derivation to include network interfaces. Fixed Windows service status detection.