Problem
`charter login --key ` validates the bearer against `sb_live_` / `sb_test_` prefixes only. Keys minted by edge-auth use the `ea_` prefix (edge-auth is the SoT for ecosystem auth; the `sb_` format is legacy from the pre-migration stackbilt-auth era).
As a result, `charter login --key ea_...` fails with:
Invalid API key format. Keys must start with `sb_live_` or `sb_test_`.
even though the resulting credentials file would be usable at runtime — the CLI's own `http-client` passes the bearer through to `/api/scaffold` without any prefix check, and the gateway accepts `ea_*` after `Stackbilt-dev/stackbilt-mcp-gateway#28` part 1 landed (commit `b63ac84`, 2026-04-11).
Evidence (2026-04-11)
Smoke-tested `charter run "smoke test..."` today using a freshly minted `ea_RqB-yrk8...` key. Couldn't use `charter login` to install it — had to write `~/.charter/credentials.json` directly, bypassing the login validator. CLI then ran the full architect → scaffold pipeline end-to-end against `mcp.stackbilt.dev` with no further issues.
Root cause
`packages/cli/src/commands/login.ts` line ~40:
```ts
if (!key.startsWith('sb_live_') && !key.startsWith('sb_test_')) {
throw new CLIError('Invalid API key format. Keys must start with sb_live_ or sb_test_.');
}
```
Same staleness bug as `stackbilt-mcp-gateway/src/auth.ts` isApiKey, one layer up.
Proposed fix
- Accept all three prefixes in `login.ts`:
```ts
const VALID_PREFIXES = ['ea_', 'sb_live_', 'sb_test_'];
if (!VALID_PREFIXES.some((p) => key.startsWith(p))) {
throw new CLIError(`Invalid API key format. Keys must start with one of: ${VALID_PREFIXES.join(', ')}.`);
}
```
- Update the help text / Usage line from `charter login --key sb_live_xxx` → `charter login --key <ea_|sb_live_|sb_test_>xxx`.
- Publish as v0.10.1 to npm.
Cross-reference
Problem
`charter login --key ` validates the bearer against `sb_live_` / `sb_test_` prefixes only. Keys minted by edge-auth use the `ea_` prefix (edge-auth is the SoT for ecosystem auth; the `sb_` format is legacy from the pre-migration stackbilt-auth era).
As a result, `charter login --key ea_...` fails with:
even though the resulting credentials file would be usable at runtime — the CLI's own `http-client` passes the bearer through to `/api/scaffold` without any prefix check, and the gateway accepts `ea_*` after `Stackbilt-dev/stackbilt-mcp-gateway#28` part 1 landed (commit `b63ac84`, 2026-04-11).
Evidence (2026-04-11)
Smoke-tested `charter run "smoke test..."` today using a freshly minted `ea_RqB-yrk8...` key. Couldn't use `charter login` to install it — had to write `~/.charter/credentials.json` directly, bypassing the login validator. CLI then ran the full architect → scaffold pipeline end-to-end against `mcp.stackbilt.dev` with no further issues.
Root cause
`packages/cli/src/commands/login.ts` line ~40:
```ts
if (!key.startsWith('sb_live_') && !key.startsWith('sb_test_')) {
throw new CLIError('Invalid API key format. Keys must start with sb_live_ or sb_test_.');
}
```
Same staleness bug as `stackbilt-mcp-gateway/src/auth.ts` isApiKey, one layer up.
Proposed fix
```ts
const VALID_PREFIXES = ['ea_', 'sb_live_', 'sb_test_'];
if (!VALID_PREFIXES.some((p) => key.startsWith(p))) {
throw new CLIError(`Invalid API key format. Keys must start with one of: ${VALID_PREFIXES.join(', ')}.`);
}
```
Cross-reference