A Family policy is a small bundle of rules attached to a single monitored user: which websites to block, which apps to permit, when to lock for the night, how many minutes per day. Policies are authored from the Control Panel per monitored user and saved with one click — the moment you hit Save policy, the ruleset is pushed to the device and the local Family daemon enforces it on the next event it evaluates. No sync window, no reboot; enforcement is local to the node, not gated through CP.
Authoring a policy
Every policy is authored from the Policies tab on a device’s Family page.
- Pick a monitored user from the dropdown at the top of the tab. The dropdown lists only the users on this device that have Monitor turned on — everyone else is hidden.
- Edit fields in the PolicyEditor. Each section below maps to one field group in the editor: blocked websites, app access, bedtime, and the daily budget slider.
- Hit Save policy. The Control Panel PUTs the new ruleset to the node, the node persists it, and the running daemon picks it up on its next tick. A toast confirms when the device acknowledges the write.
If you need the same ruleset on more than one user — for example a classroom of small machines — author it once on a template user and push it to a group with Push to all members (see Bulk policy push (Pro) below).
Blocked websites
The Blocked websites field is a list of hostnames the device should refuse to resolve for any monitored user. Enforcement happens in DNSWatch, the local resolver the Family daemon runs on the node.
- One entry per line. Each entry is a bare domain like
youtube.com— no scheme, no path, no port. - Subdomains match automatically. An entry for
youtube.comblocksyoutube.comitself plus every true subdomain:www.youtube.com,m.youtube.com,kids.youtube.com. You don’t need to list each subdomain. - Not-suffix matches are not blocked. A hostname like
notyoutube.comshares a string suffix withyoutube.combut is not a subdomain of it, so DNSWatch leaves it alone. Only true parent-child relationships count. - NXDOMAIN is the verdict. When a blocked qname is queried, DNSWatch answers NXDOMAIN rather than dropping the packet — the application gets a clean “host not found” instead of a hang. The site simply doesn’t load.
- Every block fires a
block_attemptalert. See Family stats — Alerts for the alert wiring and the per-minute rate-limit that keeps the inbox useful.
Per-device union semantics
DNSWatch resolves a query against the union of every monitored
user’s blocklist on the device. If kid A has youtube.com blocked
and kid B doesn’t, the lookup is still refused — DNS doesn’t carry
the requesting uid down to the resolver in v1, so we conservatively
block when anyone’s policy says to. Per-uid attribution is on the
roadmap; for now, author blocklists with the strictest user in mind.
App access
The App access field controls which binaries the OS will let a monitored user execute. Enforcement happens through AppArmor — the daemon generates a profile file for the user and reloads AppArmor in place.
- Mode. Pick one of two modes:
- Allow all except… — a blocklist. Every binary runs except the ones you name.
- Allow only… — an allowlist. Only the binaries you name run; everything else is denied.
- Entries. One binary name per line — short names like
steam,discord,firefox. You don’t need the full path; the daemon resolves names against the standard binary locations. - What the daemon does. On save, the daemon writes
/etc/apparmor.d/family-<uid>for the monitored user and reloads the kernel’s profile cache withapparmor_parser -r. The new profile is in force the next time the user starts the named binary; running processes are not killed.
When AppArmor isn’t available
If apparmor_parser is not installed on the node — the binary
isn’t on $PATH, or AppArmor was never set up on this distro — the
daemon persists the policy but cannot enforce it. A warning is
written to the daemon journal so the failure is visible in the node
logs, and the next save attempts the reload again. There is no
fallback to iptables, nftables, seccomp, or a userspace shim — if
AppArmor is absent on the node, the app rules sit dormant until you
install AppArmor and re-save the policy.
Bedtime lock
The Bedtime field is a single time window during which the monitored user’s sessions are locked. Enforcement happens in the daemon’s bedtime evaluator, which checks the wall clock once a minute.
- Two inputs. A start minute-of-day and an end minute-of-
day, both interpreted against the node’s local wall clock (UTC-
local — the daemon uses whatever
localtimeresolves to). The CP editor exposes them asHH:MMpickers. - Wrap past midnight is supported. A window of
22:00 → 07:00means “22:00 to 07:00 of the next day” — the evaluator handles the wrap automatically. A window of09:00 → 17:00means a normal daytime block. - What the daemon does inside the window. Once a minute, if the
wall clock is inside the configured window, the daemon enumerates
every session owned by the monitored user and runs
loginctl lock-session <id>against each one. The lock screen comes up and the user has to dismiss it; if the window is still active a minute later, it locks again. - Every lock fires a
bedtimealert. See Family stats — Alerts.
Bedtime is independent of the daily budget — a session can be inside the bedtime window and under its budget cap at the same time; either condition locks the session.
Daily screen-time budget
The Daily budget field caps how many minutes per day the monitored user can spend in an active session.
- Slider, 15-minute increments, 0 – 480. The editor exposes the value as a slider from 0 minutes (no session allowed) to 480 minutes (8 hours) in 15-minute steps. Set to 0 to effectively disable interactive use; leave the field empty to disable the budget entirely.
- Per-minute increment when a session is active. Once a minute,
the daemon calls
loginctl list-sessionsand looks for an active session owned by the monitored user. If one is found, the user’s per-day counter ticks up by one. If the user is logged out or every session isinactive, the counter doesn’t move. - At the cap. The moment the counter hits the configured budget,
the daemon locks every session owned by the user (
loginctl lock-session) and fires abudgetalert. The user can’t unlock for the remainder of the day. - Reset. The per-user counter resets to zero at UTC midnight. A new day starts a fresh budget.
The counter is a foreground-time approximation, not a precise wall-
clock measurement: a session that’s been idle long enough for
systemd-logind to mark it inactive doesn’t count. Locked sessions
also don’t count.
Bulk policy push (Pro)
When you’re running more than a couple of devices — a classroom, multiple kids on identical builds — authoring the same policy on each one by hand gets old fast. Group-level policy push lets you keep a single policy on a group and fan it out to every member device in one click.
- On the Groups page in CP, open the group you want to push to.
- Switch to the Policies tab. It exposes the same PolicyEditor you’d see on an individual user, scoped to the group instead.
- Edit the policy — blocklists, app rules, bedtime, budget.
- Click Push to all members. CP fans out the PUT to each member’s node in parallel.
Per-member success and failure is reported inline in the Push
results panel (e.g. “12 of 14 succeeded; 2 failed: node-A
timeout, node-B 5xx”) and the same per-member outcome is stored on
the group as last_push_results so you can come back later and
see how the most recent push landed without re-running it.
Bulk policy push is a Pro-tier capability — see Family overview for the full Free vs Pro matrix.
Hardening reminder
Every policy on this page is enforced from inside the running OS: DNSWatch is a process the daemon owns, AppArmor profiles are kernel state on the booted system, bedtime and budget run on the daemon’s tick loop. A monitored user who can boot the machine into a different OS — a live USB, a recovery shell, a rescue partition — bypasses every rule on this page, because the daemon never gets a chance to run.
If you want the policy to actually hold against a determined kid, you need to lock down the boot path too. See Family hardening for the boot-path lockdown — BIOS/UEFI password, boot order, recovery-mode policy, and disk-encryption recommendations.
Where to next
- Family stats — what shows up in the
Timeline + Summary after a
block_attempt,bedtime, orbudgetalert fires. - Family screen — live screen view setup and audit trail (Pro).
- Family hardening — boot-path lockdown that keeps a monitored user from disabling the policies by booting around them.