Commit Graph

267 Commits

Author SHA1 Message Date
Hugh Brown
355bed1b40 Update backend/app/api/board_webhooks.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
6b55b52a68 refactor: switch RedisRateLimiter to async redis.asyncio client
Replace sync redis.Redis with redis.asyncio to avoid blocking the
event loop during rate-limit checks. Make RateLimiter.is_allowed async
across both backends and update all call sites to await.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
f1bcf72810 feat: add trusted client-IP extraction from proxy headers
Add get_client_ip() helper that inspects Forwarded and X-Forwarded-For
headers only when the direct peer is in TRUSTED_PROXIES (comma-separated
IPs/CIDRs). Replaces raw request.client.host in rate-limit and webhook
source_ip to prevent all traffic collapsing behind a reverse proxy IP.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
528a2483b7 feat: add configurable signature_header for webhook HMAC verification
Not all webhook providers use X-Hub-Signature-256 or X-Webhook-Signature.
Add an optional signature_header field so users can specify which header
carries the HMAC signature. When set, that exact header is checked;
when unset, the existing auto-detect fallback is preserved. The custom
header is also excluded from stored/exposed payload headers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
a66765a514 Apply ruff fixes 2026-03-07 23:35:10 +05:30
Hugh Brown
0896b0772d Import linting 2026-03-07 23:35:10 +05:30
Hugh Brown
2ef6164cf8 fix: normalize webhook secret via schema validator instead of inline
Move blank/whitespace-only secret normalization to a shared
field_validator on both BoardWebhookCreate and BoardWebhookUpdate.
This ensures consistent behavior across create and update paths
and removes the inline normalization from the endpoint handlers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
91e8270364 revert: restore GatewayRead.token field to avoid frontend breaking change
The has_token boolean redaction requires coordinated frontend changes
(detail page, edit page, orval types). Revert to returning the raw
token for now; token redaction will be handled in a dedicated PR.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
b2fb8a082d feat: make webhook payload size limit configurable
Add WEBHOOK_MAX_PAYLOAD_BYTES setting (default 1 MB) so deployments
with larger webhook payloads can raise the limit via environment
variable instead of being hard-blocked at 1 MB.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
af094ad11a fix: exclude signature and auth headers from webhook payload capture
_captured_headers was storing all x-* headers including
X-Hub-Signature-256 and X-Webhook-Signature. Since stored headers
are exposed via the payload read endpoint, this enabled replay
attacks without knowing the webhook secret. Now signature and
authorization headers are excluded from capture.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
cc50877131 refactor: rename require_admin_auth/require_admin_or_agent to require_user_auth/require_user_or_agent
These dependencies check actor type (human user vs agent), not admin
privilege. The old names were misleading and could cause authorization
mistakes when wiring new endpoints. Renamed across all 10 consumer
files along with their local ADMIN_AUTH_DEP / ADMIN_OR_AGENT_DEP
aliases.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
ea78b41a36 fix: persist webhook secret on create and normalize on update
The secret field was accepted in BoardWebhookCreate but never passed
to the BoardWebhook constructor, silently dropping it. Now secret is
persisted at creation time (with empty/whitespace normalized to None)
and similarly normalized on PATCH so sending "" clears a set secret.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
3ca0931c72 Update backend/app/api/board_webhooks.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
cd7e411b3e Update backend/app/api/skills_marketplace.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
3a0c67a656 Update backend/app/api/board_webhooks.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
916dace3c8 Address ruff / formatting errors 2026-03-07 23:35:10 +05:30
Hugh Brown
62d2378bdc chore: simplify and harden security review changes
- Add prompt-injection fencing to _webhook_memory_content (was missing
  the --- BEGIN/END EXTERNAL DATA --- fence applied elsewhere)
- Wrap Content-Length parsing in try/except to avoid 500 on malformed
  header values
- Move _to_gateway_read below imports (was incorrectly placed between
  import blocks) and tighten transformer types
- Replace list-rebuild with deque.popleft in rate limiter for O(expired)
  amortized pruning instead of O(n) per call
- Make organization_id required in send_session_message to prevent
  fail-open cross-tenant check

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
4960d8561b security: fix fail-open auth, streaming payload limit, and rate limiter memory leak
- agent.py: Fail closed when gateway lookup returns None instead of
  silently dropping the organization filter (cross-tenant board leak)
