mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-29 04:25:52 +01:00
fix(server): stage a token-free API helper and drop curl from the access note
The generated Paperclip API access note taught agents to put the run bearer on a curl command line, which any process running as the same user can read. Every run now gets a paperclip-api helper staged onto PATH; the helper reads the token from its own environment and sets the Authorization header itself, so the token never becomes a command-line argument. The helper rejects an absolute URL, a scheme-relative path, and a path containing a backslash, and it verifies the built request resolves to the configured API origin before sending it. Staging now runs for every run, not only a managed-GitHub run, so a host-GitHub run still gets the helper. The note renders only when the helper was actually staged, checked through the one env field the staging step itself sets, so the note and the staging step cannot drift apart. Co-authored-by: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
f45b06a150
commit
a2d014d2ef
7 files changed
+362
-33
No files matched your search
@@ -46,6 +46,7 @@ import {
|
||||
prepareGitHubOperationLaunchers,
|
||||
prepareGitHubExecutionEnvironment,
|
||||
startAdapterExecutionTargetPaperclipBridge,
|
||||
type OperationLauncherProgram,
|
||||
} from "@paperclipai/adapter-utils/execution-target";
|
||||
import { agentService } from "./agents.js";
|
||||
import { normalizeLegacyRunnerProvider } from "@paperclipai/adapter-utils";
|
||||
@@ -22131,6 +22132,12 @@ export function heartbeatService(
|
||||
runtimeConfig = { ...runtimeConfig, env: gitExecutionEnv };
|
||||
for (const key of MANAGED_GITHUB_TOKEN_KEYS) secretKeys.add(key);
|
||||
context.githubAuthenticationMode = useHostGitHub ? "host" : "managed";
|
||||
// Stage the token-free `paperclip-api` helper on every run, not only a
|
||||
// managed-GitHub run. The generated API access note assumes the helper is
|
||||
// on `PATH` whenever the run environment carries `PAPERCLIP_API_KEY`, and a
|
||||
// host-GitHub run still carries that key.
|
||||
let operationLauncherEnv = gitExecutionEnv;
|
||||
let operationLauncherPrograms: readonly OperationLauncherProgram[] = ["paperclip-api"];
|
||||
if (!useHostGitHub) {
|
||||
const githubBrokerToken = createRuntimeToolsToken({
|
||||
agentId: agent.id,
|
||||
@@ -22139,22 +22146,24 @@ export function heartbeatService(
|
||||
responsibleUserId: responsibleUserId ?? "",
|
||||
scope: "github_credentials",
|
||||
});
|
||||
const githubBrokerEnv = githubBrokerEnvironment(gitExecutionEnv, {
|
||||
operationLauncherEnv = githubBrokerEnvironment(gitExecutionEnv, {
|
||||
url: configuredPaperclipApiBaseUrl() ?? "",
|
||||
token: githubBrokerToken?.token ?? "",
|
||||
});
|
||||
githubLauncherLocation = { runId: run.id, target: executionTarget };
|
||||
runtimeConfig = {
|
||||
...runtimeConfig,
|
||||
env: await prepareGitHubOperationLaunchers({
|
||||
runId: run.id,
|
||||
target: executionTarget,
|
||||
cwd: executionWorkspace.cwd,
|
||||
env: githubBrokerEnv,
|
||||
}),
|
||||
};
|
||||
operationLauncherPrograms = ["git", "gh", "paperclip-api"];
|
||||
secretKeys.add("PAPERCLIP_GITHUB_BROKER_TOKEN");
|
||||
}
|
||||
githubLauncherLocation = { runId: run.id, target: executionTarget };
|
||||
runtimeConfig = {
|
||||
...runtimeConfig,
|
||||
env: await prepareGitHubOperationLaunchers({
|
||||
runId: run.id,
|
||||
target: executionTarget,
|
||||
cwd: executionWorkspace.cwd,
|
||||
env: operationLauncherEnv,
|
||||
programs: operationLauncherPrograms,
|
||||
}),
|
||||
};
|
||||
context.paperclipEnvironment = {
|
||||
id: selectedEnvironment.id,
|
||||
name: selectedEnvironment.name,
|
||||
|
||||
Reference in new issue
Block a user