Spaces:
Running
Download SECURITY.md from Telearn/Project_Demo: direct link, hf CLI and curl.
- Browser
- Download file 3.56 kB
-
https://huggingface.co/spaces/Telearn/Project_Demo/resolve/main/SECURITY.md
- Command line
-
hf download hf://spaces/Telearn/Project_Demo/SECURITY.md
-
curl -L -o SECURITY.md https://huggingface.co/spaces/Telearn/Project_Demo/resolve/main/SECURITY.md
Security and deployment notes
Student Python execution
- Docker installs Bubblewrap and
prlimit; the app runs as the unprivilegedtelearnaccount. - Each public Python run gets a copied, size-limited project workspace and CPU/address-space/file/process limits. Child environments use an allowlist and do not inherit application tokens or admin credentials.
RUNNER_ISOLATION_MODE=sandbox(the source default) additionally requires Linux user/PID/network namespaces and read-only system mounts, and fails closed if the host blocks namespace creation.- At the owner's request, the Docker image explicitly sets
RUNNER_ISOLATION_MODE=processto restore Python demos on Hugging Face, whose current host rejects unprivileged namespace creation. This mode runs a separate, resource-limited process astelearn, but provides no filesystem, network, or same-user process isolation. Environment filtering and temporary project copies are not a security sandbox. Set the mode back tosandboxon a compatible execution host. - Uvicorn caps WebSocket frames at 1 MiB. Classroom sockets also have per-IP handshake and per-student message budgets; saved checkpoints/submissions have per-hour limits, cooldowns, a per-course quota, and a rolling retention cap.
Classroom storage
Defaults are configured in Dockerfile and may be changed with CLASSROOM_* environment variables. The database retains up to 100 checkpoints and 100 submissions per student per Lesson, with a 1 GiB active-data quota per course. Older versions are removed from the active SQLite history and Hugging Face repository tree.
Deleting a file from a Hugging Face repository's current tree does not rewrite earlier Git commits. Therefore these limits bound the active version set and current tree, but cannot strictly cap the repository's historical Git object storage. A hard lifetime storage cap requires moving classroom versions to bounded object storage or periodically archiving/recreating the repository; neither is performed automatically.
Browser security
The app sends CSP, COOP/COEP, X-Content-Type-Options, Referrer Policy, Permissions Policy, and HSTS (enabled in the Docker image). CodeMirror, JSZip, and Pyodide are served same-origin from exact package versions included during image build. The pinned pygame-ce wheel and its lockfile dependency closure are also vendored same-origin, with each wheel SHA-256 checked against Pyodide's lockfile during the image build. Google Fonts, the QR service, Appetize, and MakeCode remain explicit external sources. Student HTML remains inside an opaque-origin sandbox iframe.
After deployment, inspect the final public HTTPS response headers: Hugging Face's edge proxy must preserve or add HSTS and must not replace the application CSP with a weaker policy. Local source changes cannot prove what the edge returns.
Dependency scanning and lock files
Every Docker build resolves requirements.txt in a Python 3.11 build stage, generates a complete transitive lock with hashes, audits that resolved lock using pip-audit, then installs the runtime dependencies with --require-hashes. The generated lock is included in the image as /app/requirements.lock; it is build-specific rather than checked into source, so rebuilding later may select newer versions allowed by requirements.txt. GitHub Actions also runs pip-audit on pull requests and weekly when this repo is mirrored to GitHub; the canonical remote for this project is Hugging Face, which does not execute that GitHub workflow by itself.