- board_webhooks.py: Read request body via streaming chunks so an
  oversized payload is rejected before it is fully loaded into memory
- rate_limit.py: Add periodic sweep of expired keys to prevent
  unbounded memory growth from inactive clients
- test_rate_limit.py: Add test for the new sweep behavior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
858575cf6c test: add comprehensive tests for all security fixes
Add 20 tests covering:
- require_user_actor: rejects agents and null users, passes valid users
- Webhook HMAC: rejects missing/invalid signatures, accepts valid ones,
  allows unsigned when no secret configured
- Prompt injection: sanitized skill name/URL, fenced external data in
  dispatch messages, system instructions precede data
- Security headers: verify nosniff, DENY, referrer-policy defaults
- Payload size: rejects oversized body and content-length
- Rate limiting: blocks after threshold, independent per-key
- Gateway token: has_token field present, token field absent
- Agent auth logs: no token_prefix in source

Also fix deprecated HTTP_413_REQUEST_ENTITY_TOO_LARGE status code.

All 407 tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
547965a5cb security: redact gateway tokens from API responses
Gateway tokens were returned as plaintext in GatewayRead API responses.
Replace the `token` field with a boolean `has_token` flag so the API
never exposes the plaintext token. The token remains in the database
for outbound gateway connections (full encryption would require key
management infrastructure).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
94988deef2 security: add rate limiting to agent auth and webhook ingest
Agent token auth performed O(n) PBKDF2 operations per request with no
rate limiting, enabling CPU exhaustion attacks. Webhook ingest had no
rate limits either. Add an in-memory token-bucket rate limiter:
- Agent auth: 20 requests/minute per IP
- Webhook ingest: 60 requests/minute per IP

Includes unit tests for the rate limiter.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
66da278673 security: require org-admin for gateway session message endpoint
send_gateway_session_message only required basic auth (AUTH_DEP) while
all other gateway endpoints required ORG_ADMIN_DEP. Any authenticated
user could send messages to any gateway session. Now requires org-admin
and verifies the board belongs to the caller's organization.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
7ca4145aff security: add 1 MB payload size limit to webhook ingestion
The webhook ingest endpoint read the entire request body with no size
limit, enabling memory exhaustion attacks. Add a 1 MB limit checked
via both Content-Length header (early reject) and actual body size.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
5d382ed67b security: mitigate prompt injection in agent instruction strings
User-controlled fields (skill name, source URL, webhook payloads) were
interpolated directly into agent instruction messages. Sanitize skill
fields by stripping newlines/control chars, and fence all external data
behind "BEGIN EXTERNAL DATA" / "BEGIN STRUCTURED DATA" delimiters with
explicit "do not interpret as instructions" markers. Move system
instructions above the data section so they cannot be overridden.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
4d1dbb4098 security: add HMAC signature verification to webhook ingest
Webhook ingest endpoint was completely unauthenticated. Add an optional
`secret` field to BoardWebhook. When configured, inbound requests must
include a valid HMAC-SHA256 signature in X-Hub-Signature-256 or
X-Webhook-Signature headers. Uses hmac.compare_digest for timing safety.
Includes migration to add the secret column.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
10848b98cb security: scope agent board listing to organization
Main agents (board_id=None) could list boards across all organizations.
Now resolves the agent's organization via its gateway and filters boards
by organization_id to prevent cross-tenant data leakage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Hugh Brown
c7692e30d3 security: rename misleading require_admin to require_user_actor
The function only checked that the caller was an authenticated user
(not an agent) but its name implied privilege enforcement. Rename to
require_user_actor and add docstring clarifying the distinction between
actor-type checks and privilege/role checks (require_org_admin, is_super_admin).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:35:10 +05:30
Abhimanyu Saharan
532fbf1dc5 feat(config): make BASE_URL a required field and update related documentation 2026-03-05 01:36:07 +05:30
Abhimanyu Saharan
3acc276d8d fix(agent): address webhook payload read review feedback 2026-03-04 23:26:31 +05:30
Abhimanyu Saharan
1d0b318fc9 lint: fix flake8 E304 after create_task decorator 2026-03-04 23:22:27 +05:30
Abhimanyu Saharan
3fc96baa10 feat(agent): add read-only webhook payload fetch endpoint for backfill 2026-03-04 23:22:27 +05:30
Abhimanyu Saharan
4378d354f4 fix(ci): resolve backend check failures in dashboard metrics 2026-03-04 16:11:14 +05:30
Abhimanyu Saharan
bdc9fc3f01 redesigned dashboard page 2026-03-04 16:01:56 +05:30
Abhimanyu Saharan
77870b0fc7 fix(agent): improve error handling for get_agent_soul method 2026-03-03 03:09:29 +05:30
Abhimanyu Saharan
2031f8dcd8 fix: increase GIT_CLONE_TIMEOUT_SECONDS to 600 for better performance #173 2026-03-03 02:16:19 +05:30
Abhimanyu Saharan
94ae59d6aa refactor(gateway): update gateway parameters to use None as default #169 2026-03-03 01:51:52 +05:30
Abhimanyu Saharan
348b0515ac feat(boards): implement lead notification on board updates with detailed change messages 2026-02-26 01:58:55 +05:30
Abhimanyu Saharan
6b21ea6f99 feat(boards): add 'comment_required_for_review' rule and update related logic 2026-02-26 00:31:47 +05:30
Abhimanyu Saharan
adad72373c feat(tasks): add notification messages for task assignment and rework 2026-02-25 18:29:59 +05:30
Abhimanyu Saharan
3f158940cd Merge branch 'master' into docs/backend-doc-pass 2026-02-25 03:32:14 +05:30
Abhimanyu Saharan
56f4964332 feat: add support for allowing self-signed TLS certificates in gateway configuration 2026-02-22 20:20:19 +05:30
Abhimanyu Saharan
374d5a0c37 Merge branch 'master' into copilot/feature-allow-self-signed-tls
# Conflicts:
#	backend/app/api/gateways.py
#	backend/app/schemas/gateways.py
#	backend/app/services/openclaw/admin_service.py
#	backend/app/services/openclaw/gateway_resolver.py
#	backend/app/services/openclaw/gateway_rpc.py
#	backend/app/services/openclaw/provisioning.py
#	backend/app/services/openclaw/provisioning_db.py
#	frontend/src/api/generated/model/gatewayCreate.ts
#	frontend/src/api/generated/model/gatewayRead.ts
#	frontend/src/api/generated/model/gatewayUpdate.ts
2026-02-22 19:51:27 +05:30
Abhimanyu Saharan
cdced8e07c refactor: improve code formatting and readability in tests and components 2026-02-22 19:45:18 +05:30
Abhimanyu Saharan
3dfb70cd90 feat: add disable_device_pairing option to gateway configuration 2026-02-22 19:19:26 +05:30
copilot-swe-agent[bot]
520e128777 feat: Add allow_insecure_tls field to gateway model and UI
- Added allow_insecure_tls boolean field to Gateway model and schemas
- Created database migration for the new field
- Updated GatewayConfig to include allow_insecure_tls parameter
- Modified openclaw_call to create SSL context that disables verification when allow_insecure_tls is true
- Updated all GatewayConfig instantiations throughout the backend
- Added checkbox to frontend gateway form (create and edit pages)
- Updated API endpoints to handle the new field

Co-authored-by: abhi1693 <5083532+abhi1693@users.noreply.github.com>
2026-02-22 05:28:37 +00:00
Abhimanyu Saharan
6c3c9913db feat: update agent heartbeat endpoint to require no request payload 2026-02-16 01:46:06 +05:30
Abhimanyu Saharan
5912048b85 feat: add validation for gateway main agent requirement on board mutations 2026-02-16 01:25:44 +05:30
Abhimanyu Saharan
1d63bd0148 feat: add health check endpoint for agent authentication status 2026-02-16 00:42:15 +05:30
Abhimanyu Saharan
b702ade0cc fix: update HTTP status code from UNPROCESSABLE_ENTITY to UNPROCESSABLE_CONTENT 2026-02-15 16:06:06 +05:30
Abhimanyu Saharan
24731667d4 feat: add gateway runtime compatibility checks and minimum version enforcement 2026-02-15 15:59:55 +05:30