Skip to content

Epic: CLI user authentication against a Seamless Auth instance #38

Description

@Bccorb

Summary

Add user authentication to the Seamless CLI so a developer can log in against a Seamless Auth instance (self-hosted or managed) and use the resulting session to call authenticated and admin endpoints from the terminal.

Today the CLI (the seamless bin in this repo) only scaffolds projects, runs Docker, verifies conformance, and sends an admin invite via a shared bootstrap secret. It has no user login, no token storage, and no authenticated API client. This Epic delivers that foundation.

Why

Three planes of "logging in" exist in the ecosystem:

  1. Data plane: end-users of apps built on Seamless. Not the CLI's job.
  2. Managed-service control plane: seamless-portal-api (provisioning, billing, apps, infra). Portal login proxies to a Seamless Auth instance via @seamless-auth/express, so portal login is architecturally the same auth contract as instance login.
  3. Auth-instance admin plane: a Seamless Auth instance's own /admin, /system-config, /organizations, /users, and /sessions.

This Epic targets the instance plane first (Bearer and JSON, no server or contract changes), which covers the majority of the value. Any adopter can authenticate a CLI against their instance, log in through their own instance, and reach its admin endpoints. Portal login is a later phase, tracked but out of scope here (see Deferred below).

Contract used (no API changes required)

The CLI uses the existing Bearer and JSON contract on a Seamless Auth instance:

  1. POST /login with { identifier } returns an ephemeral token (5 minute TTL).
  2. GET /otp/generate-login-email-otp with the ephemeral Bearer token sends the code and returns a refreshed ephemeral token.
  3. POST /otp/verify-login-email-otp with the ephemeral Bearer token and { verificationToken } returns { token (access), refreshToken (opaque), ttl, refreshTtl, ... }.
  4. POST /refresh with the opaque refresh token in the Authorization header rotates both tokens.

Scope

Known constraints

  • Ephemeral token TTL is 5 minutes, so login must complete promptly.
  • A hardcoded per-IP OTP limiter (10 requests per 15 minutes) applies to every /otp/* call. The CLI must cap local retries and surface a 429 cleanly rather than retrying into a lockout.
  • Every /refresh rotates both tokens and detects reuse (it revokes the session chain on replay). The client must store the new refresh token after each refresh.

Deferred (Phase 2, not in this Epic)

Portal login (managed account: provisioning, infra, billing). Portal protected routes are cookie-gated with no Bearer path, so this needs a cookie-jar client or a coordinated contract change to add Bearer support. The decision is deferred until the instance layer ships.

Roadmap

Continues the CLI direction tracked under milestone M7 "CLI, Programmatic and AI Access" and relates to the cross-platform keychain work for the secrets-manager CLI in fells-code/seamless-secrets#26.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:cliSeamless CLIepicLarge tracking issue spanning multiple tasks

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions