Repository navigation
fix(rest): serve API docs with ReDoc so zip leaves the tree - #440
Conversation
utoipa-swagger-ui (every release to 10.0.1) builds against zip ^8.6, and RUSTSEC-2026-0367/0368/0369 are fixed only in zip >= 9. No patched 8.x exists, so #439 had to ignore all three in .cargo/audit.toml. Serve the OpenAPI spec at /api-docs/openapi.json as before and render it with utoipa-redoc at /redoc. zip, flate2 and seven other build-only crates drop out of Cargo.lock, and the audit ignores are deleted: cargo audit is clean with no exemptions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019a95kk88TZ1iegsBK3kox3
|
Red checks on this PR that are not this PR's, and what happened to each:
The CodeRabbit status ("Review state could not be read") is a problem on the bot's side. Generated by Claude Code |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📜 Recent review details
📝 Summary
Merge Risk: ⚪ Minimal · up to
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 72103e4990
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "/api-docs/openapi.json", | ||
| get(|| async { axum::Json(ApiDoc::openapi()) }), | ||
| ) | ||
| .merge(Redoc::with_url("/redoc", ApiDoc::openapi())) |
There was a problem hiding this comment.
Serve the ReDoc renderer locally
Redoc::with_url uses utoipa-redoc's default HTML template, which loads redoc.standalone.js from the mutable https://cdn.redoc.ly/redoc/latest/... URL. Consequently, /redoc remains blank whenever the browser cannot access the public CDN—such as in an air-gapped or outbound-filtered deployment—even though the API and embedded specification are available locally; the previous Swagger UI served its build-time-bundled assets from this process. Please use a custom template backed by a locally served, pinned ReDoc bundle so the documented endpoint remains self-contained.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Confirmed, and real: utoipa-redoc 7.0's default template (res/redoc.html in the crate) is
<script src="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"></script>so /redoc is a page we serve that executes whatever latest resolves to at request time, with no integrity attribute. The previous Swagger UI embedded its assets at build time, so this PR moved the dependency from build time to run time. Two consequences: the page is blank on an air-gapped or egress-filtered deployment, and the bundle is a mutable third-party script on a page served from our origin.
The fix I propose, in a follow-up on this stack rather than here (this PR's point is dropping the vendored zip):
Redoc::with_url(...).custom_html(...)with the same template but the version pinned (/redoc/v2.x.y/bundles/...) and anintegrity="sha384-…"attribute, computed from the bundle bytes. That keeps the tree free of the bundle and makes the dependency immutable.- Optionally an
ECHIDNA_REDOC_BUNDLEpath so an operator can serve a local copy instead of the CDN; the ENV-VARS doc gets the entry.
I cannot compute the SRI hash from this session (the CDN is not reachable through its egress policy), so I am not pushing a half-pin. @hyperpolymath: say whether you want (1) alone or (1)+(2), and I will open it against this branch's merge.
Generated by Claude Code
|
✅ Coding Agent task started: View task and status The task will inspect the CI failures, validate its fix, and commit the fix to this branch automatically.
⏭️ Checks skipped: 2 · already failing on `main` (not caused by this PR)
|
|
Add Carrot credits or activate Agent usage billing to use Autofix |
|
🤖 Completed: Generate docstrings for PR #440 — View commit |
#440 carries the same exclude (its CI-fix commit 78a70c2) and merges first; byte-identical text here means the two land without a conflict. It can go once the governance pin reaches hyperpolymath/standards#1299, which makes that crate its own workspace root. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019a95kk88TZ1iegsBK3kox3
… (#442) ## Summary [#441](#441) merged the scratch branch `claude/new-session-th4e9w-lockregen` into `main`. That branch existed only to run `.github/workflows/zz-one-off-lock-regen.yml`. That job clones hyperpolymath/panic-attack, regenerates that repository's `actions.lock` with a real token, and prints the result to the job log. The workflow triggers only on pushes to the scratch branch, so on `main` it is dead weight, and its own header says "scratch branch only, deleted after use". ## Changes - Delete `.github/workflows/zz-one-off-lock-regen.yml`. It has no `uses:` steps, so `actions.lock` needs no change. This branch also used to carry the `Cargo.toml` workspace exclude for `.standards-js/tools/js-runtimes`. [#440](#440) landed the same exclude on `main`. After the merge of `main` into this branch, the diff against `main` is the one deletion above. ## RSR Quality Checklist ### Required - [x] Tests pass (`just test` or equivalent): no code changed. - [x] Code is formatted: no code changed. - [x] Linter is clean: a workflow file is removed, none added. - [x] No banned language patterns. - [x] No `unsafe` blocks without `// SAFETY:` comments. - [x] No banned functions. - [x] SPDX license headers present on all new/modified source files: none added. - [x] No secrets, credentials, or `.env` files included. ### As Applicable - [ ] Repo deed, roadmap, docs, TOPOLOGY, CHANGELOG, dependencies, ABI/FFI: not applicable. ## Testing - `git diff --stat origin/main...HEAD` shows one file, 55 deletions. - `grep -c zz-one-off .github/workflows/actions.lock` is 0 on `main` and on this branch, so the lock gate sees no change. ## Screenshots None. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_019a95kk88TZ1iegsBK3kox3 --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Summary
This fixes the zip advisories at their source instead of ignoring them. CodeRabbit's autofix in #439 added
.cargo/audit.toml, which ignores RUSTSEC-2026-0367, 0368 and 0369 inzip. Those advisories are patched only inzip >= 9.0.0, and no fixed 8.x release exists. Everyutoipa-swagger-uirelease up to 10.0.1 build-depends onzip ^8.6, so a version bump cannot fix it. This PR swaps Swagger UI forutoipa-redoc7.0 (sameutoipa ^6,axum ^0.8), which bundles no archive. The owner chose this option.Changes
src/interfaces/rest: the raw spec is still served at/api-docs/openapi.json, now by an explicit route. ReDoc renders it at/redoc, which replaces/swagger-ui.Cargo.lock:zip,flate2,zopfli,zlib-rs,miniz_oxide,crc32fast,adler2,simd-adler32,typed-path,mime_guessandutoipa-swagger-uiare removed, andutoipa-redocis added..cargo/audit.tomlis deleted, so no advisory ignores remain.README.adocandsrc/interfaces/README.adocnow name the new docs URL.The Julia
Project.tomlUUID change from the same autofix was checked and kept. It is a correct ADR-008 profile C UUIDv8,SHA-256("julia-package:hyperpolymath/echidna")with the version and variant bits set, and nothing referenced the old v4 ID.RSR Quality Checklist
Required
cargo check/clippy -D warningsonechidna-restpass. The crate has no tests of the docs route.cargo fmt --check)unsafeblocks addedAs Applicable
/swagger-ui→/redoc)utoipa-redocis MIT/Apache-2.0, from the same project asutoipa.cargo audit: clean, exit 0, with no ignores.Generated by Claude Code