Commit Graph

465 Commits

Author SHA1 Message Date
Peter Steinberger
9c2640a810 docs: clarify WhatsApp group allowlist and reply mention behavior 2026-02-19 09:19:34 +01:00
Gustavo Madeira Santana
c5698caca3 Security: default gateway auth bootstrap and explicit mode none (#20686)
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: be1b73182c
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
2026-02-19 02:35:50 -05:00
Taras Lukavyi
d833dcd731 fix(telegram): cron and heartbeat messages land in wrong chat instead of target topic (#19367)
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: bf02bbf9ce
Co-authored-by: Lukavyi <1013690+Lukavyi@users.noreply.github.com>
Co-authored-by: obviyus <22031114+obviyus@users.noreply.github.com>
Reviewed-by: @obviyus
2026-02-18 15:31:01 +05:30
Peter Steinberger
d1c00dbb7c fix: harden include confinement edge cases (#18652) (thanks @aether-ai-agent) 2026-02-18 03:27:16 +01:00
Peter Steinberger
2e91552f09 feat(agents): add generic provider api key rotation (#19587) 2026-02-18 01:31:11 +01:00
Peter Steinberger
4c569ce246 docs(tokens): document image dimension token tradeoffs 2026-02-18 00:56:57 +01:00
Peter Steinberger
b05e89e5e6 fix(agents): make image sanitization dimension configurable 2026-02-18 00:54:20 +01:00
Peter Steinberger
a333d92013 docs(security): harden gateway security guidance 2026-02-17 23:48:49 +01:00
Sebastian
19a8f8bbf6 test(cron): add model fallback regression coverage 2026-02-17 10:40:25 -05:00
Sebastian
5d1bcc76cc docs(zai): document tool_stream defaults 2026-02-17 09:22:55 -05:00
Peter Steinberger
076df941a3 feat: add configurable tool loop detection 2026-02-17 00:17:01 +01:00
Shadow
72e228e14b Heartbeat: allow suppressing tool warnings (#18497)
* Heartbeat: allow suppressing tool warnings

* Changelog: note heartbeat tool-warning suppression
2026-02-16 13:29:24 -06:00
Gustavo Madeira Santana
8a67016646 Agents: raise bootstrap total cap and warn on /context truncation (#18229)
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: f6620526df
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
2026-02-16 12:04:53 -05:00
Advait Paliwal
bc67af6ad8 cron: separate webhook POST delivery from announce (#17901)
* cron: split webhook delivery from announce mode

* cron: validate webhook delivery target

* cron: remove legacy webhook fallback config

* fix: finalize cron webhook delivery prep (#17901) (thanks @advaitpaliwal)

---------

Co-authored-by: Tyler Yust <TYTYYUST@YAHOO.COM>
2026-02-16 02:36:00 -08:00
Peter Steinberger
c6c53437f7 fix(security): scope session tools and webhook secret fallback 2026-02-16 03:47:10 +01:00
Peter Steinberger
1b6704ef53 docs: update sandbox bind mount guidance 2026-02-16 03:05:16 +01:00
Advait Paliwal
115cfb4430 gateway: add cron finished-run webhook (#14535)
* gateway: add cron finished webhook delivery

* config: allow cron webhook in runtime schema

* cron: require notify flag for webhook posts

* ui/docs: add cron notify toggle and webhook docs

* fix: harden cron webhook auth and fill notify coverage (#14535) (thanks @advaitpaliwal)

---------

Co-authored-by: Tyler Yust <TYTYYUST@YAHOO.COM>
2026-02-15 16:14:17 -08:00
Shadow
b6069fc68c feat: support per-channel ackReaction config (#17092) (thanks @zerone0x) 2026-02-15 11:30:25 -06:00
Shadow
9203a2fdb1 Discord: CV2! (#16364) 2026-02-15 10:24:53 -06:00
Ayaan Zaidi
a69e82765f fix(telegram): stream replies in-place without duplicate final sends 2026-02-15 20:32:51 +05:30
Peter Steinberger
ddfdd20d79 docs: update Slack/Discord allowFrom references 2026-02-15 03:49:33 +01:00
Peter Steinberger
f9bb748a6c fix(memory): prevent QMD scope deny bypass 2026-02-15 02:41:45 +00:00
Peter Steinberger
4a44da7d91 fix(security): default apply_patch workspace containment 2026-02-15 03:19:27 +01:00
Gustavo Madeira Santana
5b23999404 docs: document bootstrap total cap and exec log/notify behavior 2026-02-14 18:36:35 -05:00
Peter Steinberger
5e7c3250cb fix(security): add optional workspace-only path guards for fs tools 2026-02-14 23:50:24 +01:00
Peter Steinberger
9abf86f7e0 docs(changelog): document Slack/Discord dmPolicy aliases 2026-02-14 21:04:27 +01:00
Peter Steinberger
53af46ffb8 docs: note WhatsApp per-account dmPolicy override 2026-02-14 19:52:39 +01:00
Peter Steinberger
a3c9bc792e docs(podman): add gateway.mode=local troubleshooting note 2026-02-14 18:07:05 +01:00
Peter Steinberger
054366dea4 fix(security): require explicit trust for first-time TLS pins 2026-02-14 17:55:20 +01:00
Peter Steinberger
d583782ee3 fix(security): harden discovery routing and TLS pins 2026-02-14 17:18:14 +01:00
seheepeak
cb9a5e1cb9 feat(sandbox): separate bind mounts for browser containers (#16230)
* feat(sandbox): add separate browser.binds config for browser containers

Allow configuring bind mounts independently for browser containers via
sandbox.browser.binds. When set, browser containers use browser-specific
binds instead of inheriting docker.binds. Falls back to docker.binds
when browser.binds is not configured for backwards compatibility.

Closes #14614

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(sandbox): honor empty browser binds override (#16230) (thanks @seheepeak)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-02-14 15:27:41 +01:00
Peter Steinberger
644bef157a docs: clarify hook transform module path constraints 2026-02-14 15:03:27 +01:00
Peter Steinberger
6a386a7886 docs(security): clarify canvas host exposure and auth 2026-02-14 14:57:19 +01:00
Peter Steinberger
a0361b8ba9 fix(security): restrict hook transform module loading 2026-02-14 13:46:09 +01:00
Peter Steinberger
fba19fe942 docs: link trusted-proxy auth from gateway docs (#16172) 2026-02-14 12:44:25 +01:00
Nick Taylor
1fb52b4d7b feat(gateway): add trusted-proxy auth mode (#15940)
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 279d4b304f
Co-authored-by: nickytonline <833231+nickytonline@users.noreply.github.com>
Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Reviewed-by: @steipete
2026-02-14 12:32:17 +01:00
大猫子
13aface863 fix(config): accept $schema key in root config (#15280)
* fix(config): accept $schema key in root config (#14998)

* fix: strip $schema via preprocess to avoid spurious UI section

* fix(config): allow root  without zod preprocess wrapper

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-02-14 03:07:12 +01:00
Peter Steinberger
767fd9f222 fix: classify /tools/invoke errors and sanitize 500s (#13185) (thanks @davidrudduck) 2026-02-13 16:58:30 +01:00
Peter Steinberger
1def8c5448 fix(security): extend audit hardening checks 2026-02-13 16:26:58 +01:00
Harald Buerbaumer
30b6eccae5 feat(gateway): add auth rate-limiting & brute-force protection (#15035)
* feat(gateway): add auth rate-limiting & brute-force protection

Add a per-IP sliding-window rate limiter to Gateway authentication
endpoints (HTTP, WebSocket upgrade, and WS message-level auth).

When gateway.auth.rateLimit is configured, failed auth attempts are
tracked per client IP. Once the threshold is exceeded within the
sliding window, further attempts are blocked with HTTP 429 + Retry-After
until the lockout period expires. Loopback addresses are exempt by
default so local CLI sessions are never locked out.

The limiter is only created when explicitly configured (undefined
otherwise), keeping the feature fully opt-in and backward-compatible.

* fix(gateway): isolate auth rate-limit scopes and normalize 429 responses

---------

Co-authored-by: buerbaumer <buerbaumer@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-02-13 15:32:38 +01:00
Peter Steinberger
ee31cd47b4 fix: close OC-02 gaps in ACP permission + gateway HTTP deny config (#15390) (thanks @aether-ai-agent) 2026-02-13 14:30:06 +01:00
Tulsi Prasad
8c920b9a18 fix(docs): remove hardcoded Mermaid init blocks that break dark mode (#15157)
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 3239baaf15
Co-authored-by: heytulsiprasad <52394293+heytulsiprasad@users.noreply.github.com>
Co-authored-by: sebslight <19554889+sebslight@users.noreply.github.com>
Reviewed-by: @sebslight
2026-02-12 22:48:26 -05:00
Peter Steinberger
3421b2ec1e fix: harden hook session key routing defaults 2026-02-13 02:09:14 +01:00
Peter Steinberger
99f28031e5 fix: harden OpenResponses URL input fetching 2026-02-13 01:38:49 +01:00
Seb Slight
3ed06c6f36 docs: modernize gateway configuration page (Phase 1) (#14111)
* docs(configuration): split into overview + full reference with Mintlify components

* docs(configuration): use tooltip for JSON5 format note

* docs(configuration): fix Accordion closing tags inside list contexts

* docs(configuration): expand intro to reflect full config surface

* docs(configuration): trim intro to three concise bullets

* docs(configuration-examples): revert all branch changes

* docs(configuration): improve hot-reload section with tabs and accordion

* docs(configuration): uncramp hot-reload — subheadings, bullet list, warning

* docs(configuration): restore hot-apply vs restart table

* docs(configuration): fix hot-reload table against codebase

* docs: add configuration-reference.md — full field-by-field reference

* docs(gateway): refresh runbook and align config reference

* docs: include pending docs updates and install graphic
2026-02-11 10:44:34 -05:00
Bill Chirico
ca629296c6 feat(hooks): add agentId support to webhook mappings (#13672)
* feat(hooks): add agentId support to webhook mappings

Allow webhook mappings to route hook runs to a specific agent via
the new `agentId` field. This enables lightweight agents with minimal
bootstrap files to handle webhooks, reducing token cost per hook run.

The agentId is threaded through:
- HookMappingConfig (config type + zod schema)
- HookMappingResolved + HookAction (mapping types)
- normalizeHookMapping + buildActionFromMapping (mapping logic)
- mergeAction (transform override support)
- HookAgentPayload + normalizeAgentPayload (direct /hooks/agent endpoint)
- dispatchAgentHook → CronJob.agentId (server dispatch)

The existing runCronIsolatedAgentTurn already supports agentId on
CronJob — this change simply wires it through from webhook mappings.

Usage in config:
  hooks.mappings[].agentId = "my-agent"

Usage via POST /hooks/agent:
  { "message": "...", "agentId": "my-agent" }

Includes tests for mapping passthrough and payload normalization.
Includes doc updates for webhook.md.

* fix(hooks): enforce webhook agent routing policy + docs/changelog updates (#13672) (thanks @BillChirico)

* fix(hooks): harden explicit agent allowlist semantics (#13672) (thanks @BillChirico)

---------

Co-authored-by: Pip <pip@openclaw.ai>
Co-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com>
2026-02-10 19:23:58 -05:00
Shadow
47f6bb4146 Commands: add commands.allowFrom config 2026-02-09 23:58:52 -06:00
Gustavo Madeira Santana
e19a23520c fix: unify session maintenance and cron run pruning (#13083)
* fix: prune stale session entries, cap entry count, and rotate sessions.json

The sessions.json file grows unbounded over time. Every heartbeat tick (default: 30m)
triggers multiple full rewrites, and session keys from groups, threads, and DMs
accumulate indefinitely with large embedded objects (skillsSnapshot,
systemPromptReport). At >50MB the synchronous JSON parse blocks the event loop,
causing Telegram webhook timeouts and effectively taking the bot down.

Three mitigations, all running inside saveSessionStoreUnlocked() on every write:

1. Prune stale entries: remove entries with updatedAt older than 30 days
   (configurable via session.maintenance.pruneDays in openclaw.json)

2. Cap entry count: keep only the 500 most recently updated entries
   (configurable via session.maintenance.maxEntries). Entries without updatedAt
   are evicted first.

3. File rotation: if the existing sessions.json exceeds 10MB before a write,
   rename it to sessions.json.bak.{timestamp} and keep only the 3 most recent
   backups (configurable via session.maintenance.rotateBytes).

All three thresholds are configurable under session.maintenance in openclaw.json
with Zod validation. No env vars.

Existing tests updated to use Date.now() instead of epoch-relative timestamps
(1, 2, 3) that would be incorrectly pruned as stale.

27 new tests covering pruning, capping, rotation, and integration scenarios.

* feat: auto-prune expired cron run sessions (#12289)

Add TTL-based reaper for isolated cron run sessions that accumulate
indefinitely in sessions.json.

New config option:
  cron.sessionRetention: string | false  (default: '24h')

The reaper runs piggy-backed on the cron timer tick, self-throttled
to sweep at most every 5 minutes. It removes session entries matching
the pattern cron:<jobId>:run:<uuid> whose updatedAt + retention < now.

Design follows the Kubernetes ttlSecondsAfterFinished pattern:
- Sessions are persisted normally (observability/debugging)
- A periodic reaper prunes expired entries
- Configurable retention with sensible default
- Set to false to disable pruning entirely

Files changed:
- src/config/types.cron.ts: Add sessionRetention to CronConfig
- src/config/zod-schema.ts: Add Zod validation for sessionRetention
- src/cron/session-reaper.ts: New reaper module (sweepCronRunSessions)
- src/cron/session-reaper.test.ts: 12 tests covering all paths
- src/cron/service/state.ts: Add cronConfig/sessionStorePath to deps
- src/cron/service/timer.ts: Wire reaper into onTimer tick
- src/gateway/server-cron.ts: Pass config and session store path to deps

Closes #12289

* fix: sweep cron session stores per agent

* docs: add changelog for session maintenance (#13083) (thanks @skyfallsin, @Glucksberg)

* fix: add warn-only session maintenance mode

* fix: warn-only maintenance defaults to active session

* fix: deliver maintenance warnings to active session

* docs: add session maintenance examples

* fix: accept duration and size maintenance thresholds

* refactor: share cron run session key check

* fix: format issues and replace defaultRuntime.warn with console.warn

---------

Co-authored-by: Pradeep Elankumaran <pradeepe@gmail.com>
Co-authored-by: Glucksberg <markuscontasul@gmail.com>
Co-authored-by: max <40643627+quotentiroler@users.noreply.github.com>
Co-authored-by: quotentiroler <max.nussbaumer@maxhealth.tech>
2026-02-09 20:42:35 -08:00
Suvin Nimnaka
24e9b23c4a Replace text diagrams with mermaid (#7165)
* Replace text diagrams with mermaid

* Fix review comments

* Remove newlines

* docs: fix mermaid prep blockers (#7165)

---------

Co-authored-by: Sebastian <19554889+sebslight@users.noreply.github.com>
2026-02-09 10:27:27 -05:00
max
223eee0a20 refactor: unify peer kind to ChatType, rename dm to direct (#11881)
* fix: use .js extension for ESM imports of RoutePeerKind

The imports incorrectly used .ts extension which doesn't resolve
with moduleResolution: NodeNext. Changed to .js and added 'type'
import modifier.

* fix tsconfig

* refactor: unify peer kind to ChatType, rename dm to direct

- Replace RoutePeerKind with ChatType throughout codebase
- Change 'dm' literal values to 'direct' in routing/session keys
- Keep backward compat: normalizeChatType accepts 'dm' -> 'direct'
- Add ChatType export to plugin-sdk, deprecate RoutePeerKind
- Update session key parsing to accept both 'dm' and 'direct' markers
- Update all channel monitors and extensions to use ChatType

BREAKING CHANGE: Session keys now use 'direct' instead of 'dm'.
Existing 'dm' keys still work via backward compat layer.

* fix tests

* test: update session key expectations for dmdirect migration

- Fix test expectations to expect :direct: in generated output
- Add explicit backward compat test for normalizeChatType('dm')
- Keep input test data with :dm: keys to verify backward compat

* fix: accept legacy 'dm' in session key parsing for backward compat

getDmHistoryLimitFromSessionKey now accepts both :dm: and :direct:
to ensure old session keys continue to work correctly.

* test: add explicit backward compat tests for dmdirect migration

- session-key.test.ts: verify both :dm: and :direct: keys are valid
- getDmHistoryLimitFromSessionKey: verify both formats work

* feat: backward compat for resetByType.dm config key

* test: skip unix-path Nix tests on Windows
2026-02-09 09:20:52 +09:00