Skip to content

docs: document the audit stream, generated assets and TLS trade-off - #66

Merged
plusky merged 2 commits into
plusky:mainfrom
mimi1vx:docu_refresh
Aug 7, 2026
Merged

docs: document the audit stream, generated assets and TLS trade-off#66
plusky merged 2 commits into
plusky:mainfrom
mimi1vx:docu_refresh

Conversation

@mimi1vx

@mimi1vx mimi1vx commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

What

Two documentation commits that bring README.md and docs/DESIGN.md up to
what the server actually does. No code changes; no behavior changes.

docs: record the TLS trust store trade-off and its operator cost — PR #64
moved bugwarden-core to reqwest 0.13, swapping the bundled Mozilla
webpki-roots anchors for the OS trust store via rustls-platform-verifier.
The DESIGN.md paragraph stated only the upside. It now also names the failure
mode (no OS trust store means no HTTPS, where the previous release worked from
bundled roots, and the TLS handshake error does not name the missing CA
bundle), the operator's fix (install ca-certificates or mount the host
bundle), and the bundled-roots alternative as considered and rejected — a
distro-packaged tool has to follow the system CA bundle, and bundled roots
cannot see the internal CA the target deployments sit behind.

docs(readme): document the audit stream, generated assets and MCP surface
— three parts of the server had no user-facing documentation at all:

  • Audit stream. The operator's only view of what the guard decided had no
    README section. Added: the configuration reference (path, fsync,
    fail_mode, rotate_max_bytes, rotate_keep, suppressed_ids), fail-mode
    semantics, the three record kinds, the guard field table, trace-id
    correlation, and the parameter allowlist that keeps bug content out of
    records.
  • Man page and shell completions. Every release tarball ships
    man/bugwarden.1 and bash/zsh/fish completions, and nothing said so or
    documented the gen-gated bugwarden-gen generator behind them.
  • MCP protocol revisions. The four revisions served, the pinned default,
    the mandatory initialize handshake, and tools-only capabilities.

Gaps filled in place: RUST_LOG and exit status in the CLI reference,
per-flag empty-value semantics, MCP_READ_ONLY's strict true/false, the
User-Agent sent to Bugzilla, the 25-id assessment cap and per-tool
defaults/limits in the tool reference, and the 4 MiB transport body ceiling
that bounds an upload even when max_attachment_bytes = 0.

Why

An operator containerizing a release tarball hits the trust-store dependency
at runtime with nothing pointing at the cause, and an operator wiring up
auditing had to read examples/audit.toml and the source to learn the record
schema. Both are provisioning facts that belong where someone installing the
server will look.

Invariants

No guard behavior changes. The new text documents, without altering,
I1 (policy unreadable through MCP — mcp_server_info exposes only coarse
facts, never rule names or match criteria), I3 (dropped result counts
never reach the client; the counts live in the audit stream instead),
I13 (write tools removed from the listing, not made to error), and
I15 (the audit stream reaches only the operator's file, never an MCP
surface or stderr, and tool responses are byte-identical with auditing off,
on, or failing open).

Verification

  • cargo fmt --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo clippy -p bugwarden --features gen --all-targets -- -D warnings
  • typos — clean, with no new typos.toml entry
  • The sample audit record in the README parses as JSON, and its key order
    matches the BTreeMap serialization the code produces.

The README text was reconciled against the code rather than against the
previous README, then reviewed adversarially against the source. That review
caught five factual errors in my own draft, all fixed before this PR; two of
them are worth flagging because the source comments are also wrong — see
the review note below.

Two things found while reconciling

Neither is addressed here (this PR is documentation only), but both look like
real defects:

  1. audit.rs:477-478 rustdoc is wrong about guard.rule. It says the
    field is "absent when the default action decided", but policy.rs:832
    writes the literal "default". The field is actually absent on searches,
    refusals and the pre-dispatch gate. The README documents the real
    behavior, including the synthetic rule names (default,
    min_bug_age_days, <rule>:unreadable-metadata, unavailable).
  2. suppressed_count is max(ids.len(), suppressed_extra)
    (audit.rs:1232) — a maximum of two unrelated tallies, and it counts
    private comments and attachment metadata as well as bugs. A
    summarize_bug call that dropped 3 private comments while hiding 2
    duplicate-marker bug ids records suppressed_count: 3 next to a
    two-element suppressed_ids. The README describes this accurately, but
    the semantics may be a bug rather than a documentation problem.

Closes #65.

mimi1vx added 2 commits August 7, 2026 16:22
PR plusky#64 moved bugwarden-core to reqwest 0.13, switching Bugzilla's
certificate validation from bundled webpki-roots to the OS trust store
via rustls-platform-verifier. DESIGN.md documented the upside only; an
operator building a scratch/distroless image got a TLS handshake error
with nothing pointing at the missing CA bundle, and the C-toolchain
build requirement and proxy behavior were undocumented for README
readers.

Extend the DESIGN.md TLS paragraph with the failure mode, the
operator's fix (install ca-certificates or mount the host bundle), and
the bundled-roots alternative considered and rejected. Add a README
'TLS trust anchors and proxies' subsection under Installation with the
same facts in current-state framing plus a copy-pasteable Containerfile
snippet, and note the aws-lc-sys C-toolchain requirement in the
From-source section.

Closes plusky#65.
…face

The README described the guard and the tool surface but not several
operator-facing parts of the server: the audit stream had no section at
all despite being the operator's only view of what the guard decided,
the man page and shell completions shipped in every release tarball
were undocumented, and nothing said which MCP protocol revisions a
deployment speaks or that the initialize handshake is mandatory.

Add an Audit stream section (configuration keys, fail modes and what
they do and do not guarantee, record kinds, the guard fields, and the
allowlist that keeps bug content out of records), a Man page and shell
completions section covering the assets and the gen-gated generator
that produces them, and an MCP protocol revisions section. Fill the
remaining gaps in place: RUST_LOG and exit status in the CLI
reference, the User-Agent sent to Bugzilla, the 25-id assessment cap
and the per-tool defaults and limits in the tool reference, and the
transport body ceiling that bounds an upload even when
max_attachment_bytes does not.

No behavior change; the text was reconciled against the code rather
than against the previous README.
@plusky
plusky merged commit fa05e38 into plusky:main Aug 7, 2026
11 checks passed
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.

DESIGN.md's TLS note records the upside of the OS trust store, not the trade

2 participants