Skip to Content
DocsCloud OSFamily Policies

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.

  1. 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.
  2. 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.
  3. 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.com blocks youtube.com itself 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.com shares a string suffix with youtube.com but 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_attempt alert. 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 with apparmor_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 localtime resolves to). The CP editor exposes them as HH:MM pickers.
  • Wrap past midnight is supported. A window of 22:00 → 07:00 means “22:00 to 07:00 of the next day” — the evaluator handles the wrap automatically. A window of 09:00 → 17:00 means 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 bedtime alert. 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-sessions and 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 is inactive, 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 a budget alert. 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.

  1. On the Groups page in CP, open the group you want to push to.
  2. Switch to the Policies tab. It exposes the same PolicyEditor you’d see on an individual user, scoped to the group instead.
  3. Edit the policy — blocklists, app rules, bedtime, budget.
  4. 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, or budget alert 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.