Sentinel is a Docker-first parental-control gateway for YouTube on Apple TV (YouTube Lounge).
It discovers TVs on LAN, pairs by TV code, monitors current/up-next videos, applies block/allow rules, optionally uses Gemini for AI decisions, and can actively force playback to a safe video.
- Dashboard:
http://<host>:8090 - Health:
GET /healthz - Live status API:
GET /api/status - Wiki pages (in this repo):
/docs/wiki/*.md
- Backend: FastAPI + async workers
- UI: Jinja templates + SSE live updates
- Storage: SQLite (
/data/sentinel.db) - TV control:
pyytlounge - AI: Google Gemini (
google-genai) - Packaging: Docker + Docker Compose
cp .env.example .env
docker compose --env-file .env up -d --buildOpen:
http://localhost:8090 (or replace with your host IP)
| Variable | Default | Description |
|---|---|---|
SENTINEL_PORT |
8090 |
Web UI and API port |
SENTINEL_DB_PATH |
/data/sentinel.db |
SQLite database path |
SENTINEL_BUILD_VERSION |
v1 |
Build/version label shown in UI |
GEMINI_API_KEY |
empty | Gemini API key (optional if running list-only mode) |
GEMINI_MODEL |
gemini-2.0-flash |
Gemini model id |
TZ |
UTC |
Container timezone |
This repo includes .github/workflows/docker-publish.yml to publish image tags to:
ghcr.io/joeblack2k/sentinel-yt
Pull latest:
docker pull ghcr.io/joeblack2k/sentinel-yt:latestExample compose override using GHCR image:
services:
sentinel:
image: ghcr.io/joeblack2k/sentinel-yt:latest
network_mode: host
volumes:
- ./data:/data
env_file:
- .env
restart: unless-stopped- Open YouTube on Apple TV -> Settings -> Link with TV code.
- In Sentinel, go to
Devices. - Press
Scan Network. - Click
Pairon the matching TV row. - Enter the code shown on TV and submit.
Fallback:
- Use
POST /api/devices/pair/codewith onlypairing_codewhen scan matching is not possible.
Shows blocked/allowed totals, trend charts, source breakdown, and database size.
Example:
- Use this page to see if policy changes increased block rate.
Streams real-time events (playing video, decision, intervention result, errors).
Example:
- Confirm a blocked video produced
intervention_play_safe.
Displays paged history: 50 items per page, max 500.
Example:
- Review a bad ALLOW decision, then blacklist it directly.
Manual block rules + policy toggles + imported TXT sources + local editable list.
Example manual rule payload:
{
"scope": "video",
"video_id": "dQw4w9WgXcQ",
"label": "Never allow this",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
}Manual allow rules + positive-content policy toggles + imported/local TXT sources.
Example:
- Switch schedule mode to
whitelistand only allow curated channels.
Supports multiple windows. Each window has its own mode:
blocklist: normal allow + block on matchwhitelist: default deny unless allowlisted
Example:
- 07:00-17:00 whitelist mode, 17:00-20:00 blocklist mode.
Independent from Sentinel:
- own on/off
- own schedule
- own webhook controls
- temporary remote release timer
Example release request:
{"minutes": 15, "source": "home_assistant", "reason": "shorts"}Editable custom prompt with immutable JSON output contract appended automatically.
Example:
- Save custom guardrails, keep schema lock for strict parser compatibility.
Gemini can be disabled. In that case Sentinel continues with local rules/lists only.
Example:
- Set
enabled=falseviaPOST /api/settings/gemini.
On fatal Gemini auth/quota/token failure:
- AI path degrades safely
- local block/allow lists still apply
- failure webhook can notify Home Assistant
View DB size and purge cache/history when needed.
Example purge payload:
{"target":"analysis_cache"}Control Sentinel and SponsorBlock from Home Assistant or any automation platform.
Examples:
- Pause Sentinel:
POST /api/webhook/control - Toggle SponsorBlock:
POST /api/webhook/sponsorblock/state - Temporary release:
POST /api/webhook/sponsorblock/release
GET /healthzGET /api/status
POST /api/control/statePOST /api/webhook/control
POST /api/devices/scanPOST /api/devices/pairPOST /api/devices/pair/code
GET /api/live/events(SSE)
POST /api/rules/whitelistPOST /api/rules/blacklistDELETE /api/rules/{rule_id}POST /api/blocklist/policiesPOST /api/allowlist/policies
POST /api/blocklist/sourcesPOST /api/blocklist/reloadPOST /api/blocklist/localPOST /api/allowlist/sourcesPOST /api/allowlist/reloadPOST /api/allowlist/local
POST /api/settings/promptPOST /api/settings/prompt/resetPOST /api/settings/schedulePOST /api/settings/webhookPOST /api/settings/gemini
GET /api/schedulesPOST /api/schedules/addPOST /api/schedules/{schedule_id}/updateDELETE /api/schedules/{schedule_id}
POST /api/sponsorblock/statePOST /api/webhook/sponsorblock/statePOST /api/sponsorblock/schedulePOST /api/sponsorblock/configPOST /api/sponsorblock/releasePOST /api/webhook/sponsorblock/release
GET /api/historyGET /api/db/statsPOST /api/admin/purge
Local files are adblock-style, supports comments and metadata:
# Block noisy toddler-targeted content
video:dQw4w9WgXcQ | Example title | https://www.youtube.com/watch?v=dQw4w9WgXcQ
channel:@ExampleChannel | Example channel | https://www.youtube.com/@ExampleChanneldocker compose --env-file .env up -d --build
BASE_URL=http://127.0.0.1:8090 ./scripts/smoke.shThis repository now also includes a Home Assistant add-on package.
Add-on files:
/addon/sentinel-yt/config.yaml/addon/sentinel-yt/Dockerfile/addon/sentinel-yt/run.sh/addon/sentinel-yt/DOCS.md/repository.yaml
Install flow:
- Home Assistant -> Settings -> Add-ons -> Add-on Store.
- Repositories -> add
https://github.com/joeblack2k/sentinel-yt. - Install
Sentinel YT. - Open web UI on
http://<ha-host>:8090.
See:
ops/synology/compose.yamlops/synology/.env.templateops/synology/README_DEPLOY_SYNOLOGY.mdops/synology/deploy_bundle.tar.gz
pytestCI workflow:
.github/workflows/ci.yml
Docker publish workflow:
.github/workflows/docker-publish.yml
