Skip to content

[BUG] OpenAPIToolkit: security scheme in: cookie never gets its API key injected because the branch tests the misspelled literal 'coolie' #4371

Open

Description

@BlueX888

Required prerequisites

What version of camel are you using?

0.2.91a7 (running from source, master @ 8c791b7b)

System information

  • camel installed from source (editable, master @ 8c791b7b)
  • Python 3.13.15, macOS (darwin, arm64)

Problem description

When an OpenAPI spec declares an API-key security scheme with "in": "cookie", OpenAPIToolkit never injects the API key into the outgoing request, so the request goes out with no credentials at all and the API returns an auth error with no hint as to why. The security-scheme branch in camel/toolkits/open_api_toolkit.py:307 tests the misspelled literal 'coolie':

if request_key_in == 'query':
    params[request_key_name] = api_key_value
elif request_key_in == 'header':
    headers[request_key_name] = api_key_value
elif request_key_in == 'coolie':          # <- typo: never matches 'cookie'
    cookies[request_key_name] = api_key_value

The neighboring parameter branch in the same loop handles param['in'] == 'cookie' correctly (camel/toolkits/open_api_toolkit.py:324), so the security-scheme branch is drift from the correct handling.

Per the OpenAPI 3.x specification, a securityScheme of type: apiKey allows in to be 'query' | 'header' | 'cookie', so in: cookie is a valid, common configuration (session-cookie APIs) that silently gets no key.

Reproducible example code

Fully offline — requests.request is mocked, so the exact cookies/headers/params actually sent can be inspected:

import os
from unittest.mock import patch

import camel.toolkits.open_api_toolkit as oat
from camel.toolkits import open_api_specs
from camel.toolkits.open_api_toolkit import OpenAPIToolkit

os.environ["COOKIE_DEMO_KEY"] = "secret-token-123"

captured = {}

class FakeResp:
    def json(self):
        return {"ok": True}

def fake_request(method, url, **kw):
    captured.clear()
    captured.update(kw, method=method, url=url)
    return FakeResp()

def make_spec(in_location):
    return {
        "openapi": "3.0.0",
        "info": {"title": "cookie-demo", "version": "1.0"},
        "servers": [{"url": "https://api.example.com"}],
        "security": [{"cookieAuth": []}],
        "paths": {"/data": {"get": {"operationId": "get_data",
                                    "summary": "get data with auth"}}},
        "components": {"securitySchemes": {
            "cookieAuth": {"type": "apiKey", "in": in_location, "name": "session"}}},
    }

tk = OpenAPIToolkit()

with patch.object(oat.requests, "request", fake_request), patch.dict(
    open_api_specs.security_config.openapi_security_config,
    {"cookie-demo": {"cookieAuth": "COOKIE_DEMO_KEY",
                     "get_api_key_url": "http://x"}},
):
    for in_location in ("header", "query", "cookie"):
        funcs = tk.generate_openapi_funcs("cookie-demo", make_spec(in_location))
        funcs[0]()
        print(f"[in: {in_location}] request: {captured['method']} {captured['url']}")
        print(f"[in: {in_location}] cookies={captured.get('cookies')} "
              f"headers={captured.get('headers')} params={captured.get('params')}")

Traceback

Actual output (camel 0.2.91a7 @ 8c791b7b, Python 3.13.15, macOS) — the key is injected for header and query but silently dropped for cookie:

[in: header] request: GET https://api.example.com/data
[in: header] cookies={} headers={'session': 'secret-token-123'} params={}
[in: query] request: GET https://api.example.com/data
[in: query] cookies={} headers={} params={'session': 'secret-token-123'}
[in: cookie] request: GET https://api.example.com/data
[in: cookie] cookies={} headers={} params={}

The last line is the bug: the request goes out with no credentials anywhere, and the real API just answers with an auth error.

Expected behavior

For a security scheme {type: apiKey, in: cookie}, the API key should be sent as a cookie, exactly like the query and header cases — i.e. the last line should be:

[in: cookie] cookies={'session': 'secret-token-123'} headers={} params={}

Concrete basis:

Additional context

Root cause: one-character typo in camel/toolkits/open_api_toolkit.py:307 — the branch literal 'coolie' can never match the spec value 'cookie', so the API key is silently dropped. Fixing the literal to 'cookie' restores injection; verified locally with the repro above (cookie group then sends cookies={'session': 'secret-token-123'}), plus pytest test/toolkits/test_open_api_function.py (all 11 pre-existing tests pass; 12 with a regression test added on top).

Happy to be assigned — I can open a PR with the fix once this issue is accepted.

Activity

  1. BlueX888 commented on Sep 24, 2026

    @BlueX888
    Author

    Reproduced this. Root cause: camel/toolkits/open_api_toolkit.py:307 branch literal 'coolie' never matches 'cookie'

    Minimal reproduction:

    PYTHONPATH=$PWD ../camel.tree/.venv/bin/python ../repro_openapi_cookie_apikey.py
    

    Observed output:

    [in: header] headers={'session': 'secret-token-123'} / [in: query] params={'session': 'secret-token-123'} / [in: cookie] cookies={} headers={} params={}
    

    Happy to open a PR with this fix, or to be assigned if you prefer to take it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions