Files
av-tools/docs/PORTAL_REQUIREMENTS.md

4.0 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-reviewed-stack5m.1/...; 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.

Reviewed Portal state

Portal revision 5c052bc6d1073a66600cfddc44c0e16da34bede8 (tag v0.6.0) already sends COOP same-origin, COEP require-corp, CORP same-origin, script-src 'self' 'wasm-unsafe-eval', worker-src 'self' blob: and media-src 'self' blob:. Its nginx profile also maps .wasm explicitly to application/wasm. Local source and result Blob previews therefore require no CSP exception beyond that reviewed narrow media directive.

As inspected on 2026-07-26, the active /mnt/DATA/git/toolbox-portal/deploy/nginx.conf has an additional worktree patch that extends the immutable FFmpeg cache rule from plain semantic versions to the one exact reviewed build profile 0.12.10-reviewed-stack5m.1. The corresponding deployment tests accept the five reviewed core files and version.json while rejecting mutable-looking suffixes, malformed versions and unexpected paths. A clean temporary clone containing that exact patch passed the AV release assembly smoke without a known-header-gap override.

Until the cache extension is committed, cite it only as staged integration evidence, not as a published Portal revision. The clean v0.6.0 rule leaves the reviewed profile at no-cache; that affects performance, not loading, MIME type, isolation or preview correctness.

Caching

The staged Portal cache map makes Vite content-hashed assets, plain semantic versions and the explicitly reviewed profile immutable. For performance, the exact directory apps/av/vendor/ffmpeg/0.12.10-reviewed-stack5m.1/{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.