Viewer guide
Securing your Viewer
Who can get in, what each person can reach, and where on your network to run it.
A Viewer holds your team's unreleased work: prototypes, and everything said about them. Four things decide who reaches it, and you set all four.
Nothing here is optional-but-recommended fiddling. The defaults are already closed, and this page is mostly about knowing what they are.
Nobody gets in unless you let them#
The Viewer is invite-only. Signing in with GitHub does not create an account by itself. One check decides every sign-in, and it admits someone only if:
- they were invited, by an invite link or a sign-in link an Admin sent them; or
- their email domain matches a rule you added; or
- they are the very first person on a brand-new instance, who becomes the Admin.
Anyone else is turned away and told to ask an admin for an invite. See members and tokens for the four ways to sign in and how to send an invite.
Note A domain rule is the one that catches people by surprise. It lets anyone with an email at that domain sign themselves in, which is what you want for your own company and not what you want for a shared contractor domain. Review the rules in Settings before you hand the address out.
Three roles, and no per-project ones#
Everyone has exactly one role for the whole Viewer.
| Role | Can |
|---|---|
| Admin | Everything, including inviting people, changing roles, and managing every prototype |
| Editor | Manage any prototype they can read: rename it, rebuild it, change who can open it |
| Viewer | Read and comment. They cannot manage anything. |
There is no per-prototype ownership to configure. Whether someone can rename, rebuild or delete a prototype comes from their role alone. Give a reviewer the Viewer role and there is nothing they can break.
You cannot lock yourself out: demoting or removing the last active Admin is refused.
Who can open one prototype#
Each prototype is in one of three states, which you change from its settings:
- Everyone here (the default). Any active member can open it.
- Invited only. Only people on that prototype's list, plus Admins.
- Anyone with the link. No sign-in at all.
That third one is the only way something leaves your team, so there is a switch above it: an Admin can turn public links off for the whole Viewer. Turn it off and every prototype set to "anyone with the link" quietly requires sign-in again. Nothing is deleted, and turning it back on restores them.
A prototype someone is not allowed to open does not tell them it exists. See deploy a prototype for setting this per prototype.
Where to run it#
This is the part to decide before you hand out the address.
Building a prototype runs that repository's own commands on the machine the Viewer is on, the same as any build server you host. A build gets a minimal environment, is stopped as a whole if it hangs, has its output capped, and never sees your GitHub token in its logs. It still runs there, so treat the people who can connect a repository as people who can run code on that machine. Today that is Admins and Editors.
Sign-in, comment writes and invites are rate limited. Nothing else is. That is enough for a Viewer your team reaches, and it is not enough to sit unprotected on the open internet.
So put it where your team already is: a private network, an office network, a VPN, or a machine only your team can reach. That is the setup this is built for, and it is the one that needs the least from you. If you do put it on a public address anyway, put a proxy in front that rate limits.
Put HTTPS in front of it#
The Viewer speaks plain HTTP and terminates nothing, so a proxy does your TLS. Two settings there are easy to miss and both fail quietly:
VIEWER_PUBLIC_URLmust be thehttpsaddress. Sign-in cookies are marked secure only when it starts withhttps://. Leave it on anhttpvalue behind an HTTPS proxy and those cookies travel unprotected.VIEWER_TRUST_PROXYmust be set, or every request looks like it came from the proxy and the rate limits above collapse into one shared bucket.
HTTPS and a reverse proxy has the nginx block with both, and the header the proxy has to pass for the second one to mean anything.
A prototype cannot reach your session#
A prototype is code someone else wrote, running in a reviewer's browser next to the Viewer itself. It is kept from reading their sign-in or reaching the Viewer's API, and the strength of that depends on one piece of setup: give each prototype an address of its own and the browser's own rules do the work.
Where prototypes are served covers the one wildcard DNS record that arranges it, and what happens if you cannot add one.
Tokens for scripts#
A machine token lets a script or an Editor talk to the Viewer. Each one is read-only unless you tick write, and each is tied to the person who made it.
A token can never do more than its owner can do right now. Change someone's role or remove them and their tokens follow immediately, so there is no separate list to clean up when someone leaves.
A token is shown once, when it is made, and never again. See members and tokens for minting and revoking.
Before you hand out the address#
- Put it on a network your team already trusts.
- Set
VIEWER_PUBLIC_URLto thehttpsaddress, andVIEWER_TRUST_PROXYbehind a proxy. - Give each prototype an address of its own, with one wildcard DNS record.
- Check Settings for domain rules you did not mean to add.
- Decide whether public links should be available at all, and turn the switch off if not.
- Give reviewers the Viewer role. Editor is for people who deploy.
- Back up the data folder. See backups and disk space.
Next#
- Members and tokens: invites, roles, and tokens in full
- Deploy a prototype: setting who can open one
- Deploy the Viewer: running it in the first place