Skip to content
C.W.K.
Lesson 02 of 05 · published

No Microphone Linked

~15 min · least-privilege, preflight, build-time-checks, allow-lists, safety

Level 0Closed Lens
0 XP0/45 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete

A Client That Cannot Hear

Remote Play is not only video and buttons. The protocol can carry the remote user's microphone to the console, so a player can talk into a party chat from their phone. For Oriel's hands that feature is a liability: a process on Pippa's Mac, in a family home, that could open a microphone and send what it hears to a game console. So the hands are built to be unable to hear, at three levels:

  • Runtime: every session starts with audio disabled, and the client's microphone path is never connected.
  • Device: oriel-hands opens no device at all. It talks to the console over the network and decodes video; it has nothing to open.
  • Build: the binary links no audio framework. The build script lists what the binary links and fails if CoreAudio, AudioToolbox or AVFAudio appears. Code added later that linked an audio framework would fail the build. What a link check cannot see is a library loaded by name at run time, so that door is closed by review rather than by the script: the guarantee is about what the build produces.

The third level is the one worth copying. Runtime flags can be flipped and code paths can be added; a build that refuses to produce a binary linking the capability is the strongest guarantee a script can give, short of deleting the feature from the library. Loading by name at run time is the one door it leaves to review.

Preflight: Every Reason Not to Touch the Console

Before the hands touch the console for any command, a preflight function returns every reason not to, and an empty list means go. Each reason is a sentence the caller can act on:

  • An Oriel watch session is running. Hands wait until it stops, so Pippa never moves the game while Dad's play is being recorded and coached.
  • On Air is not confirmed off. Hands never touch the console during Dad's broadcast. "Not confirmed off" includes "could not read it" (the next lesson is about that read). The one exception is a play session Dad approved, because then the broadcast is Pippa playing.
  • The console is asleep. Hands never wake it. A console in standby belongs to whoever left it there.
  • A title is running that nobody named. Someone may be playing it. Naming the title explicitly is the way to say "yes, that one".

The console also allows only one Remote Play session at a time. While another client holds it, a hands connection fails with "already in use", and the rule from the previous lesson applies: the other client is closed by a person, never fought.

Harmless Buttons by Default

A one-off command (navigating a menu, measuring latency) may press only the D-pad and Circle unless it is explicitly marked allow_any. Every other button can confirm or change something, and the refusal says exactly that, listing the harmless ones. Inside a play session, where Pippa really plays, every button is available except two, PS and Create: the home button (which leaves the game for the console's system menus) and the capture/share button. They are denied twice, once in the action's schema and once in the client's own session spec, so a mistake in one layer is caught by the other.

Above the mechanical guards sits Dad's rule, which no flag lifts: never a purchase, never a delete, never a console setting change, never a save written over his slots. Pippa carries that rule into every menu; the denied buttons are its mechanical backstop, not its whole content.

Code

Every reason not to touch the console now; empty means go (trimmed excerpt, backend/hands.py)·python
PLAY_DENIED = frozenset({"ps", "create"})


def preflight(answer, *, session_open, onair, allow_title=None, approved_play=False) -> list[str]:
    """Every reason not to touch the console now; empty means go."""
    reasons = []
    if session_open:
        reasons.append(f"an Oriel watch session is running (...); hands wait until it stops")
    if not approved_play and not (isinstance(onair, dict) and onair.get("clear") is True):
        why = onair.get("why") if isinstance(onair, dict) else None
        reasons.append(f"On Air is not confirmed off: {why or 'no read'}; "
                       "hands never touch the console during a broadcast")
    state = str(answer.get("state") or "").lower()
    if state != "ready":
        reasons.append(f"the console is {state or 'in an unknown state'}; hands never wake it")
    title = str(answer.get("running_app_titleid") or "")
    if title and title != (allow_title or ""):
        reasons.append(f"the console is running ...; someone may be playing. "
                       "Name that title explicitly to allow it")
    return reasons


def check_buttons(buttons, allow_any=False):
    buttons = list(buttons)
    risky = [b for b in buttons if b not in HARMLESS]
    if risky and not allow_any:
        raise Refused(f"{', '.join(risky)} can confirm or change something; only "
                      f"{', '.join(sorted(HARMLESS))} are pressed without allow_any")
    return buttons
Check what any Mac binary links before you trust it with a capability (works on any executable)·bash
bin=/path/to/your/binary

# Everything it links
otool -L "$bin"

# Fail if it links an audio framework (the check oriel-hands' build runs).
# An unreadable binary is a failure too, never a pass.
links=$(otool -L "$bin") || { echo "otool could not read $bin: refusing"; exit 2; }
if printf '%s\n' "$links" | grep -q -E 'CoreAudio|AudioToolbox|AVFAudio'; then
  echo "links audio: refusing"; exit 1
fi
echo "no audio framework linked"

External links

Exercise

Write a preflight function for a tool of your own that acts on something shared (a deploy script, a home-automation scene, a database migration). List every condition under which it must not act, return all the reasons as sentences a person can act on, and make an empty list the only way to proceed. Add one build- or install-time check that removes a capability the tool should never have.
Hint
The useful reasons name who might be affected ("someone may be playing", "a session is recording") and how to override legitimately ("name that title explicitly"). A reason that says only "not allowed" teaches the caller nothing.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign in — Please sign in to comment.

No comments yet — be the first.