Summary#
Your app's own code may call any public host by default — the platform blocks only its internal addresses. An
administrator narrows that with egress rules: allow a host and the app may reach only what is allowed; deny a
host and it may never reach it, whatever else says so.
The rules live in a file beside app.osy called .egress. It is the durable record: osy egress edits it, a local
osy compile applies it to your local platform, and osy deploy carries it with the app and applies it where the
app runs. A rule you wrote is the rule in force, on your machine and in every environment you deploy to.
Signature#
$ osy egress allow api.partner.example # permit a host — the FIRST allow closes the app
$ osy egress deny *.tracker.example # refuse a host, whatever else allows it
$ osy egress remove api.partner.example # drop every rule naming that host
$ osy egress list # the rules, what they mean, and every package's granted hosts
$ osy egress observed # where the app has actually tried to goDescription#
What the file says#
One rule per line, allow or deny and one host. # starts a comment.
# only these hosts
allow *.partner.example
allow api.payments.example
# …and never this one, even though the wildcard covers it
deny blocked.partner.exampleA host is api.example.com, or *.example.com for every subdomain — not the apex: *.example.com does not match
example.com. A URL, a port, a bare * or a wildcard anywhere but the front is refused by name rather than read as
something else. So is a line with no verb: api.example.com on its own could mean either, and guessing wrong in the
permissive direction turns a deny-list into an allow-list.
What a set of rules means#
Only an allow closes the app. That is the one rule to remember, and osy egress list says which posture you are
in so you never have to work it out:
| The file holds | The app may reach |
|---|---|
| nothing, or no file | any public host — open |
only deny lines | any public host except the denied ones |
one or more allow lines | only the allowed hosts, minus any denied |
⚠ The first allow is a bigger change than one line looks: from then on everything not allowed is refused. Run the app
open first and read osy egress observed — every host it has actually tried to reach — before you close it.
A deny binds your packages too: a package reaches only what you grant it in use X { egress "…"; }, and a deny
refuses that host even so. Your own allow list does not narrow a package's grant — the grant already is your decision
about that package ([[project-package#browser-egress]]).
It reaches where the app runs#
osy deploy reads .egress with the rest of the project and the deploy carries it. The zone that builds the
version applies the rules to the environment's database in the same commit as the version's other data, so the
version goes live with its rules or not at all:
$ osy deploy --env prod
Building billing locally…
Built billing: blob 3f2a9c1b04e7 (412311 bytes), 0 package archive(s), in 2140 ms
Its own egress rules (.egress) travel with it and are applied where it runs: CLOSED to 2 allowed host(s), minus 1 denied- The file is the whole posture. A deploy with no
.egressfile sets no rules of its own — any the app had in that environment are removed. A line you delete is a rule that is gone there too, on the next deploy. - A line that cannot be read refuses the deploy, naming the line, before anything is uploaded. Shipping the lines that could be read would put a posture in force that no file describes.
- A change to
.egressis a new version. Two deploys that differ only in their rules are not the same deploy. - The rules are shown on the application's Config tab in the console, per environment, as the app's own — beside the hosts its packages are granted.
Local: applied on every compile#
On your machine the verbs apply the file to a running local platform immediately, and osy compile re-applies it after
every compile — so it survives a reset of the local instance with nothing to remember.
An app that sends nothing#
The rules govern what the app sends: its own Http.*, Imap.* and Smtp.* calls (all under use Osysharp.Http;), the
calls of the packages it grants hosts, and the browser hosts it grants a package. An app that does none of these has
nothing to govern, so it carries no table for rules at all. Write a .egress file for it anyway and it is kept: the
verbs and osy compile say the rules were not applied and why, and the first compile or deploy of a version that does
send applies them.
When your organization sets rules too#
An application may also be bound by rules its organization sets. Those are a ceiling: your allow cannot reach past
them, while your deny can always be stricter. The .egress file only ever writes the application's own rules — it
cannot add, change or remove an organization's.
On Osyrin Cloud an organization's Owners and Admins keep its Allowed hosts in the organization's settings. While
that list holds a host, every application of the organization reaches only the hosts on it — whatever the application
allows, and whatever a kit it uses asks for, a kit granted any host included. A change reaches every application at
its next call out, wherever it runs; an empty list hands the decision back to each application's own rules.
osy egress list shows the organization's hosts beside your own, marked as not yours to change, and a host the list
refuses is named in the refusal with where to add it.
Beside it the organization keeps its Blocked hosts: hosts none of its applications may reach. A blocked host is refused whatever else allows it — the application's own rules, a kit granted any host, and the organization's own allowed hosts. The application's code, every kit it uses and the page's browser code are all held to it, from the next call out. The refusal says the organization blocks the host; only an Owner or Admin of the organization can unblock it.
See also#
- package.osy — granting a package the hosts it needs,
egress browserfor browser code - Hosting an Osy# app — where a deploy runs
- Deploying while workflows are running — what a deploy mints