4.3 KiB
Toolbox Portal requirements
av-tools is built and packaged independently. Toolbox Portal consumes the exact ZIP and SHA-256 from a reviewed release lock; it must never import the app source into its React build.
Required serving behavior
All app, wrapper, core, WASM and worker responses are same-origin and served over HTTPS (or trusted localhost). Apply:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-origin
X-Content-Type-Options: nosniff
Serve .wasm as application/wasm, JavaScript modules as a JavaScript MIME
type and JSON as application/json. Test real responses under
/apps/av/vendor/ffmpeg/0.12.10/...; a file-extension allowlist alone does not
prove the MIME type.
Suggested CSP:
default-src 'self';
script-src 'self' 'wasm-unsafe-eval';
worker-src 'self' blob:;
connect-src 'self';
img-src 'self' blob: data:;
media-src 'self' blob:;
font-src 'self';
style-src 'self';
object-src 'none';
frame-src 'none';
frame-ancestors 'none';
base-uri 'none';
form-action 'none';
'wasm-unsafe-eval' is the narrow WebAssembly permission; broad
'unsafe-eval' is unnecessary. worker-src blob: covers the wrapper-created
worker path. media-src blob: permits local source/result previews.
Immutable reference and active-worktree state
Portal revision bda9da044d61c109afd9969d357cc27f76648938 already sends COOP
same-origin, COEP require-corp, CORP same-origin, script-src 'self' 'wasm-unsafe-eval', and worker-src 'self' blob:. Its packaged nginx CSP does
not declare media-src; default-src 'self' therefore blocks local
blob: audio/video URLs. The expected browser diagnostic is equivalent to:
Refused to load media from 'blob:…' because it violates
"default-src 'self'".
Smallest required Portal change: append exactly
media-src 'self' blob:; to that CSP. This permits only same-origin and
in-memory Blob media; it does not permit remote media hosts, inline script or
eval. If the Portal is not changed, conversion/download can remain available
but Blob source/result preview must show a clear disabled reason.
As inspected on 2026-07-24, the active
/mnt/DATA/git/toolbox-portal/deploy/nginx.conf contains that exact directive
as a local worktree patch. The worktree still resolves to the immutable
revision above, so the patch is useful for local deployment testing but is not
a committed Portal revision and must not be cited as published release
evidence. The clean-reference assembly smoke therefore continues to require
--allow-known-header-gap until a reviewed Portal commit contains the fix.
The nginx profile includes .wasm in its static allowlist/gzip types but
relies on the base image mime.types. Verify Content-Type: application/wasm against the pinned image; add an explicit mapping if the
response differs.
Caching
The immutable Portal reference's cache map makes Vite content-hashed assets
immutable but leaves versioned FFmpeg cores at no-cache. Correctness is
unaffected.
For performance, the exact directory
apps/av/vendor/ffmpeg/0.12.10/{st,mt}/ may receive:
Cache-Control: public, max-age=31536000, immutable
Only do this while a version path is immutable and verified against
version.json. Keep index.html, manifest/catalog/release JSON and legal
notices revalidated.
Nested path and context
The artifact uses base: './', entry: './', a relative icon, a relative
manifest URL and relative core URLs. Portal may therefore target av, yielding
apps/av/. Do not rewrite files to root-absolute /assets or /vendor.
Use top-level navigation; embedding is unsupported.
The app remains usable without valid Toolbox context. It validates context version/origin and falls back to standalone shell behavior without moving or duplicating suite controls.
Fallback contract
MT requires all isolation headers plus secure context and
SharedArrayBuffer. When any prerequisite or MT load fails, the app terminates
that instance and loads ST. The manifest intentionally declares
crossOriginIsolated: false because isolation is not an unconditional
requirement; it declares workers, secure context, IndexedDB and top-level
context.
See scripts/portal-assembly-smoke.mjs and docs/RELEASE.md for the temporary,
non-mutating assembly procedure.