Skip to content

Commit 980ba17

Browse files
Theaxiomclaude
andcommitted
fix: API key auth sends Bearer header, handle null aegis_role for consumer users
Three bugs: 1. Sent key in JSON body instead of Authorization header 2. Rejected null aegis_role (consumer users have zaru_tier, not aegis_role) 3. Hardcoded isOperator=true and operator security context for all API keys Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 49ba1d0 commit 980ba17

1 file changed

Lines changed: 14 additions & 10 deletions

File tree

  • zaru-mcp-server/src/middleware

zaru-mcp-server/src/middleware/auth.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ export function isApiKey(token: string): boolean {
4242
*/
4343
export interface ApiKeyIdentity {
4444
user_id: string;
45-
aegis_role: AegisRole;
45+
tenant_id: string | null;
46+
aegis_role: AegisRole | null;
47+
zaru_tier: string | null;
4648
scopes: string[];
4749
}
4850

@@ -61,8 +63,8 @@ export async function validateApiKeyWithOrchestrator(
6163
method: "POST",
6264
headers: {
6365
"Content-Type": "application/json",
66+
Authorization: `Bearer ${token}`,
6467
},
65-
body: JSON.stringify({ api_key: token }),
6668
});
6769

6870
if (!response.ok) {
@@ -78,11 +80,7 @@ export async function validateApiKeyWithOrchestrator(
7880
if (!body.user_id) {
7981
throw new Error("API key validation response missing user_id");
8082
}
81-
if (!isValidAegisRole(body.aegis_role)) {
82-
throw new Error(
83-
`API key validation response has invalid aegis_role: ${body.aegis_role}`,
84-
);
85-
}
83+
// aegis_role is null for consumer users (they have zaru_tier instead)
8684

8785
return body;
8886
}
@@ -227,12 +225,18 @@ export function createZaruAuthMiddleware(
227225
if (isApiKey(rawToken)) {
228226
try {
229227
const identity = await apiKeyValidator(rawToken);
228+
const isOp =
229+
identity.aegis_role === "admin" || identity.aegis_role === "operator";
230+
const tier = identity.aegis_role ?? identity.zaru_tier ?? "free";
231+
const secCtx = isOp
232+
? OPERATOR_SECURITY_CONTEXT
233+
: `zaru-${identity.zaru_tier ?? "free"}`;
230234
req.zaruUser = {
231235
userId: identity.user_id,
232-
tier: identity.aegis_role,
233-
securityContext: OPERATOR_SECURITY_CONTEXT,
236+
tier,
237+
securityContext: secCtx,
234238
token: rawToken,
235-
isOperator: true,
239+
isOperator: isOp,
236240
};
237241
next();
238242
} catch (error) {

0 commit comments

Comments
 (0)