Skip to content

feat(init): Ask for the profile name and hide the API key - #31

Merged
jdenquin merged 1 commit into
mainfrom
feat/init-prompts
Sep 17, 2026
Merged

jdenquin merged 1 commit into
mainfrom
feat/init-prompts

Conversation

@jdenquin

Copy link
Copy Markdown
Contributor

What changed

lago init, interactive mode only:

  • The API key is read without echoing it (term.ReadPassword), so the prompt reads API key (hidden): and the secret never reaches the scrollback. When stdin is not a terminal, or the reader already holds buffered input, it falls back to the visible prompt — echo was never suppressible there, so tests, pipes, and CI are unaffected.
  • The profile name is asked first, defaulting to the current profile, and re-initing an existing name says so before writing. A name typed at the prompt must match [A-Za-z0-9][A-Za-z0-9._-]{0,63} and is rejected at exit 2 while it can still be retyped.

Both prompts are skipped when --profile/LAGO_PROFILE or --api-key/LAGO_API_KEY already answer them, so scripted init is byte-for-byte unchanged. Names passed via --profile are not validated, so no existing profile stops working.

$ lago init
Profile name [default]: staging
Allow an anonymous release check at most once per day? (y/N) [N]: n
API key (hidden):
Region (us/eu/self-hosted) [us]: eu
Connected to Lago as Example Organization.
Saved eu profile "staging" to ~/.config/lago/config.toml (mode: live).

Why

An API key is a secret, and init was the one command that printed one back to the terminal. It was never asked for the profile name either, so an interactive run always wrote default: configuring a second environment silently overwrote the first, with no point at which the operator could name it.

Verification

Driven through a pty against a stub /organizations server: the key stayed off-screen while every other answer echoed, and it still landed in the profile. make security needs gitleaks, which is not installed locally; it runs in CI.

  • make test
  • make coverage (internal/cli 89.2%, floor 86.0%)
  • make lint
  • make security
  • make generate-check
  • No secrets, customer data, internal URLs, or unreleased roadmap details are included
  • User-facing or JSON-contract changes are documented (README "Configure", CHANGELOG)

🤖 Generated with Claude Code

`lago init` never asked for a profile name, so an interactive run always
wrote `default` and configuring a second environment overwrote the first.
The API key was read with the echoing prompt, leaving a secret in the
terminal scrollback and in screen shares.

init now asks for the profile name first, defaulting to the current
profile, and reads the key through term.ReadPassword. Both prompts are
skipped when --profile/LAGO_PROFILE or --api-key/LAGO_API_KEY already
answer them, so scripted init is unchanged. A name typed at the prompt
must be letters, digits, dots, dashes, or underscores, and re-initing an
existing profile says so before it writes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jdenquin
jdenquin merged commit 49a7a03 into main Sep 17, 2026
12 checks passed
@jdenquin
jdenquin deleted the feat/init-prompts branch September 17, 2026 13:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants