Repository navigation
feat(keys): drop the impossible key picker, name device keys, add keys audit - #232
Conversation
The CLI's sk-ar key cannot reveal another key (reveal is session-only, prod returns 401), so keys use, the launcher key… item and the config Switch key never worked. Remove them; local account switching stays. Device login now names its key <host> anyr <date>. A re-login offers to revoke this machine's previous device key after a yes, and prints the command in scripted runs. New: keys audit and keys revoke <last4|id>. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Duyet Le <me@duyet.net> Co-authored-by: duyetbot <bot@duyet.net>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Duyet Le <me@duyet.net> Co-authored-by: duyetbot <bot@duyet.net>
|
Dashboard half: duyet/anyrouter#6665 (Unused keys notice, same rules and fixed-date cases). |
anyr size and startupStartup is wall time for a cold Size budget:
Budget check: ok raw timings[
{
"asset": "anyr-darwin-arm64",
"kind": "native",
"path": "/Users/runner/work/cli/cli/anyr-darwin-arm64",
"bytes": 2537224,
"size": "2.4 MiB",
"version": "0.1.34 (built 2026-10-27 17:19:43)",
"target": "aarch64-apple-darwin",
"os": "macos-latest",
"startup_version": {
"n": 21,
"min_ms": 4.2,
"median_ms": 5.66,
"p95_ms": 8.46,
"mean_ms": 6.05
},
"startup_help": {
"n": 21,
"min_ms": 3.68,
"median_ms": 7.0,
"p95_ms": 11.86,
"mean_ms": 6.91
}
},
{
"asset": "anyr-darwin-x86_64",
"kind": "native",
"path": "/Users/runner/work/cli/cli/anyr-darwin-x86_64",
"bytes": 3037616,
"size": "2.9 MiB",
"version": "0.1.34 (built 2026-10-27 17:20:31)",
"target": "x86_64-apple-darwin",
"os": "macos-latest",
"startup_version": {
"n": 21,
"min_ms": 39.6,
"median_ms": 55.93,
"p95_ms": 107.69,
"mean_ms": 59.87
},
"startup_help": {
"n": 21,
"min_ms": 40.59,
"median_ms": 54.52,
"p95_ms": 68.0,
"mean_ms": 55.63
}
},
{
"asset": "anyr-linux-arm64",
"kind": "native",
"path": "/home/runner/work/cli/cli/anyr-linux-arm64",
"bytes": 3020040,
"size": "2.9 MiB",
"version": "0.1.34 (built 2026-10-27 17:19:23)",
"target": "aarch64-unknown-linux-gnu",
"os": "ubuntu-24.04-arm",
"startup_version": {
"n": 21,
"min_ms": 0.81,
"median_ms": 0.89,
"p95_ms": 1.0,
"mean_ms": 0.89
},
"startup_help": {
"n": 21,
"min_ms": 0.86,
"median_ms": 0.96,
"p95_ms": 1.04,
"mean_ms": 0.96
}
},
{
"asset": "anyr-linux-x86_64",
"kind": "native",
"path": "/home/runner/work/cli/cli/anyr-linux-x86_64",
"bytes": 3516632,
"size": "3.4 MiB",
"version": "0.1.34 (built 2026-10-27 17:19:21)",
"target": "x86_64-unknown-linux-gnu",
"os": "ubuntu-latest",
"startup_version": {
"n": 21,
"min_ms": 0.63,
"median_ms": 0.66,
"p95_ms": 0.69,
"mean_ms": 0.66
},
"startup_help": {
"n": 21,
"min_ms": 0.61,
"median_ms": 0.64,
"p95_ms": 0.9,
"mean_ms": 0.68
}
},
{
"asset": "anyr-windows-x86_64.exe",
"kind": "native",
"path": "D:\\a\\cli\\cli\\anyr-windows-x86_64.exe",
"bytes": 2991616,
"size": "2.9 MiB",
"version": "0.1.34 (built 2026-10-27T17:20:25Z)",
"target": "x86_64-pc-windows-msvc",
"os": "windows-latest",
"startup_version": {
"n": 21,
"min_ms": 8.55,
"median_ms": 8.77,
"p95_ms": 9.42,
"mean_ms": 8.86
},
"startup_help": {
"n": 21,
"min_ms": 8.67,
"median_ms": 8.94,
"p95_ms": 9.63,
"mean_ms": 9.04
}
},
{
"asset": "anyr.wasm",
"kind": "wasm",
"path": "/home/runner/work/cli/cli/target/wasm-pkg/anyr_cli_bg.wasm",
"bytes": 257891,
"size": "251.8 KiB",
"version": "wasm",
"target": "wasm32-unknown-unknown",
"os": ""
}
] |
|
APPROVE. Reviewed head 976922c. Revoke is never silent: the re-login prompt uses term::confirm, which ignores --yes; non-interactive runs only print the revoke command; the new key is never offered. keys audit never lists the key in use. Output shows last 4 only. Rust tests (keys_audit 4, key_audit unit 11) pass; prod run of keys audit with the smoke key returned no suggestions and printed no secret. Plain top-left output. |
Why
The owner asked whether device login can ever pick an old key. From the CLI it can't:
POST /api/v1/keys/:hash/revealusesrequireAuth, which accepts only a session or anak_key. Every CLI login stores ansk-ar-key. A prod probe with the smoke key returned 401 on both of its keys.token.post.tsbinds"", "", ""), so nobody can reveal them, not even from a session.So
keys use, the launcher'skey…item, the config TUI's "Switch key" /api keyrow, and the silentresolve_latest_keycall at login never worked: they always failed or did nothing. (The browser consent page can still hand over an existing dashboard key. That is server-side and is unchanged.)What changes
Removed:
keys use(it now prints how to get a key),bind_agent_key/switch_agent_key, both launcherkey…entries,ConfigureKind::Key, the legacy config "Switch key" item (menu arms re-mapped),resolve_latest_key,reveal_key,save_agent_key,RemoteKey.can_reveal.Kept: local profile switching, which works:
auth switch,account use,config use, per-agentaccount…. The config TUIapi keyrows stay visible; pressing Enter on one prints the login /--key -hint. A per-agentapi_keyalready in config is still read.Device login names the key
<host> anyr <YYYY-MM-DD>(key_label, which the server already accepts, capped at 60 chars). The host comes fromgethostname, with env as the fallback.Re-login revoke offer. After a browser or device login, if this profile's previous key is still on the server, has a
cli*origin and differs from the new key, the CLI asksRevoke the previous key from this device, "<name>" (…abcd)? [y/N]and revokes only on yes.--yesdoes not answer this prompt. Scripted runs revoke nothing and printRevoke it: anyr keys revoke abcd.anyr keys audit [--json]lists suggested removals with the reason for each:It never suggests the key this machine uses, and never a key with requests in the last 30 days. It only suggests and never deletes. The same rules, with the same fixed-date cases, are in duyet/anyrouter
apps/dashboard/src/app/keys/-components/key-audit.ts.anyr keys revoke <last4|id|hash>: the existing confirm stays, and the prompt warns when you are revoking the key this machine uses.Output shows only the last 4 characters of a key. Printed hints no longer leak the internal
usagemarker.Verification
cargo fmt --check,cargo clippy --locked --all-targets -- -D warnings, andcargo test --locked --all-targetspass (1012 tests) after rebasing on 0.1.34.src/cmd/key_audit.rs(rules with fixed dates, current key never suggested, revoke only after yes, no revoke and only a hint when non-interactive),src/civil.rs,auth::device_start_names_the_key_after_the_device, andtests/keys_audit.rs. The last one runs against a mock server: device login sendskey_label, re-login sends no DELETE and prints the hint,keys auditskips the current key,keys useis gone, andkeys revoke <last4>deletes that hash.login --key -,keys list,keys audit("No unused keys. Checked 2 keys."),keys audit --json,keys use(exit 2 with the hint),keys revoke zzzz(exit 3, not found), andauth status. Nothing was revoked. Device login itself can't be approved unattended, so the label and the revoke offer are covered only by the mocked tests.Platform side: the dashboard "Unused keys" notice is in duyet/anyrouter (linked in a comment).
🤖 Generated with Claude Code