Uh oh!
There was an error while loading. Please reload this page.
Add hyp remote mint for CI enrollment tokens - #969
Conversation
…I reference
Two review findings on `hyp remote mint`:
- `--expires-days` was declared `{ type: 'string' }` and then re-validated by
hand in `runRemoteMint` with `Number()` + `Number.isInteger`, duplicating the
coercion the arg codec already does for `integer` + `minimum`. LLP 0293 makes
the schema entry the whole surface of a command, so the bound and the 365-day
default now live there. Side effect: a bad value is refused at the gate and
prints the usage line, like every other argument error.
- `docs/CLI_REFERENCE.md` enumerates every other `hyp remote *` subcommand and
had no entry for the new one. Added it, with the LLP 0298 D4 CI recipe.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>Review of |
…1 names both causes Two more review findings on `hyp remote mint`: - The printed recipe pasted the registered target URL into `hyp join`. A target may legitimately be registered as `<base>/v1/mcp` (LLP 0084 D2, and the shape docs/CLI_REFERENCE.md shows for `hyp remote add`), and `hyp join` stores its url argument verbatim as the central sink url, which central's IdentityClient then resolves `/v1/identity/bootstrap` against. Such a user would see minting succeed locally (deriveIdentityBase already reduces to the origin) and then every CI run 404 on bootstrap. The recipe now prints the origin. - A 401 that survived the one-shot refresh reported only "session expired". This server answers 401, not 403, to a live session lacking a scope (LLP 0155 #write-401), so the 403 branch never fires for that case and a user who is not permitted to mint gets sent round the re-login loop forever. A refreshable session's surviving 401 now names both causes, as report writes already do. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…stops putting the CI secret in argv Three findings from the round-2 review of b4c9f52. The printed expiry read `expires_at` only when it was a string, but the identity plane sends a Unix epoch-second (`/mint` is the sibling of `/token`), so a real server's expiry was dropped from a token that is shown exactly once. It now reuses `expiryTimestamp`, which is exported for that, and an unreadable value drops the detail rather than the token. The printed recipe passed a 365-day, non-rotating, fleet-shared secret to `hyp join` as an argv positional, which `hyp join`'s own help and docs/CLI_REFERENCE.md both warn against: on a runner that is `ps` and any `set -x` trace. It now pipes the token on stdin, the path `runJoin` already reads on a non-TTY. The token also shared stdout with six lines of narration, so `TOKEN=$(hyp remote mint)` captured the banner too; re-minting after that fails creates a second gateway row (LLP 0298 D2). stdout is now the token alone and every advisory line moved to stderr, as the first-sync consent block in the same file already does. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
philcunliffe
commented
Aug 20, 2026
Review round 2 of |
philcunliffe
commented
Aug 20, 2026
Triage at head Verified at the current head before deciding:
All three are enumerated with evidence in #972. |
Uh oh!
There was an error while loading. Please reload this page.
Adds
hyp remote mint [name] [--label <label>] [--expires-days <n>]: mints a long-lived CI enrollment token from the user's logged-in OIDC session and prints it once, for storing in CI secrets. Design is LLP 0298 (in this PR): CI runs enroll with the existinghyp joinpath and all share one gateway; each run exchanges the token for its own short-lived JWT, so the shared secret never rotates.The CI recipe is existing commands only:
hyp join <url> <token> --no-daemon,hyp daemon run --foreground &, andhyp sync --yesas the teardown flush.Server prerequisite (hypaware-server):
POST /v1/identity/mintand accepting the minted token on bootstrap against an existing gateway with multiple concurrent JWTs. Until that ships, the command reports HTTP 404 with a clear message.Deferred, filed as #968: capturing the CI run id into rows for per-run attribution.
Tests: 9 new tests in test/core/remote-mint-command.test.js;
npm testotherwise green except the pre-existing top-level-help pin failure in command-dispatch.test.js (fails on master too); typecheck clean.