<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Octuo team</title>
    <description>The latest articles on DEV Community by Octuo team (octuo).</description>
    <link>https://dev.to/octuo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F15363%2F81e69f90-0e5f-4e66-bf82-dfd88c4ed43c.png</url>
      <title>DEV Community: Octuo team</title>
      <link>https://dev.to/octuo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/octuo"/>
    <language>en</language>
    <item>
      <title>Let an agent sign in for you without showing the model your password</title>
      <dc:creator>Aline Mercer</dc:creator>
      <pubDate>Sat, 17 Oct 2026 09:26:22 +0000</pubDate>
      <link>https://dev.to/octuo/let-an-agent-sign-in-for-you-without-showing-the-model-your-password-34lo</link>
      <guid>https://dev.to/octuo/let-an-agent-sign-in-for-you-without-showing-the-model-your-password-34lo</guid>
      <description>&lt;p&gt;You are halfway through a task with an agent. It has found the settings page and filled in most of the form, and then it stops: "To continue, please paste your password here." Or it needs an API key for the service it is about to call, and the chat box is right there.&lt;/p&gt;

&lt;p&gt;It feels harmless because the conversation feels private. But a chat is not a safe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the chat box is the wrong place
&lt;/h2&gt;

&lt;p&gt;Anything you type into a prompt becomes part of the model's context. Depending on the tool, it may be kept in history, written to logs, sent to a hosted model or summarized into memory that later conversations read. You cannot see or reliably delete all of those copies.&lt;/p&gt;

&lt;p&gt;The same goes for instruction files. Files such as CLAUDE.md or AGENTS.md exist so the model reads them on every run. That makes them a good home for project conventions and a bad home for a token. Treat them as visible to the model, and often to everyone with access to the repository.&lt;/p&gt;

&lt;p&gt;The goal is simple to state: the agent can use a credential, but the raw value never enters the text the model reads or writes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use a store the tool calls for the model
&lt;/h2&gt;

&lt;p&gt;The pattern that works is a credential store or vault that sits outside the conversation. The model asks for an action, such as "sign in to the billing portal" or "call the API with the deploy token", and the tool fetches the secret and uses it directly. The model sees a reference or a result, never the value.&lt;/p&gt;

&lt;p&gt;Your operating system's keychain is the simplest version of this; a dedicated secrets vault adds encryption, access rules and a usage history. Either way, check one thing: when the agent uses the secret, does the value show up in the transcript? If it does, the store is decoration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give the agent less than you have
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scope tokens.&lt;/strong&gt; Create a token for the one job: read-only if reading is enough, one repository, one project. Do not reuse a key that can do everything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expire them.&lt;/strong&gt; A short lifetime turns a leak into a small incident. Set the expiry when you create the token, not later.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prefer OAuth and app passwords over master passwords.&lt;/strong&gt; Delegated access can be limited and revoked without changing the password you use everywhere else. A master password should never be something an agent holds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep 2FA and payments in human hands.&lt;/strong&gt; The second factor is where a person confirms intent. Let the agent get you to that screen; you approve the code, the purchase or the transfer yourself.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Log every use, and read the log
&lt;/h2&gt;

&lt;p&gt;A credential an agent can use should leave a trace each time it is used: which secret, when, and for which task. Many services also keep their own sign-in and API activity pages. Set a recurring reminder to skim both. You are looking for uses you do not recognize, at times you were not working, against services you did not ask about.&lt;/p&gt;

&lt;h2&gt;
  
  
  After a paste accident, rotate
&lt;/h2&gt;

