Implement local agent JWT authentication for adapters
Add HS256 JWT-based authentication for local adapters (claude_local, codex_local) so agents authenticate automatically without manual API key configuration. The server mints short-lived JWTs per heartbeat run and injects them as PAPERCLIP_API_KEY. The auth middleware verifies JWTs alongside existing static API keys. Includes: CLI onboard/doctor JWT secret management, env command for deployment, config path resolution from ancestor directories, dotenv loading on server startup, event payload secret redaction, multi-status issue filtering, and adapter transcript parsing for thinking/user message kinds. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,8 @@ import { createHash } from "node:crypto";
|
||||
import type { RequestHandler } from "express";
|
||||
import { and, eq, isNull } from "drizzle-orm";
|
||||
import type { Db } from "@paperclip/db";
|
||||
import { agentApiKeys } from "@paperclip/db";
|
||||
import { agentApiKeys, agents } from "@paperclip/db";
|
||||
import { verifyLocalAgentJwt } from "../agent-auth-jwt.js";
|
||||
|
||||
function hashToken(token: string) {
|
||||
return createHash("sha256").update(token).digest("hex");
|
||||
@@ -32,6 +33,34 @@ export function actorMiddleware(db: Db): RequestHandler {
|
||||
.then((rows) => rows[0] ?? null);
|
||||
|
||||
if (!key) {
|
||||
const claims = verifyLocalAgentJwt(token);
|
||||
if (!claims) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
const agentRecord = await db
|
||||
.select()
|
||||
.from(agents)
|
||||
.where(eq(agents.id, claims.sub))
|
||||
.then((rows) => rows[0] ?? null);
|
||||
|
||||
if (!agentRecord || agentRecord.companyId !== claims.company_id) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
if (agentRecord.status === "terminated") {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
req.actor = {
|
||||
type: "agent",
|
||||
agentId: claims.sub,
|
||||
companyId: claims.company_id,
|
||||
keyId: undefined,
|
||||
};
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user