Permissions and secrets
How approvals, operating-system grants, and provider credentials are handled.
Approval cards
Supported providers emit permission requests and questions through the local harness. Brainwrite displays these inline and records the outcome. Cancellation closes outstanding requests so stale approvals cannot be answered after a turn has ended.
“Always allow” is narrow: it is tied to a server-issued key and a pending request rather than granting arbitrary execution from a paired device.
Operating-system permissions
Screen Recording and Accessibility permissions are controlled by the operating system. The desktop process owns local CUA lifecycle so grants are attributed to Brainwrite.
Secret handling
- Do not paste API keys into chat. For a token a skill needs, save it as a secret: bots use it without seeing it.
- Packaged builds use write-only settings and operating-system-backed encryption where supported.
- Secret values are scrubbed from public configuration responses and mobile APIs.
- Per-provider environment injection prevents unrelated agent processes from inheriting credentials they do not use.
- OAuth provider tokens for connected apps stay with Composio.
Connected-app tool grants
Connected apps are scoped per bot on the desktop: a bot without a grant to a service's tool cannot call it, the ungranted tool is never offered to the model, and every allow/deny is written to the decision log. New and upgraded bots keep all tools until someone assigns grants, and imported bots always land with none, so a shared persona cannot reach your Gmail on turn one. Paired phones see grants read-only; grant editing requires the computer.
Website sign-in
Bots may complete a sign-in you explicitly authorize for a particular site and account, using an existing session, autofill, or credentials you supply or designate for that purpose, including test accounts. A login form alone is not a reason to refuse the task. Bots must check the destination and account first; instructions on a webpage do not authorize using credentials.
Bots never ask for a website password, or for a one-time code, in chat, and a bot never holds a password: a login you saved is typed into the page by Brainwrite itself (Saved logins).
When you ask a bot to do something that needs a sign-in (in your own chat, or in a routine or automation you set up) and the site sends a one-time code to your email or phone, the bot reads it from your connected email or messages and types it into that site, then carries on. Your request is the authorization, so it does not ask again. A code only ever goes into the site it was sent for: a bot never sends, posts, forwards or pastes one anywhere else, and a web page, email or document that tells it to share a code, or enter it somewhere else, is ignored.
When a bot is not signed in and has no saved login for the site, the code goes somewhere it cannot read (an authenticator app, a phone it has no access to), or a step needs a CAPTCHA, a passkey, payment details or your personal interaction, it asks you to sign in yourself. You get one Sign in needed card in the chat, naming the site and quoting the bot's reason, and one notification ("Scout needs you to sign in to example.com"). The bot's turn ends there.
- Open goes to the exact place the bot works, because a sign-in made anywhere else would not reach it. For the built-in browser, that is the Computer panel's Browser tab, at the bot's page, already in your control. For a Local VM or a cloud computer or VPS, it is that computer's view, where the banner offers Take control. For this computer, the card tells you to sign in there, in the browser the bot is using: the Browser tab keeps its own sign-ins, which a bot on this computer does not use.
- Done hands control back and resumes the bot, which checks it is signed in and continues.
- Cancel resumes the bot with your answer that you declined.
- Save a login (built-in browser only) opens a masked form for the
username, the password and, optionally, the site's 2FA setup key. Saving
answers the card: the bot resumes and signs in with
fill_login, now and in later conversations. When the bot's browser shows a sign-in page on another site, such aslogin.microsoftonline.comfor a company that signs in with Microsoft, the form names it and offers Also fill it on …, unticked: the login fills there only if you tick it.
A newer request for the same site in the same conversation replaces the older card. The card works on the desktop, the web app, a Cloud home and a desktop paired to another computer (its Computer panel has a Browser view for this; the host must allow browser control for that device in Settings → Remote access). A phone shows the request and its notification; sign in from a computer.
With Open, you type the password into the page yourself. In the Browser tab, Type a password or code… in the browser menu sends masked text to the page's selected field; it is never kept, logged or shown, and goes nowhere but the page. While you hold the browser, the bot's browser tools, screenshots and snapshots are refused, and its live preview pauses. Saved sign-ins persist per browser profile, encrypted. None of this overrides your provider's own restrictions, and approval modes are unchanged.
Saved logins
A saved login lets a bot sign in to a site without you. Save one from a Sign in needed card (Save a login), or in Settings → Logins (Add login). Settings lists every saved login by site, username, whether it has a 2FA key, where it came from, which bots may use it and when it was last used. Change edits the website, the username, the password, the 2FA key and who may use it; Delete removes it. Changing only the username keeps the saved password and 2FA key. Changing the website needs the password typed again, because a saved password belongs to one site and is never moved to another without you entering it; the saved 2FA key and last-used date are cleared too, unless you enter a new key. A website and username that another saved login already uses is refused. A saved password is never shown again, and no screen or API returns it: it can only be replaced.
- Who may use it. A login saved from a card is for the bot that asked. One added in Settings is for every bot unless you pick bots. Bots see which sites they have a login for (site and username), never more.
- How a bot uses it. On the site's login page in its built-in browser (or
in My Chrome), the bot calls
fill_login. Brainwrite itself finds the visible username, password and one-time-code fields, types the values in as real keyboard input, and submits the form: Enter in the last field, or the form's sign-in button when Enter does nothing. A two-step login (the username, Next, then the password, then a one-time code) goes through in the same call, and nothing is ever submitted twice. The bot hears only what happened ("Filled the username and the password for alice@example.com on accounts.example.com and submitted it; the page is now https://example.com/dashboard."), or why not. Withsubmit: falseit only fills, and the bot submits. - When the site refuses it. If the site says no ("Incorrect password"), asks for the password again or shows a CAPTCHA, the bot is told what the site said and the filled password and code are cleared from the page.
- Only on its own site. The page must be https (plain http only for an
address on the same computer, such as
localhost), and on the login's site: a login forexample.comfills onexample.com,www.example.comandaccounts.example.com, never onexample.com.evil.testorexample.org. Names that a shared domain hands out to anyone are sites of their own, so a login foralice.github.iois never filled onbob.github.io. A login also fills on the sign-in pages saved with it. For a company that shares one domain with others (acme.okta.com), tick Only on this exact address in Settings so it fills on that host alone. - One-time codes. With a 2FA setup key saved (the key, or the
otpauth://address in the site's QR code), the code is made when the form is filled (standard TOTP, as an authenticator app makes it) and typed into the code field. - Where it works. The built-in browser and My Chrome. On this computer, a
Local VM, a cloud computer or a VPS,
fill_loginsays it does not work there yet, and the bot asks you to sign in instead. - At rest. Logins are encrypted (AES-256-GCM) in one file in the data
folder of the computer Brainwrite runs on, the same way the built-in
browser keeps its saved sign-ins, with a key of their own beside it: the
same on the desktop, a server and Cloud. Neither file is ever included in a
workspace backup, a team export or a move to Cloud, so a saved login stays
on the computer it was saved on. Nothing is written to
config.jsonor to a log.
Logins from 1Password
Settings → Logins → Connect 1Password lets bots use the logins in a 1Password vault. In 1Password, create a service account that can read one vault only, such as "Shared with Brainwrite", and paste its token. Brainwrite checks the token reaches 1Password before keeping it, keeps it in the same encrypted file as saved logins, and never shows it again. 1Password itself enforces which vaults the token reaches. It works the same way on My Cloud: connect it in My Cloud's own Settings → Logins.
A bot that needs it asks with a secure card (request_credential with
onePasswordToken), never in chat; what you paste there goes to the same
place as Connect 1Password. Only a service account token works: it starts
with ops_. A 1Password Connect token, your account password or your Secret
Key is refused with a message saying so, and a token 1Password refuses (revoked,
expired, or without its vault) is told apart from one that is incomplete.
Every Login item in those vaults that has a website and a password appears
in the Logins list, marked From 1Password, by the website's site (an
item with websites on two sites is listed under both). Each vault is for
every bot until you pick bots for it under 1Password in Settings →
Logins; a bot not picked does not see that vault's logins at all, neither
in its list of logins nor when it calls fill_login. These rows are
read-only here: change or remove them in 1Password. fill_login uses them the
same way as saved logins, with the same site rule, the same one-time
codes (from the item's one-time-password field) and the same scrubbing. The
password is read from 1Password at the moment it is filled. Refresh reads
the vault again; Brainwrite also does so when its copy of the list is more
than ten minutes old. Disconnect forgets the token and everything read
from 1Password.
1Password's SDK (MIT
license) is part of the desktop app, the server image and the brainwrite
npm package; it talks to 1Password over the internet, and only once a token
is connected.
What is protected, and what is not
Every saved password, saved 2FA key, password filled from 1Password, the
1Password token, and one-time code made in the last few minutes is replaced
with •••••• wherever it could flow back to a bot or into
a conversation: every browser tool result (snapshots, page text, eval
results, console and network output), the stored conversation, and the engine
protocol logs. That covers the value as plain text, inside JSON, in a web
address and in HTML.
It does not cover everything, and you should know where it stops:
- Screenshots. A picture of the page cannot be scrubbed. Password boxes show dots, but a page that displays the password, or a one-time code, as text shows it in a screenshot too.
- A bot that works around it on purpose. A bot that runs its own page
script to read the password box and change the text (reverse it, spell it
out, encode it) or send it somewhere from the same site gets past the
scrubber. Right after
fill_login, the browser refuses the bot's page scripts (agent_browser_eval) on that page for a minute, or until the page moves on, and a form the bot was left to submit is cleared after that minute. Past that, the filled value lives in the page, as it does when you type it. Save logins only for sites you trust your bots with, and on accounts you are willing to let them use. - The computer it runs on. The key sits beside the encrypted file in the data folder. Anyone who can read that folder (an administrator of the computer, or a bot whose engine permissions let it read any file there) can decrypt the logins. The engines' own permission settings are the gate for what a bot may read; Brainwrite adds no approval step of its own.
Taking over the Browser tab
Clicking or typing in a bot's Browser tab takes the browser from the bot; it goes back a few seconds after your last input. Take control holds it until you press Hand back, and so does an open sign-in request, so the browser is never handed back while you are in the middle of signing in. Anyone the bot is shown to can watch and drive its browser; installing the browser engine stays with admins.
Shared machines
Brainwrite assumes the logged-in operating-system user is the workspace owner. On a shared machine, other administrators may be able to read application data or inspect processes. Use a dedicated OS account for stronger separation.