mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-10 12:37:55 +01:00
Clarify safe response and saved-wait recovery after secret denial
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
b68826b5df
commit
f49c92870a
2 files changed
+21
-1
No files matched your search
@@ -169,6 +169,26 @@ describe("secret routes", () => {
|
||||
expect(mockLogActivity).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("gives a denied agent safe response and saved-wait options without echoing the submitted value", async () => {
|
||||
const value = "private-denial-canary-value";
|
||||
const res = await request(createApp({
|
||||
type: "agent", agentId: "agent-1", companyId: "company-1", source: "agent_jwt",
|
||||
})).post("/api/companies/company-1/secrets").send({ name: "Deployment key", value });
|
||||
|
||||
expect(res.status).toBe(403);
|
||||
expect(res.body.error).toContain("finish the current conversation response");
|
||||
expect(res.body.error).toContain("without claiming that credential setup is complete");
|
||||
expect(res.body.error).toContain("first create a non-governing secure-save acknowledgment");
|
||||
expect(res.body.error).toContain("request_human_input");
|
||||
expect(res.body.error).toContain("request_confirmation");
|
||||
expect(res.body.error).toContain("never ask for the secret value in that card");
|
||||
expect(res.body.error).toContain("Wait only on the actual saved request");
|
||||
expect(JSON.stringify(res.body)).not.toContain(value);
|
||||
expect(res.body).not.toHaveProperty("details");
|
||||
expect(mockSecretService.create).not.toHaveBeenCalled();
|
||||
expect(mockLogActivity).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it.each([undefined, ""])("validates a board caller's missing or empty managed value %j", async (value) => {
|
||||
const res = await request(createApp()).post("/api/companies/company-1/secrets")
|
||||
.send({ name: "Deployment key", value });
|
||||
|
||||
@@ -888,7 +888,7 @@ export function secretRoutes(db: Db, deps: SecretRoutesDeps = {}) {
|
||||
const companyId = req.params.companyId as string;
|
||||
if (req.actor.type === "agent") {
|
||||
assertCompanyAccess(req, companyId);
|
||||
throw forbidden("Company secret creation requires a human board operator. Ask the human to enter the value in Settings → Secrets for this company. Do not send secret values in chat or tool calls.");
|
||||
throw forbidden("Company secret creation requires a human board operator. Ask the human to enter the value in Settings → Secrets for this company. Do not send secret values in chat or tool calls. You can finish the current conversation response with these secure-entry instructions without claiming that credential setup is complete. If you need a resumable wait, first create a non-governing secure-save acknowledgment with request_human_input using request_confirmation; ask only whether secure entry is complete, never ask for the secret value in that card. Wait only on the actual saved request.");
|
||||
}
|
||||
assertCompanySecretWrite(req, companyId);
|
||||
next();
|
||||
|
||||
Reference in new issue
Block a user