Repository navigation
feat: platform-token auth for runs, run help text, nan --version fix (0.1.25) - #42
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Precedence: NAN_TOKEN > --token-file > session > saved platform token > saved API key. A token file readable or writable by others is refused. Refused credentials are named, never shown. nan me and nan metrics usage explain that they need a session when only a token is configured. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reads a platform token or API key from stdin (hidden on a terminal), checks it with GET /v1/runs?limit=1 and saves it 0600. Platform tokens go to platformToken, never apiKey, which the Setup tab writes into tools. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…okens nan --version and nan -v print "nan <version>" and exit 0 instead of the full-screen wordmark. The sign-in step of the dashboard says that a platform token only works for nan run and nan runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n --help nan runs --help and nan runs logs --help link the docs; logs lists the event types and the --json line format. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A saved platform token now goes before the session: a session expires on the server unseen, and ranked after it the token was never reached. - --api-token asks the terminal itself whether stdin is one, so </dev/null (cron, docker run without -i) says no token arrived. - The login output says what nan run will actually use, and warns when an sk- key replaces the one the Setup tab saved. - --token-file paths are sanitised in errors; a missing file says so. - NAN_TOKEN is one constant (session.TokenEnvVar); usingKey() removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Stat and read errors drop the raw path from *os.PathError too. Help and README say an sk- key saved with --api-token counts as a saved API key, and a refused saved token says the logout way back to the session. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Makes the CLI usable headless (CI, servers) with platform tokens, documents what a run does, and fixes
nan --version.1. Token auth for
nan run/nan runsPrecedence (first match wins), documented in
nan run --helpand the README:NAN_TOKEN: anan_pat_...platform token or ansk-...API key. Read only, never written to disk.--token-file PATH(onnan runand persistent onnan runs): first line of the file. On unix a regular file accessible to group/others (mode & 0o077) is refused withchmod 600advice (writable-by-others also matters: it would let another user swap in their token and receive your runs/prompts).nan auth login --api-token.nan auth login.The saved platform token ranks above the session (the brief listed session > stored apiKey, which still holds): a session expires on the server with nothing local knowing, so ranked after it a token saved for runs would never be reached on a machine that once signed in by email.
Tokens are shape-checked (
nan_pat_/sk-prefix, printable ASCII, <= 512 bytes) before being sent, so nothing can split a header. Errors name the credential's source ("the token in NAN_TOKEN", "the token in /path"), never its value. A refused token says where to make a new one.nan auth login --api-tokenreads the token from stdin only (hidden prompt when stdin is a real terminal perterm.IsTerminal, first line otherwise, so</dev/nullgives "no token arrived"), verifies it withGET /v1/runs?limit=1, and saves it through the existingsession.Save(temp file + 0600 + rename). Nothing is saved on any failure.Deviation from the brief, on purpose: a
nan_pat_token is saved in a newplatformTokenfield, not inapiKey. The Setup tab writesapiKeyinto every tool config it manages (OpenCode, Pi, Codex...), and the inference API rejects platform tokens, so storing a PAT there would break those tools.sk-keys still go toapiKey.nan meandnan metrics usagenow say "<cmd>needs a session: run nan auth login (platform tokens and API keys only work for nan run and nan runs)" when only a token is configured, instead of a bare 401. The dashboard's sign-in step shows the same notice when a platform token (saved orNAN_TOKEN) is present.--wsdefault resolution keeps usingGET /api/workspaces, which accepts tokens.2. Help text
nan run --help: sections for Git branch (auto /--worktree/--no-worktree,nan-run/<8 chars>, never pushes), Queue, portal label mapping, Authentication, docs link https://nan.builders/docs/runs. Flag descriptions for--worktree/--no-worktree/--cwdmatch.nan runs --help: one paragraph + docs link.nan runs logs --help: event types,--jsonprints one event per line, schema in the docs.nan auth login --help: explains--api-token.3.
nan --version/nan -vPrints
nan <version>and exits 0 (the framed full-screen wordmark read as the dashboard opening). The now-unusedtui.WelcomeStackedis removed.4. Docs
README: runs section (branch, queue, portal labels), new Authentication section with a GitHub Actions example using
NAN_TOKENfrom a secret. SECURITY.md: where a saved platform token lives.Tests
Spec-first, httptest mocks:
cmd/credentials_test.go: precedence matrix, shape validation (incl. CRLF/header injection), token file first line / errors / private-mode enforcement, bearer vs cookie on the wire, refused-token messages per source, end-to-endNAN_TOKENand--token-filethroughnan runs ls, NAN_TOKEN never written to disk, session-only commands explain tokens, no token value in any error.cmd/auth_test.go:--api-tokensaves verified PATs toplatformTokenandsk-toapiKeywith 0600, keeps the rest of the session, hidden read on a TTY, nothing saved on empty/malformed/401/5xx, flag combination refused.cmd/root_test.go:--versionand-vprintnan <version>and never open the TUI.cmd/help_test.go: required facts in help, docs links, no em-dashes,--token-fileon every runs command.internal/tui/session_test.go: sign-in notice with a platform token.go vet ./...andgo test ./...pass locally (macOS); CI is authoritative for Linux.Deploy notes
No env vars or migrations. Release is automatic on merge (v0.1.25).
🤖 Generated with Claude Code