Skip to content

feat(admin): add compute-auth-tag - #5935

Open
Chessing234 wants to merge 6 commits into
block:mainfrom
Chessing234:feat/admin-compute-auth-tag
Open

feat(admin): add compute-auth-tag#5935
Chessing234 wants to merge 6 commits into
block:mainfrom
Chessing234:feat/admin-compute-auth-tag

Conversation

@Chessing234

Copy link
Copy Markdown
Contributor

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-admin is already in that image and already owns the neighbouring step, so the command goes there. The buzz CLI would be the other candidate, but the published image does not ship it (Dockerfile:169-171).

buzz-admin compute-auth-tag --agent <npub|hex> [--conditions kind=9]

The owner secret comes from BUZZ_OWNER_PRIVATE_KEY, or from stdin with --owner-key -. A literal secret on --owner-key is refused rather than accepted: argv is readable by any process on the host through ps, and shell history keeps it. That is the one deliberate difference from the example, which takes the secret as argv[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 warnings clean, cargo fmt --all --check clean, 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 wherever generate-key does.

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>
@Chessing234
Chessing234 requested a review from a team as a code owner August 15, 2026 08:03

@themiguelamador themiguelamador left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 valid kind=9&created_at<... example, explicitly tells shell users to quote compound conditions, and says stdout is ready for BUZZ_AUTH_TAG. (Multiple kind= 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_tag directly, 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 real Cli::try_parse_from assertion covering --owner-key - and compound conditions.

Verification completed on the fix commit:

  • cargo test -p buzz-admin --bin buzz-admin — 7 passed
  • cargo clippy -p buzz-admin --all-targets -- -D warnings
  • cargo fmt --all -- --check
  • git diff --check
  • Generated compute-auth-tag --help inspected
  • 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.
@Chessing234

Copy link
Copy Markdown
Contributor Author

Thanks — both gaps fixed, in 8250ffa and 9b51f67. Complear/buzz 404s for me, so 4519887cb was unreachable; written from your description.

Help. Confirmed the comma form is rejected, and the error is worth quoting because it shows why the old example was misleading:

$ … compute-auth-tag --agent <npub> --conditions 'kind=0,kind=9' --owner-key -
error: invalid input: kind value has leading zero: "0,kind=9"
exit 5

validate_conditions splits on &, so 0,kind=9 is read as a single kind value and the complaint is about the value, not the comma — an operator following the old help would have been sent looking in the wrong place. Help now shows 'kind=9&created_at<1713957000', says to quote the value in a shell, notes the clauses are conjunctive (so repeating kind= is unsatisfiable), and says stdout is ready for BUZZ_AUTH_TAG.

Tests. The command's own path from raw secret to tag — --agent parsing, the trim, Keys::parse, the SDK call — is now auth_tag_from_secret, and the round-trip tests drive that instead of buzz_sdk::nip_oa::compute_auth_tag. Added: an nsec secret arriving with a trailing newline (what piped input actually looks like) paired with an npub agent, and the comma-conditions rejection. Clap is asserted directly 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 OwnerKeySource::Env.

Verified on the pushed head: cargo test -p buzz-admin --bin buzz-admin 10 passed (was 5), cargo clippy -p buzz-admin --all-targets -- -D warnings clean, cargo fmt --all -- --check, git diff --check, the generated --help read back, and a real end-to-end run — a generated secret piped on stdin emitted ["auth", <owner pubkey>, "kind=9&created_at<1713957000", <sig>] and exited 0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add some official cli command for compute_auth_tag

2 participants