Advisory Details
Title: [Authentication Bypass] Unauthenticated Tenant Takeover via Header Injection in runAuth Middleware (Dev/Test Mode)
Description:
Summary
An authentication bypass vulnerability exists in the runApiKeyAuthHandler middleware when the agents-api application is running in development or test mode. The vulnerability allows any unauthenticated external attacker to achieve complete "Tenant Takeover" to impersonate arbitrary tenants, projects, and agents by simply injecting x-inkeep-* HTTP headers into their requests, leading to severe unauthorized data access, privilege escalation, and downstream API exhaustion.
Details
The vulnerability is located in the fallback authorization logic of agents-api/src/middleware/runAuth.ts. When the backend application runs with ENVIRONMENT=development or ENVIRONMENT=test, the middleware attempts to bypass strict API key validation to facilitate local testing. If a request lacks a valid Authorization header, the middleware automatically invokes the createDevContext function to construct a dummy user execution context.
However, createDevContext blindly trusts the x-inkeep-tenant-id, x-inkeep-project-id, and x-inkeep-agent-id headers extracted from the incoming request (reqData), prioritizing these remote, unverified user inputs over the safe default fallback constants (e.g., 'test-tenant').
function createDevContext(reqData: RequestData): AuthResult {
const result: AuthResult = {
apiKey: 'development',
// VULNERABILITY: Blindly prioritizing external HTTP headers over safe defaults
tenantId: reqData.tenantId || 'test-tenant',
projectId: reqData.projectId || 'test-project',
agentId: reqData.agentId || 'test-agent',
apiKeyId: 'test-key',
...
An external attacker can simply send HTTP requests carrying these headers. The middleware will map the target identity to the global execution context (c.set('executionContext', ...)), completely bypassing any API key authentication or developer bypass secrets (INKEEP_AGENTS_MANAGE_API_BYPASS_SECRET). Although restricted to environments configured for development or testing, this poses a Critical risk if these environments are publicly exposed or deployed in Staging namespaces without explicit warnings.
PoC
- Ensure the
agents-api application is running locally with ENVIRONMENT=development (which is the default in .env.example).
- Identify a protected endpoint, such as
/run/agents/{agent_id}/chat.
- Submit an unauthenticated
POST request, injecting targeted execution context parameters via the x-inkeep-tenant-id, x-inkeep-project-id, and x-inkeep-agent-id headers:
curl -X POST "http://localhost:3002/run/agents/target-agent/chat" \
-H "x-inkeep-tenant-id: hacked-tenant" \
-H "x-inkeep-project-id: hacked-project" \
-H "x-inkeep-agent-id: hacked-agent" \
-H "Content-Type: application/json" \
-d '{"message": "Hello"}'
- Observe that the middleware accepts the request, overrides the standard
test-tenant safety defaults, and attempts to execute the downstream action directly as the hacked-tenant identity.
Log of Evidence
[*] Sending an unauthenticated request to a protected /run endpoint...
[*] Target URL: http://localhost:3002/run/agents/target-agent/chat
[*] Headers injected:
x-inkeep-tenant-id: hacked-tenant
x-inkeep-project-id: hacked-project
x-inkeep-agent-id: hacked-agent
[+] Status Code: 404
[+] Response body extracts: {"code":"not_found","title":"Not Found","status":404,"detail":"Project not found: hacked-project","error":{"code":"not_found","message":"Project not found: hacked-project"}}
[SUCCESS] Authentication bypassed! The middleware allowed our execution context injection without an API key or session.
(Note: A 404 Project not found response originating from internal execution validation proves the request completely bypassed the initial Auth/401 layer and operated entirely within the hijacked context).
Impact
- Authentication Bypass & Privilege Escalation (Tenant Takeover): Unauthenticated attackers can assume the identity of any registered platform tenant and project merely by specifying target IDs in the headers.
- Unauthorized Data Access: Complete exposure of cross-tenant interaction histories, metadata, and intelligent model configurations if a staging component has remote database links.
- API Exhaustion / Billing Fraud: Attackers can spoof execution payloads to consume significant backend LLM tokens (e.g., Anthropic, OpenAI) which are billed to the impersonated victim accounts or platform developers.
Affected products
- Ecosystem: npm
- Package name: @inkeep/agents-api
- Affected versions: <= 0.58.14 (Verified on commit
b10c96fc081866fc02c662aa34b002c277ae2563)
- Patched versions:
Severity
- Severity: Critical
- Vector string: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (9.8 Critical) (Note: Score reflects environments where development configurations are misconfigured or deployed externally without compensating controls).
Weaknesses
- CWE-288: Authentication Bypass Using an Alternate Path or Channel
- CWE-306: Missing Authentication for Critical Function
Occurrences
| Permalink |
Description |
|
tenantId: reqData.tenantId || 'test-tenant', |
|
projectId: reqData.projectId || 'test-project', |
|
agentId: reqData.agentId || 'test-agent', |
|
apiKeyId: 'test-key', |
|
The createDevContext fallback improperly prioritizes unverified user HTTP headers (reqData.tenantId) for context assignment over safer default fallback dummy strings ('test-tenant'). |
|
logger.info({}, 'development environment'); |
|
|
|
const attempt = await authenticateRequest(reqData); |
|
|
|
if (attempt.authResult) { |
|
c.set('executionContext', buildExecutionContext(attempt.authResult, reqData)); |
|
} else { |
|
logger.info( |
|
{}, |
|
reqData.apiKey |
|
? 'Development/test environment - fallback to default context due to invalid API key' |
|
: 'Development/test environment - no API key provided, using default context' |
|
); |
|
c.set('executionContext', buildExecutionContext(createDevContext(reqData), reqData)); |
|
The runApiKeyAuthHandler routes unauthenticated requests to createDevContext seamlessly when ENVIRONMENT is development or test, without requiring explicit verification or developer bypass secrets to map an arbitrary identity. |
Advisory Details
Title: [Authentication Bypass] Unauthenticated Tenant Takeover via Header Injection in runAuth Middleware (Dev/Test Mode)
Description:
Summary
An authentication bypass vulnerability exists in the
runApiKeyAuthHandlermiddleware when theagents-apiapplication is running indevelopmentortestmode. The vulnerability allows any unauthenticated external attacker to achieve complete "Tenant Takeover" to impersonate arbitrary tenants, projects, and agents by simply injectingx-inkeep-*HTTP headers into their requests, leading to severe unauthorized data access, privilege escalation, and downstream API exhaustion.Details
The vulnerability is located in the fallback authorization logic of
agents-api/src/middleware/runAuth.ts. When the backend application runs withENVIRONMENT=developmentorENVIRONMENT=test, the middleware attempts to bypass strict API key validation to facilitate local testing. If a request lacks a validAuthorizationheader, the middleware automatically invokes thecreateDevContextfunction to construct a dummy user execution context.However,
createDevContextblindly trusts thex-inkeep-tenant-id,x-inkeep-project-id, andx-inkeep-agent-idheaders extracted from the incoming request (reqData), prioritizing these remote, unverified user inputs over the safe default fallback constants (e.g.,'test-tenant').An external attacker can simply send HTTP requests carrying these headers. The middleware will map the target identity to the global execution context (
c.set('executionContext', ...)), completely bypassing any API key authentication or developer bypass secrets (INKEEP_AGENTS_MANAGE_API_BYPASS_SECRET). Although restricted to environments configured for development or testing, this poses a Critical risk if these environments are publicly exposed or deployed in Staging namespaces without explicit warnings.PoC
agents-apiapplication is running locally withENVIRONMENT=development(which is the default in.env.example)./run/agents/{agent_id}/chat.POSTrequest, injecting targeted execution context parameters via thex-inkeep-tenant-id,x-inkeep-project-id, andx-inkeep-agent-idheaders:test-tenantsafety defaults, and attempts to execute the downstream action directly as thehacked-tenantidentity.Log of Evidence
(Note: A
404 Project not foundresponse originating from internal execution validation proves the request completely bypassed the initial Auth/401 layer and operated entirely within the hijacked context).Impact
Affected products
b10c96fc081866fc02c662aa34b002c277ae2563)Severity
Weaknesses
Occurrences
agents/agents-api/src/middleware/runAuth.ts
Lines 581 to 584 in b10c96f
createDevContextfallback improperly prioritizes unverified user HTTP headers (reqData.tenantId) for context assignment over safer default fallback dummy strings ('test-tenant').agents/agents-api/src/middleware/runAuth.ts
Lines 678 to 691 in b10c96f
runApiKeyAuthHandlerroutes unauthenticated requests tocreateDevContextseamlessly whenENVIRONMENTisdevelopmentortest, without requiring explicit verification or developer bypass secrets to map an arbitrary identity.