&lt;p&gt;If a secret did land in a chat, a log or a committed file, assume it is exposed. Rotate it at the source, revoke the old value, then clean up the copies you can find. Deleting the message is fine, but it does not replace rotation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Risk and the safer habit
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Risk&lt;/th&gt;
&lt;th&gt;Safer habit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Pasting a password or key into the chat&lt;/td&gt;
&lt;td&gt;Keep it in a vault or keychain the tool reads on the model's behalf&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tokens in CLAUDE.md, AGENTS.md or other instruction files&lt;/td&gt;
&lt;td&gt;Refer to a named secret; never write the value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One broad key reused for everything&lt;/td&gt;
&lt;td&gt;Scoped, per-task tokens with an expiry date&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The agent holds your master password&lt;/td&gt;
&lt;td&gt;OAuth or app-specific passwords you can revoke&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The agent completes 2FA or a payment alone&lt;/td&gt;
&lt;td&gt;You confirm the code, purchase or transfer yourself&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No record of what the agent did with access&lt;/td&gt;
&lt;td&gt;A usage log per secret, reviewed on a schedule&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A secret leaked into a transcript&lt;/td&gt;
&lt;td&gt;Rotate at the source first, then clean up&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Before you let an agent sign in through a browser
&lt;/h2&gt;

&lt;p&gt;Browser sign-in is where agents become most useful for website chores. Before you grant it, check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] The credential comes from a store, not from the chat or a file the model reads.&lt;/li&gt;
&lt;li&gt;[ ] The account has the least access the task needs; a separate, limited account is better where the site allows it.&lt;/li&gt;
&lt;li&gt;[ ] 2FA stays on, and the second factor reaches you, not the agent.&lt;/li&gt;
&lt;li&gt;[ ] Payments, account deletion and security settings need your confirmation.&lt;/li&gt;
&lt;li&gt;[ ] You can see which sites the agent signed in to, and when.&lt;/li&gt;
&lt;li&gt;[ ] You know how to revoke the session or token in one step.&lt;/li&gt;
&lt;li&gt;[ ] Saved browser sessions are cleared or expire when the task is done.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this needs special tooling to start. Move the next secret out of the prompt, shorten the next token's life, and keep the last click on anything irreversible for yourself.&lt;/p&gt;

&lt;p&gt;This post comes from the Octuo team at Tutuo, Inc. More of our notes on handing work to agents are on &lt;a href="https://www.tutuo.ai/en/blog/?utm_source=devto-org&amp;amp;utm_medium=post&amp;amp;utm_campaign=w4&amp;amp;utm_content=pos-vault" rel="noopener noreferrer"&gt;our blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Drafted with AI assistance and reviewed before publishing.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>productivity</category>
      <category>llm</category>
    </item>
    <item>
      <title>The handoff brief: what to write before a coding agent starts</title>
      <dc:creator>Aline Mercer</dc:creator>
      <pubDate>Sat, 17 Oct 2026 08:51:11 +0000</pubDate>
      <link>https://dev.to/octuo/the-handoff-brief-what-to-write-before-a-coding-agent-starts-3a3d</link>
      <guid>https://dev.to/octuo/the-handoff-brief-what-to-write-before-a-coding-agent-starts-3a3d</guid>
      <description>&lt;p&gt;Most agent runs that go sideways don't fail at the code. They fail at the handoff. The task lived in someone's head and the prompt carried only half of it. The diff that comes back answers a slightly different question than the one we meant to ask. Reviewing it then means working backwards from the output to the intent, and that is the slow direction.&lt;/p&gt;

&lt;p&gt;So before we give any non-trivial task to Codex or Claude Code, we write a short handoff brief. Review then becomes a comparison: did the run do what the brief said, and nothing else?&lt;/p&gt;

&lt;h2&gt;
  
  
  What goes in a brief
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Goal&lt;/strong&gt;: the outcome in one or two sentences, not the method.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope&lt;/strong&gt;: what the agent may change, as paths or modules.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Off limits&lt;/strong&gt;: files and behaviour it must not touch, even if it thinks it should.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Checks&lt;/strong&gt;: the exact commands that prove the change works.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Done&lt;/strong&gt;: the observable state that ends the task.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Report back&lt;/strong&gt;: what the summary must contain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escalate, don't guess&lt;/strong&gt;: decisions that belong to a human.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last item does the most work. When an agent hits an ambiguity, it will usually resolve it somehow. If you name the ambiguities up front, a silent guess becomes a question in the report.&lt;/p&gt;

