Skip to content

auth

auth

auth top-level command — authenticate an agent or tool.

Three invocation shapes, in increasing specificity:

  • terok auth — interactive chained menu.
  • terok auth <provider> — host-wide auth for one provider.
  • terok auth <provider> --project name — project-scoped auth.

Where credentials land depends on the named project's credentials_scope: "shared" (default) writes to the host-wide bucket every project sees, "project" carves out a private vault row and agent-config mount tree keyed by the project name. Host-wide terok auth (no --project) always writes to the shared bucket — there's no project context to override it.

register(subparsers)

Register the auth top-level command.

Source code in src/terok/cli/commands/auth.py
def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
    """Register the ``auth`` top-level command."""
    # Accept either an auth-entry name (codex) or the LLM provider it
    # authenticates (openai → codex), since the two can be confusing.
    provider_of = _provider_of()
    accepted = list(AUTH_PROVIDERS) + list(provider_of.values())
    entries = []
    for name, p in AUTH_PROVIDERS.items():
        suffix = f" → {provider_of[name]}" if name in provider_of else ""
        entries.append(f"{name} ({p.label}{suffix})")
    providers_help = ", ".join(entries)
    p_auth = subparsers.add_parser(
        "auth",
        help="Authenticate an agent/tool (host-wide by default; --project scopes it)",
        description=(
            f"Available providers: {providers_help}\n\n"
            "Without arguments, opens an interactive menu to authenticate one "
            "or more providers in sequence.  ``terok auth <provider>`` "
            "authenticates host-wide — credentials are shared across every "
            "project that uses the same agent.  Pass ``--project <name>`` to "
            "scope the auth to a specific project: the project's image is "
            "reused, and if the project opted into per-project credentials "
            "(``credentials.scope: project`` in project.yml) the captured "
            "token lands in that project's private vault row instead of the "
            "shared bucket."
        ),
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    p_auth.add_argument(
        "provider",
        nargs="?",
        default=None,
        choices=accepted,
        metavar="provider",
    )
    set_completer(
        p_auth.add_argument(
            "--project",
            dest="project_flag",
            default=None,
            help="Scope auth to a project (image + project.yml credentials.scope)",
        ),
        _complete_project_names,
    )
    p_auth.add_argument(
        "--device-auth",
        dest="device_auth",
        action="store_true",
        help=(
            "Force the headless device-code login (skip the method chooser) — "
            "for remote/headless hosts with no local browser"
        ),
    )

dispatch(args)

Handle terok auth. Returns True if handled.

Source code in src/terok/cli/commands/auth.py
def dispatch(args: argparse.Namespace) -> bool:
    """Handle ``terok auth``.  Returns True if handled."""
    if args.cmd != "auth":
        return False
    project_name = args.project_flag
    if args.provider is None:
        _run_interactive(project_name, device_auth=args.device_auth)
    else:
        _run_one(args.provider, project_name, device_auth=args.device_auth)
    return True