Skip to content

Session commands ignore the api_url stored by dcd login and default to prod ("Invalid or expired JWT") #16

@riglar

Description

@riglar

Summary

dcd login records the environment you logged into (api_url, env) in the config store. But most commands default --api-url to the hard-coded prod URL (https://api.devicecloud.dev) and ignore the stored api_url. A user who logs into a non-prod env (e.g. dev) and then runs dcd list/status/cloud/artifacts/live without re-passing --api-url sends their dev Bearer token to the prod API and gets an auth failure.

Reproduction

$ dcd login --api-url https://api.dev.devicecloud.dev   # stores env=dev, api_url=dev
$ dcd whoami
   ...
   Env:  dev                                            # whoami reads config, correct

$ dcd list --limit 1
✗ Error: Failed to list uploads: Access denied. Invalid or expired JWT token
                                                        # defaulted to PROD, dev token rejected

dcd list --api-url https://api.dev.devicecloud.dev works fine.

Inconsistency

The codebase is split on this:

  • switch-org (src/commands/switch-org.ts) correctly falls back to the stored api_url, with an explicit comment: "Honor the env the user logged into — defaulting to prod here would send a dev Bearer token to the prod API."
  • whoami reads purely from config (correct).
  • cloud, list, status, artifacts, live read args['api-url'], which defaults to prod from apiFlags regardless of the logged-in env.

So the exact footgun switch-org guards against is live in every other session-aware command.

Impact

  • Affects anyone on a non-prod env (internal dev/staging, self-hosted), and any future multi-env usage.
  • The error ("Invalid or expired JWT") is misleading — the token is valid, it's just being sent to the wrong environment.

Suggested fix

When --api-url is not explicitly provided, fall back to config.api_url (as switch-org already does) before the prod default. The api-key auth path is unaffected since those users pass --api-key/env explicitly.

Found during a full feature sweep of v5.0.0 against the dev environment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions