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

  1. added
    type:featureNew capability or command
    type:securitySecurity boundary or hardening
    area:core-protocolHeadlessProtocol: wire protocol, validation, transport
    area:macos-hostWKWebView host (main.swift, Host/)
    area:linux-hostChromium host (LinuxHost/, CDP)
    area:agent-runtimeInjected JS: inspection, pruning, refs
    status:blockedWaiting on another item or an owner decision
    on Sep 10, 2026
  2. yashranaway commented on Sep 10, 2026

    @yashranaway
    Collaborator

    Unsigned rules for this flow: Touch ID or the macOS account password every time a saved credential is used. No session-level or trusted-origin approvals. #166 is not in this cut.

    Direct fill stays for test passwords. Default once the vault exists is aliases only, with a clear warning that Headless cannot scrub a secret out of the model provider after the user typed it to the agent.

    Native save sheet plus interactive CLI is enough. Don't block this on the Settings window in #158.

  3. yashranaway commented on Sep 11, 2026

    @yashranaway
    Collaborator

    Still after #155 and #156. Decision 24 (#171) is the policy: AUTH_REQUIRED with aliases, Touch ID every saved use, native save sheet plus interactive CLI, no Settings window, no silent fill.

    Direct fill stays for test passwords. Default is aliases only once the vault exists.

  4. yashranaway commented on Sep 13, 2026

    @yashranaway
    Collaborator

    This is on main. Confirmed login forms return AUTH_REQUIRED with a short-lived challenge and origin-scoped aliases. auth login --challenge --account and auth login --interactive fill inside the host. Save is a separate native/CLI consent after a successful login. The original action is not replayed. #166 stays out.

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