Move secrets between users and computers without the model seeing them
A new personal env scope (paradigm user: one user's secret for one bot) beats every other scope, reaches only that user's runs of that bot, and is redacted like any secret. Bots take secrets in with request_secret, which puts a [secret-request:ID] card in the chat: the user types the value into a masked input there, never into a message, and the bot is told only the key. Bots show secrets with capture_secret (a task's computer tool that saves a file or a command's output straight to a personal env, then redacts it from the rest of the run) and show_secret (an env by key): both give a [secret:ID] chip whose Reveal and Copy fetch the value on click, for its own user (personal) or a super admin (anything else), logged by key. Values never go into messages, page props, history, Copy chat or logs. Users manage their own secrets on Settings > Secrets; the Environment page lists everyone's, remove only. Deleting a bot or user removes its personal secrets, and SecretsNote tells bots never to ask for or print secrets in chat. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -51,12 +51,26 @@ export const ProposalRefHrefPrefix = "#proposal-";
|
||||
*/
|
||||
export const HookProposalRefHrefPrefix = "#hook-proposal-";
|
||||
|
||||
/**
|
||||
* The link target a secret ref (`secretRef`) becomes, e.g. `#secret-ref-12`.
|
||||
* The chat renders it as a masked chip with Reveal and Copy.
|
||||
*/
|
||||
export const SecretRefHrefPrefix = "#secret-ref-";
|
||||
|
||||
/**
|
||||
* The link target a secret request ref (`secretRequestRef`) becomes, e.g.
|
||||
* `#secret-request-4`. The chat renders it as a chip that opens the card
|
||||
* the user types the secret into.
|
||||
*/
|
||||
export const SecretRequestRefHrefPrefix = "#secret-request-";
|
||||
|
||||
/**
|
||||
* Turns every computer ref (`[computer:3]`) and take-over ref
|
||||
* (`[take-over:3:browser]`), bot ref (`[bot:3]`), workspace ref
|
||||
* (`[workspace:2]`), file ref (`[file:12]`), folder ref
|
||||
* (`[folder:computer:3:seo/raw]`), proposal ref (`[proposal:7]`) and hook
|
||||
* proposal ref (`[hook-proposal:4]`) in a message into a markdown link, so it
|
||||
* proposal ref (`[hook-proposal:4]`), secret ref (`[secret:12]`) and secret
|
||||
* request ref (`[secret-request:4]`) in a message into a markdown link, so it
|
||||
* survives markdown rendering as a link the chat can swap for a button,
|
||||
* chip or download.
|
||||
*
|
||||
@@ -87,6 +101,11 @@ export default function linkComputerRefs({ text }: { text: string }) {
|
||||
/\[hook-proposal:(\d+)\](?!\()/g,
|
||||
(_, id: string) => `[hook proposal ${id}](${HookProposalRefHrefPrefix}${id})`,
|
||||
)
|
||||
.replace(/\[secret:(\d+)\](?!\()/g, (_, id: string) => `[secret ${id}](${SecretRefHrefPrefix}${id})`)
|
||||
.replace(
|
||||
/\[secret-request:(\d+)\](?!\()/g,
|
||||
(_, id: string) => `[secret request ${id}](${SecretRequestRefHrefPrefix}${id})`,
|
||||
)
|
||||
.replace(/\[file:(\d+)\](?!\()/g, (_, id: string) => `[file ${id}](${FileRefHrefPrefix}${id})`)
|
||||
.replace(/\[folder:([a-z]+):(\d+):([^\]\n]+)\](?!\()/g, (_, volume: string, owner: string, path: string) =>
|
||||
`[${path}](${FolderRefHrefPrefix}${encodeURIComponent(`${volume}:${owner}:${path}`)})`,
|
||||
|
||||
Reference in New Issue
Block a user