# Security Policy

## Reporting a vulnerability

Email **duncan@tourolle.paris** with `[JellyTau security]` in the subject.
Please do **not** open a public issue for a vulnerability — JellyTau handles
Jellyfin credentials and media, and an unfixed issue in a public tracker is an
advisory for everyone running it.

Include what you have: what the problem is, how to reproduce it, the version and
platform, and what you think an attacker could do with it. A rough report is
worth more than a polished one that never gets sent.

You can expect an acknowledgement within a week. If a fix is warranted it will
ship in the next release, and you will be credited in the release notes unless
you would rather not be.

## Supported versions

JellyTau is a single-maintainer project without long-term support branches.
**Only the latest release receives fixes.** Desktop builds can update themselves
(Settings → Updates); on Android, install the latest APK from the releases page.

## What is in scope

The application and its build pipeline:

- The Tauri backend (`src-tauri/`) and the Svelte frontend (`src/`)
- Credential storage — the system keyring and its encrypted-file fallback
- The Android player service and its JNI bridge
- The loopback media server used for downloaded playback
- The release pipeline: artifact signing, the update manifest, the builder image

**Out of scope:** vulnerabilities in Jellyfin itself (report those to the
Jellyfin project), and issues that require an already-compromised device or a
malicious server the user deliberately configured and trusted.

## What the project already does

Not a guarantee, but so you know what has been considered:

- **Credentials** never go in plaintext config: the system keyring is used where
  available, with an AES-GCM encrypted file as fallback (see
  [docs/architecture/09-security.md](docs/architecture/09-security.md)).
- **The webview runs under a restrictive CSP**, and the asset protocol is scoped
  to the thumbnail cache directory only.
- **Path confinement** is enforced on the cache and download roots — a
  server-supplied id cannot decide where a file lands (DR-210, DR-211).
- **Queries and URLs bind or encode their inputs** rather than interpolating
  them (DR-212).
- **Dependencies are scanned on every build** by `cargo deny` against the RustSec
  advisory database, and licence-checked against an allow-list (DR-216).
- **Releases carry `SHA256SUMS` and an SBOM**, so you can verify a download and
  find out what went into it.
- **Desktop updates are signature-verified** against a key held only in CI before
  anything is installed (DR-217).

Windows installers are **not** Authenticode-signed — SmartScreen will warn on
first run. That is a cost and identity problem, not an oversight; verify the
download against `SHA256SUMS` instead.
