feat(admin): add compute-auth-tag - #5935
Conversation
Starting an agent on a machine Buzz Desktop cannot reach needs a NIP-OA auth tag, and the only way to produce one was `cargo run --example compute_auth_tag` — a source checkout and a release build, for a value the operator otherwise gets from a throwaway container (`buzz-admin generate-key`). buzz-admin already ships in the image, so put it next to the rest of that bootstrap. The owner secret comes from BUZZ_OWNER_PRIVATE_KEY or stdin. A literal value on `--owner-key` is refused rather than accepted: argv is readable by any process on the host and shell history keeps it. Signed-off-by: Taksh <takshkothari09@gmail.com>
The refusal of a literal `--owner-key` is the security-relevant case, so it is asserted rather than left to review. The round-trip tests pin the tag to the agent it names — a tag that verified for any key would authorize any agent. Signed-off-by: Taksh <takshkothari09@gmail.com>
The example is the path the issue reporter had to take. Say where the supported one is, and why it is preferable — the example takes the owner secret on argv. Signed-off-by: Taksh <takshkothari09@gmail.com>
Cargo.lock entry for the dependency added with compute-auth-tag. Signed-off-by: Taksh <takshkothari09@gmail.com>
themiguelamador
left a comment
There was a problem hiding this comment.
The command's cryptographic implementation correctly delegates to the SDK primitive the relay verifies, and --owner-key - works through Clap. I found two user-facing/test gaps and fixed them in 4519887cb (review/pr-5935-fix):
- The generated help advertised
kind=0,kind=9, but NIP-OA clauses are joined with&; the comma form is rejected as an unsupported clause. The help now uses a validkind=9&created_at<...example, explicitly tells shell users to quote compound conditions, and says stdout is ready forBUZZ_AUTH_TAG. (Multiplekind=clauses would also be conjunctive and therefore unsatisfiable, so the replacement uses a kind plus time bound.) - The original “emitted tag” tests called
buzz_sdk::compute_auth_tagdirectly, bypassing the new command's owner-secret parsing, while the stdin test exercised only an internal source enum. The fix extracts the command's actual secret-to-tag path for round-trip tests and adds a realCli::try_parse_fromassertion covering--owner-key -and compound conditions.
Verification completed on the fix commit:
cargo test -p buzz-admin --bin buzz-admin— 7 passedcargo clippy -p buzz-admin --all-targets -- -D warningscargo fmt --all -- --checkgit diff --check- Generated
compute-auth-tag --helpinspected - End-to-end stdin invocation with the public NIP-OA test vector emitted a valid JSON tag with the expected owner pubkey and conditions
Please incorporate the fix commit (or an equivalent change) before merge.
The review points out the help advertised `kind=0,kind=9`, but NIP-OA joins clauses with `&` — `validate_conditions` splits on it, so the comma form is read as one kind value and rejected (`kind value has leading zero: "0,kind=9"`). Two kind clauses would also be conjunctive and therefore unsatisfiable, so the replacement pairs a kind with a time bound. The help now shows `'kind=9&created_at<1713957000'`, says to quote the value in a shell, and says stdout carries the tag ready for BUZZ_AUTH_TAG.
The review points out the round-trip tests called buzz_sdk::nip_oa::compute_auth_tag directly, bypassing everything the command adds, and the stdin coverage stopped at an internal enum. The command's path from a raw secret to a tag — --agent parsing, the trim, Keys::parse, the SDK call — is now auth_tag_from_secret, and the round-trip tests drive that. New cases cover an nsec secret arriving with a trailing newline (as piped input does) with an npub agent, and the comma-separated conditions string being rejected. Clap itself is now asserted too, via Cli::try_parse_from: `--owner-key -` survives as the value `-` rather than being taken for a flag, `&` survives in --conditions as one argument, and the no-flag default resolves to the environment source.
|
Thanks — both gaps fixed, in 8250ffa and 9b51f67. Help. Confirmed the comma form is rejected, and the error is worth quoting because it shows why the old example was misleading:
Tests. The command's own path from raw secret to tag — Verified on the pushed head: |
Fixes #5426.
Starting an agent on a machine Buzz Desktop cannot reach needs a NIP-OA auth tag, and the only way to produce one was
cargo run --release --example compute_auth_tag— a source checkout and a release build, for a value the operator otherwise obtains from a throwaway container (docker run --rm --entrypoint /usr/local/bin/buzz-admin ghcr.io/block/buzz:main generate-key).buzz-adminis already in that image and already owns the neighbouring step, so the command goes there. ThebuzzCLI would be the other candidate, but the published image does not ship it (Dockerfile:169-171).The owner secret comes from
BUZZ_OWNER_PRIVATE_KEY, or from stdin with--owner-key -. A literal secret on--owner-keyis refused rather than accepted: argv is readable by any process on the host throughps, and shell history keeps it. That is the one deliberate difference from the example, which takes the secret asargv[1]; the example's doc comment now points here and says why.Verified locally with CI's own gates:
cargo clippy --workspace --all-targets -- -D warningsclean,cargo fmt --all --checkclean,cargo test -p buzz-admin --bin buzz-admin(6 passed, 5 new — key-source precedence, the refusal, and a compute→verify round trip that also asserts the tag does not verify for a different agent). Not run: the command inside the published image — it needs no database, so it runs wherevergenerate-keydoes.