&lt;h2&gt;
  
  
  The template
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Goal&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;What&lt;/span&gt; &lt;span class="na"&gt;should&lt;/span&gt; &lt;span class="na"&gt;be&lt;/span&gt; &lt;span class="na"&gt;true&lt;/span&gt; &lt;span class="na"&gt;when&lt;/span&gt; &lt;span class="na"&gt;this&lt;/span&gt; &lt;span class="na"&gt;is&lt;/span&gt; &lt;span class="na"&gt;done.&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="gu"&gt;## Scope&lt;/span&gt;
May change:
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;path&lt;/span&gt; &lt;span class="na"&gt;or&lt;/span&gt; &lt;span class="na"&gt;module&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

Off limits (do not edit, even to "fix" something):
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;generated&lt;/span&gt; &lt;span class="na"&gt;code&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="na"&gt;migrations&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lockfiles&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="na"&gt;CI&lt;/span&gt; &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;public&lt;/span&gt; &lt;span class="na"&gt;interfaces&lt;/span&gt; &lt;span class="na"&gt;other&lt;/span&gt; &lt;span class="na"&gt;code&lt;/span&gt; &lt;span class="na"&gt;depends&lt;/span&gt; &lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="gu"&gt;## Context&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;Why&lt;/span&gt; &lt;span class="na"&gt;this&lt;/span&gt; &lt;span class="na"&gt;change&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt; &lt;span class="na"&gt;constraints&lt;/span&gt; &lt;span class="na"&gt;the&lt;/span&gt; &lt;span class="na"&gt;code&lt;/span&gt; &lt;span class="na"&gt;doesn&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;t&lt;/span&gt; &lt;span class="na"&gt;show&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;Link&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt; &lt;span class="na"&gt;the&lt;/span&gt; &lt;span class="na"&gt;issue&lt;/span&gt; &lt;span class="na"&gt;or&lt;/span&gt; &lt;span class="na"&gt;prior&lt;/span&gt; &lt;span class="na"&gt;decision&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="gu"&gt;## How to check&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Run: &lt;span class="nt"&gt;&amp;lt;test&lt;/span&gt; &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Run: &lt;span class="nt"&gt;&amp;lt;lint&lt;/span&gt; &lt;span class="err"&gt;/&lt;/span&gt; &lt;span class="na"&gt;type-check&lt;/span&gt; &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Expected: all pass, no tests skipped or deleted

&lt;span class="gu"&gt;## Done means&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;Observable&lt;/span&gt; &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="gu"&gt;## Report back&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Files changed, one line on why for each
&lt;span class="p"&gt;-&lt;/span&gt; Commands run and their results
&lt;span class="p"&gt;-&lt;/span&gt; Anything noticed but not changed
&lt;span class="p"&gt;-&lt;/span&gt; Every assumption made

&lt;span class="gu"&gt;## Escalate instead of guessing&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;Behaviour&lt;/span&gt; &lt;span class="na"&gt;changes&lt;/span&gt; &lt;span class="na"&gt;visible&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt; &lt;span class="na"&gt;callers&lt;/span&gt; &lt;span class="na"&gt;or&lt;/span&gt; &lt;span class="na"&gt;users&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;New&lt;/span&gt; &lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="na"&gt;secrets&lt;/span&gt; &lt;span class="na"&gt;or&lt;/span&gt; &lt;span class="na"&gt;credentials&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;Checks&lt;/span&gt; &lt;span class="na"&gt;that&lt;/span&gt; &lt;span class="na"&gt;cannot&lt;/span&gt; &lt;span class="na"&gt;pass&lt;/span&gt; &lt;span class="na"&gt;without&lt;/span&gt; &lt;span class="na"&gt;touching&lt;/span&gt; &lt;span class="na"&gt;an&lt;/span&gt; &lt;span class="na"&gt;off-limits&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep it short. Codex's docs on managing usage advise controlling the size of prompts and reducing the size of AGENTS.md. The same logic holds for readability, because a brief that restates the codebase gets skimmed. Durable project rules belong in the instruction file the tool already reads (AGENTS.md, CLAUDE.md), and the brief covers only this task. Claude Code's guidance to use /clear when starting a new task fits well here: clear the context, then paste the brief.&lt;/p&gt;

