Skip to content

fix(api): derive default API base URL from the login environment - #13

Merged
emsearcy merged 4 commits into
mainfrom
claude/autopatch-scan-29eb251e-vuln-4956724-uubawi
Oct 20, 2026
Merged

emsearcy merged 4 commits into
mainfrom
claude/autopatch-scan-29eb251e-vuln-4956724-uubawi

Conversation

@dealako

@dealako dealako commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

lfx auth login --audience and lfx api --hostname are removed. Neither the audience requested at login nor the API base URL lfx api uses is configurable per invocation anymore; both are always the compiled-in default for the login's --env (see lfx auth environments).

This replaces the PR's original approach (persisting the login audience and validating it against the environment's compiled-in default before using it as lfx api's base URL), per review feedback: that approach left --audience effectively dead outside development, since a non-default stored audience could never actually be used by lfx api, and --hostname was independently gated to development logins. Removing both flags (and no longer persisting an audience at all) is a cleaner fix: there's no longer an audience field in state.json to tamper with, and no --hostname escape hatch to reason about.

Changes

  • internal/commands/auth.go: removes --audience from lfx auth login; the audience sent to Auth0's device code endpoint is always defaultAudienceForEnvironment(env). lfx auth status's "Audience:" line is now computed from the stored Environment the same way, instead of read back from state.json.
  • internal/commands/api.go: removes --hostname from lfx api; its base URL is unconditionally defaultAudienceForEnvironment(env). Removes the now-unreachable apiDefaultBaseURL validation helper.
  • internal/commands/environment.go: doc-comment updates for the above (drops the --hostname/--audience rationale that no longer applies).
  • internal/credstore/credstore.go: removes DeviceState.Audience -- nothing in state.json can influence which host receives a bearer token anymore.
  • internal/commands/api_test.go: removes TestAPIDefaultBaseURL and TestRunAPIRefusesTamperedAudience (both tested the removed validation layer; there's nothing left to validate against).
  • internal/credstore/credstore_test.go: drops Audience from the DeviceState round-trip test.
  • README.md: updates the lfx api base URL description to reflect that it's no longer configurable.

Behavior changes

  • lfx auth login --audience and lfx api --hostname no longer exist; passing either is a parse error.
  • lfx auth login's requested audience, and lfx api's base URL, are always the compiled-in default for the login's environment -- there is no supported way to point either at a different API/audience anymore, including in development.
  • State files from before this PR (including ones written by this PR's earlier revision, which persisted audience) keep working: Audience is simply ignored/dropped from state.json on the next write, since it's no longer part of DeviceState.

Suggested release: minor (removes two user-facing flags).

Testing

  • go build ./..., go vet ./..., go test ./..., and gofmt -l . all pass.
  • Manually verified: lfx auth login --help and lfx api --help no longer list --audience/--hostname; lfx auth login --insecure-storage --with-token --env development followed by lfx auth status --insecure-storage shows the correct compiled-in Audience: for the stored Environment; lfx api against a stored login with an invalid refresh token fails with the expected refresh error before ever constructing a request to the API host.
  • golangci-lint/revive were not run locally due to an unrelated local Go-toolchain/linter export-data version mismatch (go1.27.2 vs. the installed golangci-lint's go1.27.1 build); not specific to this change.

🤖 Generated with Claude Code

https://claude.ai/code/session_01L8qMuq3je1uuU2JMLHuYBG


Generated by Claude Code

Copilot AI balanced review requested due to automatic review settings October 1, 2026 22:19
@dealako
dealako requested review from a team and emsearcy as code owners October 1, 2026 22:19
@dealako
dealako requested a review from jordane October 1, 2026 22:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The implementation and coverage are sound; the remaining README wording issue is non-blocking.

Review effort: Balanced
Findings: 1 Low severity

Open (1)
What changed in this PR

Derives the default lfx api base URL from the authenticated environment rather than persisted audience data.

Changes:

  • Validates stored audiences against compiled-in environment defaults.
  • Documents the updated audience and API routing behavior.
  • Adds unit and integration coverage for mismatched audiences.
File Description
README.md Documents default API routing behavior.
internal/​commands/​api.go Adds environment-based URL selection and validation.
internal/​commands/​api_test.go Tests defaults and mismatch refusal.
internal/​commands/​auth.go Updates token-resolution documentation.
internal/​credstore/​credstore.go Clarifies persisted audience usage.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread README.md Outdated
Without --hostname, `lfx api` now always uses the compiled-in default
API audience for the login's environment as its base URL, rather than
the audience value persisted in state.json. A stored audience that
differs from that default is refused with an error asking the user to
run `lfx auth login` again (or, for development logins, to pass
--hostname explicitly), mirroring the existing IdP domain consistency
check in loadDeviceStateForBackend.

Logins made with a non-default --audience therefore need --hostname
(development only) to use `lfx api`; `lfx auth token` is unaffected.

Signed-off-by: David Deal <ddeal@linuxfoundation.org>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8qMuq3je1uuU2JMLHuYBG
@dealako
dealako force-pushed the claude/autopatch-scan-29eb251e-vuln-4956724-uubawi branch from 2d50739 to cbe5782 Compare October 1, 2026 22:22
Describe the environment's default API as the behavior when --hostname
is not passed, rather than implying it applies unconditionally.

Signed-off-by: David Deal <ddeal@linuxfoundation.org>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8qMuq3je1uuU2JMLHuYBG
Copilot AI balanced review requested due to automatic review settings October 1, 2026 22:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The implementation matches the stated security behavior and includes focused regression coverage.

Review effort: Balanced
Findings: None

Resolved since last review (1)

@dealako dealako added the security An issue, task, feature, bug, or pull request related security or security audit. label Oct 1, 2026
@dealako dealako self-assigned this Oct 1, 2026
@emsearcy

Copy link
Copy Markdown
Contributor

Following up on this approach: I confirmed it effectively nullifies --audience on non-development logins. With this PR, lfx auth login --env production --audience <anything other than the compiled-in default> will still succeed and cache a token, but lfx api can never use it — apiDefaultBaseURL refuses it as a base URL (audience mismatch), and --hostname is independently blocked for non-development environments. So the only environment where overriding where lfx api sends requests is actually possible is development.

Given that (a) this isn't documented anywhere today — README.md doesn't mention --audience or --hostname customization at all — and (b) we don't have another supported audience/API (e.g. an LFX v1 endpoint) that this needs to accommodate, the cleanest fix is to stop pretending these are independently configurable at all:

  • Remove --audience from lfx auth login and --hostname from lfx api entirely.
  • Stop persisting audience in state.json/credstore.DeviceState. Store only environment (already stored).
  • Compute the audience everywhere it's needed (device-code audience param at login, lfx api's base URL, the lfx auth status display, lfx auth environments' "default audience" line) via defaultAudienceForEnvironment(env) from the compiled-in table — never from anything persisted.

This is more defensible as a security fix than comparing a stored value against the table: there's no longer an audience field in state.json to tamper with in the first place, and no --hostname escape hatch to reason about at all. It also simplifies apiDefaultBaseURL away (and the whole --hostname development gate in runAPI), since there's nothing left to validate against — the base URL is unconditionally the compiled-in default for the login's environment.

Can push this as a revision to this PR if that works, rather than opening a new one.

@emsearcy

Copy link
Copy Markdown
Contributor

Correction on my last comment: the doc gap isn't the README (which doesn't cover either flag), it's the in-CLI help. --hostname's Usage string already discloses the development-only restriction. --audience's does not — it just says it defaults to --env's audience, with no hint that a non-default value on production/staging becomes unusable by lfx api. That's the actual misleading bit.

Doesn't change the recommendation: removing --audience and --hostname entirely (and no longer persisting audience in state.json) is still cleaner than patching --audience's help text to disclose a footgun we don't actually need to support.

@emsearcy emsearcy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see above comments

dealako commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @emsearcy, agreed: removing --audience and --hostname and always deriving the audience from the environment's compiled-in default, instead of persisting it, is the cleaner fix. I'll push that revision to this PR, along with a merge from main to resolve the README conflict, so no need to push on your side. Since dropping the flags is user-facing, we'll plan a minor version bump for the release.


Generated by Claude Code

…uubawi

Resolve the README conflict by keeping both the device login URL note
from main and the lfx api default base URL note from this branch.

Signed-off-by: David Deal <ddeal@linuxfoundation.org>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8qMuq3je1uuU2JMLHuYBG
Copilot AI balanced review requested due to automatic review settings October 16, 2026 00:00

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No blocking issues were identified in the focused routing change, supporting tests, or documentation; tests were not executed.

0 open findings

🧠 Review effort: Balanced

@emsearcy

Copy link
Copy Markdown
Contributor

@dealako thanks—I see your merge commit, but not the commit removing --audience or --hostname. When you push it, please also be sure to update the PR description to reflect the new/effective direction.

…only

Per review feedback on this PR: the prior approach (validating a
persisted `--audience` against the environment's compiled-in default)
left `--audience` effectively dead outside `development`, since `lfx
api` could never use a non-default stored audience and `--hostname`
was independently gated to development logins.

Instead of validating, remove the ability to configure either value at
all:

- `lfx auth login` no longer accepts `--audience`; the audience sent to
  Auth0's device code endpoint is always the compiled-in default for
  `--env` (defaultAudienceForEnvironment).
- `lfx api` no longer accepts `--hostname`; its base URL is always the
  compiled-in default audience for the login's environment.
- `credstore.DeviceState` no longer persists `Audience`; nothing in
  state.json can influence which host receives a bearer token anymore.
- `lfx auth status`'s "Audience:" line is now computed from the stored
  Environment via defaultAudienceForEnvironment, not read back from
  state.json.
- Removed `apiDefaultBaseURL` and its now-obsolete tests (the
  audience-mismatch validation and tampered-audience end-to-end test),
  since there's nothing left to validate against.

Suggested release: minor (removes two user-facing flags).

Signed-off-by: David Deal <ddeal@linuxfoundation.org>
Copilot AI balanced review requested due to automatic review settings October 19, 2026 19:50
@dealako

dealako commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

Pushed 0b67546: removes --audience from lfx auth login and --hostname from lfx api, stops persisting Audience in state.json/credstore.DeviceState, and derives the audience everywhere (device-code request, lfx api's base URL, lfx auth status's display) from defaultAudienceForEnvironment(env). apiDefaultBaseURL and its tests are removed since there's nothing left to validate. PR description updated to reflect this as the current/effective direction. go build/vet/test/gofmt all pass; manually smoke-tested --help output, auth status audience display, and the lfx api refresh-failure path.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The changes consistently use environment defaults, preserve legacy-state decoding, and have no identified blocking issues.

No open issues 🎉

Review effort: Balanced

@emsearcy
emsearcy merged commit fbb2f54 into main Oct 20, 2026
9 checks passed
@emsearcy
emsearcy deleted the claude/autopatch-scan-29eb251e-vuln-4956724-uubawi branch October 20, 2026 17:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security An issue, task, feature, bug, or pull request related security or security audit.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants