is_eq : _
Compare two declarations.
:= [
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.