Permission

:= [
    HttpOrigin(Url),
    HttpAny,
    UdpBind(U16),
    UdpPeer(Str, U16),
    UdpLoopback,
    UdpAny,
    Command(Str),
    CommandAny,
    EnvVar(Str),
    EnvAny,
    ClipboardRead,
    ClipboardWrite,
    WorkingDirectory([ReadOnly, ReadWrite]),
    Directory(Str, [ReadOnly, ReadWrite]),
    FilesAny([ReadOnly, ReadWrite]),
]

What an app may access beyond its own resources.

Some things every app has without asking: its window, input, clocks, standard output and error, captures under its output directory, and the directory beside its executable. Everything else -- network origins and peers, other directories, programs, environment variables, the clipboard -- is declared in the startup Config, and the declaration is the grant:

config =
    App.default
    .with_title("Weather")
    .with_permission(HttpOrigin("https://api.example.com"))
    .with_permission(EnvVar("WEATHER_TOKEN"))

There is no launch flag that widens this, so what an app can access is visible in its source and changed only by changing its source.

Declare each facility as narrowly as it allows. An origin, a port, a program name, a variable name, or a directory is a scope: an effect whose target falls outside every declared scope returns PermissionDenied without doing anything, because a URL or path can be runtime data. PermissionDenied means only that: no declaration covers the target. A path refused for its shape -- one with .. that no declaration can cover, or one that meets a symbolic link beneath a handle -- is PathInvalid instead, because the fix is to the path, not to the declarations.

Using a facility the app never declared at all is a programmer error: the app stops at once with a message naming the declaration to add. A malformed declaration -- a directory with .., a peer that is not an IPv4 address -- stops the app before init!.

A declaration is platform policy, not an operating-system sandbox: it limits what Roc code in the app can access, because that code has no way to access anything except through the platform.

is_eq : _

Compare two declarations.