Skip to content

Blog

AI agents should not log in by copying cookies

Why Appaloft separates human browser login, CI tokens, and AI agent token handoff instead of letting agents impersonate users.

AppaloftAICLIAuthAgents

When an AI agent is about to deploy an application for you, the awkward question is often not whether it can write the command. It is how it should log in.

One tempting answer is to let the agent run appaloft login, open a browser, copy a user code, or pull a cookie from the local machine before continuing. That can look magical in a demo. In a real control plane, it muddles identity, permission, and audit.

Appaloft takes a more conservative view: humans can use browser login, CI can use scoped tokens from the environment, and AI agents need an explicit token handoff. An agent should not pretend to be the person sitting in front of the browser.

This post follows Skills are not MCP and focuses on the auth boundary. MCP, CLI, Web, and API can be different entrypoints, but they should not give agents a shortcut around the product permission model.

Three callers need three login shapes

The Appaloft CLI serves three kinds of callers.

The first is a human operator. They are at their own machine, they know which control plane they want to use, and they can confirm an account in a trusted browser. For that case, the browser/auth-session flow behind appaloft login or appaloft auth login makes sense: the CLI prints a login URL and user code, the user confirms in the browser, and the CLI exchanges the result into a local profile.

The second is CI and automation. A GitHub Actions job, deployment pipeline, or scheduled task should not open a browser. It should receive a scoped token from a secret manager or environment variable, such as APPALOFT_TOKEN, and use that token to call the CLI or API. If the scope is not enough, the command should fail before mutation instead of asking the pipeline to complete an interactive login.

The third is an AI agent. It sits somewhere between the first two. It may not have a preconfigured secret like CI, but it also should not control a user’s browser like a human operator. It may run on a user machine, in a remote sandbox, inside an IDE, in a desktop app, or in a hosted runtime. It needs permission, but that permission should be granted by a human through a trusted surface with visible scope, duration, and purpose.

Putting all three callers through the same browser login flow blurs the boundary. The more an agent looks like “a person operating your browser,” the harder the product has to work to explain who authorized what.

Cookies are compatibility, not guidance

Many CLIs accumulate compatibility paths over time: environment variables, cookies, temporary sessions, manual bearer values. Appaloft has supported a local trusted operator path through APPALOFT_AUTH_COOKIE, which can adapt an existing product-session credential.

The problem is not that code can read a cookie. The problem is whether documentation and skills teach that as normal behavior.

If agent-facing guidance says “no profile, go get a cookie,” the failure modes are obvious:

  • the agent may try to inspect browser storage or shell history
  • users may paste product-session cookies into chat or issues
  • the cookie often carries more power than one deployment task needs
  • expiry, revocation, audit, and ownership become ambiguous
  • credentials are more likely to appear in logs, screenshots, fixtures, or pull request text

So Appaloft treats the cookie path as legacy or diagnostic compatibility, not the default auth method for AI or CI. An agent may check whether a usable local profile already exists. It may use a token explicitly provided through the environment. It should not dig through browser state.

What token handoff is trying to do

The better shape is not “the agent logs in for you.” It is “the human hands the agent a key that is just powerful enough.”

In Appaloft, that path breaks down into a few steps:

  1. The agent reads current state with appaloft auth status and appaloft context show.
  2. If a usable profile or APPALOFT_TOKEN is already present, it uses that credential.
  3. If not, the agent stops and asks the user to authorize a scoped token through Cloud UI, a secret manager, or another trusted surface.
  4. The CLI uses that token through an explicit import path, such as appaloft auth token login, or through the environment.
  5. The CLI performs endpoint handshake, current-context readback, and scope readback, then prints only redacted information.
  6. Deployment, observation, and recovery still go through the operation catalog, CommandBus/QueryBus, authz, audit, and redaction.

The exact command name is not the point. The product meaning is the point: token handoff is a noninteractive credential for an agent or automation workflow. It is not a browser session in disguise.

An agent token should eventually answer practical questions. Which organization or project does it belong to? What can it read or write? Can it deploy, roll back, inspect logs, edit resource config, or manage domains? When does it expire? When was it last used? Who created it? Where can it be revoked?

The full scope, expiry, readback, revoke, and audit UI still needs hardening. We should not write about it as if that whole lifecycle is finished. But the direction is clear: agents need smaller, shorter, more explainable permission, not sneakier login.

MCP should not bypass the auth model

MCP can make auth look like a transport problem: once the tool can reach the server, the agent can call it. Real systems need more than that.

A remote MCP gateway should answer the same questions as a CLI command. Who is the current actor? Which tenant do they belong to? Which capabilities are available? Is this tool call read or write? Does it need plan-first behavior? Where is the audit record? How are secrets redacted?

Appaloft’s hosted MCP path should not have MCP-only permissions. MCP tools still map to the operation catalog, and dispatch still lands on the same command/query boundary. Cloud can add team permissions, entitlement, tenant context, audit, and policy at that layer. It should not invent a private route just because the caller is an agent.

That is also how flows such as auth mcp login should be understood: they help a human authorize controlled bearer material for an MCP profile. They are not permission for an agent to operate the user’s browser. A human can authorize; the agent can use the resulting tool entrypoint. Those two actions are better kept separate.

Why agents should not run browser login

A fair question is: if the user is nearby, why not let the agent run appaloft login --no-browser, hand the URL to the user, or copy the user code?

For a human in a terminal-only session, that can be useful. It should not be the default path for AI agents.

This is not ceremony. The interaction meaning of browser login is “this person is confirming this account in this browser.” Once an agent is involved, responsibility is spread across chat, terminal, browser, CLI profile, and possibly a remote sandbox. Was the authorization for the human’s current session, the local CLI, the agent, or future commands? The user may not get a clear chance to see the difference.

Token handoff makes the question explicit: this token is for the agent; it has these scopes; it expires at this time; it can be revoked; its use will be recorded; the raw secret is visible once and should not appear in chat, logs, or screenshots.

Less magic, more revocation. For a deployment control plane, that is a good trade.

Auth is not permission to apply everything

Having a credential does not mean the agent should execute directly.

The workflow should still be: identify the project, environment, resource, server, or Blueprint; produce a plan before creating or changing durable state; show missing secrets, permissions, and external-resource impact; wait for user or policy acceptance; then observe the result through events, logs, health checks, diagnostics, and access readback.

Auth answers “who are you, and what may you do?” It does not answer “should this be done now?” Keeping those questions separate prevents a token from turning an agent into a script that applies changes everywhere.

It also makes revocation clearer. auth logout can remove local profile material. Token revoke can change server-side state. A failed deployment can be retried or rolled back. An overpowered token can be rotated or revoked. Each action has its own meaning, and the audit trail is easier to read.

The default behavior we want

The Appaloft default guidance for AI agent auth can stay short:

  • check appaloft auth status, appaloft context show, and APPALOFT_TOKEN first
  • when no credential is available, ask the user to authorize a scoped token through a trusted UI or secret manager
  • use CLI-supported token import or an environment variable, not chat
  • do not open the browser on behalf of the user
  • do not copy user codes
  • do not read browser cookies
  • do not treat product-session cookies as normal agent auth
  • keep write operations on the same plan, authz, audit, redaction, and readback path

Those rules do not make the demo flashier. They make it possible for a real team to connect agents to a deployment control plane with a straight face.

The value of an AI agent is not that it can bypass login. The value is that, once it has just enough permission, it can follow the product’s existing safe path and make deployment, observation, and recovery faster, steadier, and easier to review.