&lt;h2&gt;
  
  
  A vague brief and a better one
&lt;/h2&gt;

&lt;p&gt;The task: a small internal service still calls a deprecated &lt;code&gt;fetchLegacy&lt;/code&gt; method on its HTTP client wrapper.&lt;/p&gt;

&lt;p&gt;The vague version:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Replace the deprecated fetchLegacy calls with the new client API and make sure everything still works.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That brief leaves four questions open:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which files count?&lt;/li&gt;
&lt;li&gt;Must the retry behaviour be kept?&lt;/li&gt;
&lt;li&gt;What does "everything" mean?&lt;/li&gt;
&lt;li&gt;What happens to call sites that pass options the new API lacks?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent will answer all four. We just won't know how until we read the diff.&lt;/p&gt;

&lt;p&gt;The better version:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; no calls to &lt;code&gt;fetchLegacy&lt;/code&gt; remain in &lt;code&gt;src/&lt;/code&gt;; behaviour for callers is unchanged.&lt;br&gt;
&lt;strong&gt;Scope:&lt;/strong&gt; &lt;code&gt;src/clients/&lt;/code&gt; and &lt;code&gt;src/handlers/&lt;/code&gt;. Off limits: &lt;code&gt;src/generated/&lt;/code&gt;, the dependency manifest and lockfile, &lt;code&gt;migrations/&lt;/code&gt;.&lt;br&gt;
&lt;strong&gt;Check:&lt;/strong&gt; unit tests and type-checker pass, with no tests skipped or deleted.&lt;br&gt;
&lt;strong&gt;Done:&lt;/strong&gt; a search for &lt;code&gt;fetchLegacy&lt;/code&gt; in &lt;code&gt;src/&lt;/code&gt; finds only its definition, which stays for a follow-up.&lt;br&gt;
&lt;strong&gt;Report:&lt;/strong&gt; each call site changed, and how retries are handled now.&lt;br&gt;
&lt;strong&gt;Escalate:&lt;/strong&gt; any call site relying on an option the new API lacks. Leave it unchanged and list it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's the same task, but now the reviewer knows what a correct diff looks like before opening it.&lt;/p&gt;

&lt;h2&gt;
  
  
  When the run comes back
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Diff first, summary second.&lt;/strong&gt; The summary is an account of the work; the diff is the work. Check the file list against Scope and Off limits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rerun the checks yourself&lt;/strong&gt;, using the commands from the brief, in a clean state. "Tests pass" in a report is a claim, not evidence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Look for silent scope creep&lt;/strong&gt;: reformatted files, renamed helpers, a nearby cleanup, a loosened assertion, a new dependency. Each may be fine. None should be a surprise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Answer the escalations&lt;/strong&gt; and write the answers down.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Record decisions&lt;/strong&gt; in the brief, the commit message or the PR description, so the next brief starts from there.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Where context gets lost between tools
&lt;/h2&gt;

&lt;p&gt;The weak point is rarely inside one run. It sits between runs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reasoning from a planning chat never reaches the agent.&lt;/li&gt;
&lt;li&gt;An escalation gets answered in one terminal and then forgotten.&lt;/li&gt;
&lt;li&gt;A follow-up starts in another tool without any of the earlier decisions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each tool keeps its own session history. A brief kept in a file and updated with what came back is the one thing that carries across tools. Treat it like code: version it, review it and reuse it.&lt;/p&gt;

&lt;p&gt;This post comes from the Octuo team at Tutuo, Inc. More of our notes on running coding agents are on &lt;a href="https://www.tutuo.ai/en/blog/?utm_source=devto-org&amp;amp;utm_medium=post&amp;amp;utm_campaign=w4" rel="noopener noreferrer"&gt;our blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Drafted with AI assistance; the tool behaviour mentioned was checked against the Codex and Claude Code documentation before publishing.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
