Summary
Vault plugin cannot find X-Vault-Tokens header despite it being present in the request and logged by tool service. Root cause: plugin does case-sensitive dict lookup but ASGI middleware lowercases all headers per spec.
Related JIRA Issues
- ICACF-41: Vault plugin fails to find X-Vault-Tokens header (symptom)
- ICACF-42: HttpAuthMiddleware lowercases headers (not a bug - per ASGI spec)
Root Cause
Not a bug: ASGI spec (RFC 7230) requires headers to be case-insensitive and ASGI standardizes them as lowercase bytes tuples. The middleware at mcpgateway/middleware/http_auth_middleware.py:227 correctly lowercases all headers.
Actual bug: Vault plugin at plugins/vault/vault_plugin.py:186-187 does case-sensitive dict lookup:
if self._sconfig.vault_header_name not in headers: # "X-Vault-Tokens" not in {"x-vault-tokens": ...}
return ToolPreInvokeResult()
Reproduction Steps
- Configure gateway with passthrough headers including
X-Vault-Tokens
- Configure vault plugin with
vault_header_name: "X-Vault-Tokens" (default config)
- Send request with header:
X-Vault-Tokens: {"github.com": "token123"}
- Middleware lowercases to
x-vault-tokens (per ASGI spec)
- Tool service sends
{"x-vault-tokens": "..."} to plugin
- Plugin checks
"X-Vault-Tokens" not in {"x-vault-tokens": ...} → FAILS
- Plugin logs: "Vault header 'X-Vault-Tokens' not found in headers"
Impact
- Vault plugin fails silently in production
- OAuth2 token unwrapping does not work
- No bearer tokens generated for MCP servers requiring auth
Affected Code
File: plugins/vault/vault_plugin.py
- Line 177, 178: Case-sensitive lookup and delete in
safe_headers
- Line 187: Case-sensitive lookup (main bug)
- Line 192, 196, 202: Case-sensitive access and delete
- Line 240: Case-sensitive write for AUTH_HEADER tag
Total: 7 operations affected
Solution
Follow the pattern from plugins/examples/simple_token_auth/simple_token_auth.py:105 which normalizes header names to lowercase:
# In __init__ (after line 95)
self._vault_header_key = self._sconfig.vault_header_name.lower()
# Replace all 6 read operations
if self._vault_header_key not in headers: # Line 187
vault_tokens = orjson.loads(headers[self._vault_header_key]) # Line 192
# Normalize write operation
headers[auth_header.lower()] = str(token_value) # Line 240
Test Coverage Gap
Critical: All existing tests use matching case for config AND payload headers (both "X-Vault-Tokens"). They bypass ASGI middleware and never test real production flow.
Required new tests:
test_vault_header_lowercase_headers - Config uppercase, headers lowercase (production)
test_vault_header_lowercase_config - Both lowercase
test_pat_token_custom_header_lowercase - AUTH_HEADER tag normalization
Files to Change
plugins/vault/vault_plugin.py - 7 lines (production code)
tests/unit/mcpgateway/plugins/plugins/vault/test_vault_plugin.py - 3 new tests
References
- ASGI spec: Headers must be lowercase bytes tuples
- RFC 7230: HTTP header names are case-insensitive
- Tests verifying lowercase:
tests/unit/mcpgateway/middleware/test_http_auth_headers.py:377,387,1039
- Example pattern:
plugins/examples/simple_token_auth/simple_token_auth.py:105
Summary
Vault plugin cannot find
X-Vault-Tokensheader despite it being present in the request and logged by tool service. Root cause: plugin does case-sensitive dict lookup but ASGI middleware lowercases all headers per spec.Related JIRA Issues
Root Cause
Not a bug: ASGI spec (RFC 7230) requires headers to be case-insensitive and ASGI standardizes them as lowercase bytes tuples. The middleware at
mcpgateway/middleware/http_auth_middleware.py:227correctly lowercases all headers.Actual bug: Vault plugin at
plugins/vault/vault_plugin.py:186-187does case-sensitive dict lookup:Reproduction Steps
X-Vault-Tokensvault_header_name: "X-Vault-Tokens"(default config)X-Vault-Tokens: {"github.com": "token123"}x-vault-tokens(per ASGI spec){"x-vault-tokens": "..."}to plugin"X-Vault-Tokens" not in {"x-vault-tokens": ...}→ FAILSImpact
Affected Code
File:
plugins/vault/vault_plugin.pysafe_headersTotal: 7 operations affected
Solution
Follow the pattern from
plugins/examples/simple_token_auth/simple_token_auth.py:105which normalizes header names to lowercase:Test Coverage Gap
Critical: All existing tests use matching case for config AND payload headers (both
"X-Vault-Tokens"). They bypass ASGI middleware and never test real production flow.Required new tests:
test_vault_header_lowercase_headers- Config uppercase, headers lowercase (production)test_vault_header_lowercase_config- Both lowercasetest_pat_token_custom_header_lowercase- AUTH_HEADER tag normalizationFiles to Change
plugins/vault/vault_plugin.py- 7 lines (production code)tests/unit/mcpgateway/plugins/plugins/vault/test_vault_plugin.py- 3 new testsReferences
tests/unit/mcpgateway/middleware/test_http_auth_headers.py:377,387,1039plugins/examples/simple_token_auth/simple_token_auth.py:105