infiniflow/ragflow · error · Exception

Anonymous webhook access requires allow_anonymous to be true

Error message

Anonymous webhook access requires allow_anonymous to be true

What it means

When a webhook's security config has auth_type 'none' (or omits it), validate_webhook_security checks _allow_anonymous_webhook(security_cfg); unless allow_anonymous is explicitly true it raises Exception('Anonymous webhook access requires allow_anonymous to be true') (agent_api.py:1913). Anonymous is opt-in only - unauthenticated requests are rejected even though a security block exists.

Source

Thrown at api/apps/restful_apis/agent_api.py:1913

        await _validate_max_body_size(security_cfg)

        # 2. Validate IP whitelist
        _validate_ip_whitelist(security_cfg)

        # # 3. Validate rate limiting
        _validate_rate_limit(security_cfg)

        # 4. Validate authentication
        auth_type = security_cfg.get("auth_type", "none")

        if auth_type == "none":
            if not _allow_anonymous_webhook(security_cfg):
                logging.warning(
                    "Webhook denied: anonymous access missing explicit opt-in agent_id=%s method=%s",
                    agent_id,
                    request.method,
                )
                raise Exception("Anonymous webhook access requires allow_anonymous to be true")
            return

        if auth_type == "token":
            _validate_token_auth(security_cfg)

        elif auth_type == "basic":
            _validate_basic_auth(security_cfg)

        elif auth_type == "jwt":
            _validate_jwt_auth(security_cfg)

        else:
            raise Exception(f"Unsupported auth_type: {auth_type}")

    async def _validate_max_body_size(security_cfg):
        """Check request size does not exceed max_body_size."""
        max_size = security_cfg.get("max_body_size")
        if not max_size:

View on GitHub (pinned to 554fb1133a)

Solutions

  1. If the webhook must be public, set "allow_anonymous": true in the security config (accepting anyone can invoke it - pair with IP whitelist/rate limits).
  2. Otherwise pick a real auth_type: 'token', 'basic', or 'jwt' and configure its fields.
  3. Re-publish/restart the agent so the updated security config takes effect.
  4. Send the matching credentials from the caller once auth is enabled (Bearer token, Basic header, or JWT).

Example fix

// before
"security": {"auth_type": "none", "max_body_size": "1MB"}

// after (public, with mitigation)
"security": {"auth_type": "none", "allow_anonymous": true, "max_body_size": "1MB", "rate_limit": "10/min"}
Defensive patterns

Strategy: validation

Validate before calling

sec = agent_config.get("webhook", {}).get("security", {})
if sec.get("auth_type", "none") == "none" and sec.get("allow_anonymous") is not True:
    raise ValueError("Anonymous webhook requires allow_anonymous=true, or pick token/basic/jwt auth")

Type guard

def is_valid_webhook_anonymous(sec: dict) -> bool:
    return sec.get("auth_type", "none") != "none" or sec.get("allow_anonymous") is True

Try / catch

try:
    resp = await invoke_webhook(session, url, payload)
except WebhookRejected as e:
    if "allow_anonymous" in str(e):
        raise ConfigError("Webhook is not open: either enable allow_anonymous or send credentials") from e
    raise

Prevention

When it happens

Trigger: security config contains {"auth_type": "none"} without allow_anonymous: true; auth_type omitted (defaults to 'none') and allow_anonymous not set; a client calls the webhook without credentials expecting it to be open.

Common situations: Users set a security block just to configure rate limits or IP whitelist but leave authentication off, forgetting the separate anonymous opt-in; trial webhooks intended for public testing.

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/eb51e56932915053. Report an issue: GitHub.