Skip to content

Authentication orchestration: challenges, account selection, login, and save consent #157

Description

@SarthakWade

User flow

An agent attempts an action, the site requires authentication, and Headless returns a structured AUTH_REQUIRED challenge containing the exact origin and matching account aliases. The agent asks the user which alias to use, submits that alias, Headless fills and submits inside the trusted host, and the agent retries the original action.

headless auth login --challenge ID --account ALIAS
headless auth login --interactive

A successful login does not imply permission to save the credential.

Challenge contract

  • Challenges are short-lived, single-use, session-bound, and invalidated by top-level origin changes.
  • Only aliases for the current authentication origin are returned; aliases never enter page DOM.
  • Challenge responses distinguish a confirmed authentication requirement from a heuristic hint.
  • Login success is verified before offering to save credentials.
  • OAuth redirects, cross-origin frames, passkeys, MFA, CAPTCHA, and failed logins return explicit continuation states instead of guessing.
  • The original blocked action is not replayed automatically after login; the agent takes a fresh snapshot and retries deliberately.

Save consent

Saving is always a separate decision.

Interactive CLI login asks Save this credential? [y/N] with No as the default. The macOS app uses a native secure input sheet with an unchecked Save option. Agent-controlled login returns a short-lived save offer so the agent can ask the user.

Save offers are session-bound, origin-bound, single-use, and expire quickly. Candidate secrets remain only in temporary protected memory and are erased after acceptance, rejection, expiry, origin change, session close, or host termination.

Support explicit choices to save under a selected alias, decline once, or never ask for the origin. A login must never be saved solely because an agent requested it without the required user authorization.

Direct credential freedom

Users may continue giving credentials directly to an agent and using normal fill commands. Add settings for:

  • Aliases only, the default.
  • Allow direct credentials for the current session.
  • Always allow direct credentials.

Headless still redacts direct values from its own logs, flows, snapshots, traces, diagnostics, and errors. The UI and documentation must warn that Headless cannot remove a password from model-provider history or tool transcripts after the user supplies it to an agent.

A GUI command such as auth login --interactive opens a native secure field. Passwords must never be entered into generic GUI command text, completion history, or shell arguments.

Authorization by deployment tier

Local or community macOS build

Developer ID macOS build

The same command contract applies. Session-level and trusted-origin approvals may be enabled only if #154 approves the signed broker identity, storage, expiry, revocation, and audit design. Notarization alone must not silently broaden credential permissions.

Linux

Authorization behavior follows the accepted broker policy and available desktop secret service. Lack of a secure backend or user-presence mechanism is reported explicitly rather than weakening the policy.

Private contexts

Private contexts cannot see normal-profile aliases, approvals, credentials, cookies, or storage. They may use only in-memory credentials enrolled within that private context. All associated state is destroyed when the final session using the context closes, as tracked in #35.

Acceptance criteria

  • Parser, protocol, capability, help, and both-engine E2E coverage ship together.
  • False-positive and false-negative authentication detection cases are tested.
  • Origin, iframe, replay, prompt-injection, alias-enumeration, redirect, expiry, and denial cases fail closed.
  • Local macOS builds cannot activate signed-only approval modes through agent-facing surfaces; the explicit user-controlled exception in Unsigned macOS credentials: user-authorized use without repeated confirmation #166 is the only proposed unsigned-build bypass.
  • Flows, snapshots, traces, logs, errors, and diagnostics never contain password values.
  • Existing raw fill remains compatible and never implicitly saves a credential.
  • Login, save, approval, denial, logout, session restart, host restart, and private-context cleanup are covered.
  • Documentation clearly separates Headless redaction guarantees from model-provider retention.

Blocked by #153, #154, #155, and #156.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:agent-runtimeInjected JS: inspection, pruning, refsarea:core-protocolHeadlessProtocol: wire protocol, validation, transportarea:linux-hostChromium host (LinuxHost/, CDP)area:macos-hostWKWebView host (main.swift, Host/)priority:highBlocks a roadmap phasestatus:blockedWaiting on another item or an owner decisiontype:featureNew capability or commandtype:securitySecurity boundary or hardening

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions