08 When you get a 403

Chapter 08

When you get a 403

Sites and folders can be locked to a list of unlocked IP addresses. If yours is not on that list you get a refusal with no explanation. Not every refusal is that one, though, so the first job is recognising what you are looking at.

How locking works

A locked site or folder serves only requests from unlocked IP addresses. Everyone else gets a 403, refused at the proxy before your application is ever consulted. Two shapes exist:

  • The whole site is locked — nothing is reachable except from an approved address.
  • Specific folders are locked, such as an admin area, while the rest of the site stays public.

A whole-site lock supersedes the folder list. Locks apply to the site's alias domains too, so there is no way around one by using a different address — with one exception, an alias that only redirects to the primary domain rather than serving the site, which keeps redirecting while the site is locked (chapter 07). The same holds for a custom stack: one lock covers every one of its domains, and there is deliberately no per-domain lock — every row serves the same application, so locking one and leaving another open would only look like safety.

Locking is the same page for both kinds of site: open the site and pick the Locking tab. A "locked folder" is a URL path prefix such as /wp-admin/*, not a directory in your files — which is why it works identically whatever is running behind it.

You can see which sites are locked without opening any of them: the sites list says so in the same Visibility column that says whether a site is published (chapter 02.1), with a Locked chip for a whole-site lock and a count of folders when only some paths are locked. The control panel itself never carries that chip, because it cannot be locked — it is the way back in.

What a lock covers stops at web traffic, and that boundary has three consequences worth knowing.

  • If a folder of one of your sites is mounted into another of them (chapter 06), that mount keeps working whether either site is locked or not — locking decides who is served over the web, and has no say over files.
  • A port opened on the server for a custom stack — git over SSH, for instance — is a raw connection that never reaches the proxy. The allowlist is an HTTP-level control, so it cannot cover such a port at all: a locked stack is still reachable there, from anywhere, and whatever listens on the container port is the only access control there is. Chapter 02.2.
  • A locked site is still reachable over SFTP. The file service listens on its own port, outside the allowlist as well, and it is usually what you want: whoever holds a key is generally the person fixing the thing the site was locked for. What revokes file access is removing the key from the account, never locking the site. Chapter 04.

The list is global rather than per-site: an approved address passes everywhere it is allowed. It keeps working even if the control panel itself is stopped, because enforcement lives in the proxy and not in the panel.

Because it is enforced at the proxy, locking always compares against the visitor's real address. An IP check inside your own application is a different thing entirely and does not: it sees the proxy until you configure trusted proxies, which chapter 07 covers. The two are easy to conflate when an in-app allowlist admits everyone and the platform lock next to it is behaving perfectly.

Telling the refusals apart

Three different things can turn you away, and they look nothing alike. Which one you are looking at tells you what to do.

A locked site or folderThe panel refusing youA site that is not yours
What you see A blank browser error page. No branding, no words, no links. A styled Nimbus page reading "You do not have access to this part of the panel." A plain not found — the same answer the panel gives for a site nobody ever created.
What it means Your IP address is not unlocked. You are signed in, but the page you asked for is administrator-only. The site exists, but it is filed under another account, so it is not in yours.
What to do Unlock your IP address — see below. Nothing you can fix yourself. Ask your operator, or sign out if you used the wrong account. Check which account you are signed in as. If the site should be yours, ask an administrator to hand it over.

The blank one is the one you can act on. It is deliberately bare — the refusal happens at the proxy, which knows nothing about who you are or that a panel exists.

Unlocking your IP address

There are two ways onto the list, and they answer different situations. Pressing a button in the panel is the quick one, and needs nothing set up beforehand. A machine holding an API token can do the same thing with one HTTPS call — which is the one that keeps working when your address has changed and the panel will not let you in.

From the panel

The control panel's own domain is never lockable. That is the way back in, and it always answers.

  1. Go to the panel's domain — ask your operator for it if you do not have it, and keep it somewhere you can find without a working site.
  2. Press "Unlock my address". The front page offers that button precisely because it does not recognise the address you are at; the usual "Open the panel" is deliberately absent, since from here it would only lead to a refusal.
  3. Sign in. The panel takes you straight to IP unlock.
  4. Your current IP address is shown under "Your address", with a line telling you whether it is unlocked.
  5. Press "Unlock my IP address".
  6. Reload the site that refused you. It should serve immediately — the change takes effect right away, not after a delay.
You hold one IP address at a time

Unlocking replaces your previous IP address rather than adding to it. Moving between networks — office to home, or onto mobile data — means the old address stops working the moment you unlock the new one.

If the page tells you that you are currently unlocked from a different address, that is exactly what has happened: you moved. Press the button again to move your entry to where you are now.

This page unlocks where you are, and nothing else

It has no address field. It unlocks the IP address the request actually came from — there is no way to type in a colleague's address, or a range. Anyone who needs access this way must sign in themselves, from the place they need access from.

The practical consequence: a VPN, a proxy, or a mobile connection that changes address needs unlocking again each time the address changes. Doing that by hand every time is what the next section removes; an address that should stay admitted with nobody behind it at all is a different job again, further down.

From the machine, with an API token

The button has one weakness, and it is the situation people actually hit: your address changed, so the panel refuses you, so you cannot reach the page that would fix it. The only answer used to be finding somebody who was already unlocked.

An account can instead hold an API token, and a machine holding that token unlocks its own address with a single call — no browser, no sign-in, nobody else involved.

Tokens live on Your accountAPI tokens, one of that page's two tabs; the other is SSH keys, which is how you reach your sites' files (chapter 04). You reach that page from the foot of the panel's menu, where the address you are signed in as is followed by two small icon buttons: one opens your account, the other signs you out. They sit where the full-width Sign out button used to be, and they are in the same place on a phone, inside the ☰ drawer. The page is deliberately not in the administrator area, and every account can use it whatever its role — you have to be able to get at it while you are locked out.

Add token asks what the token is for, then shows the token once, with a copy button. It is never shown again: the panel keeps only a one-way hash of it, so there is nothing to look up later. Put it somewhere your machine can read it before you leave the page.

A lost token is replaced, never recovered

If you did not save it, or you are no longer sure who has a copy, revoke it and add another. That is the whole remedy, and it costs nothing — a token carries no history worth keeping.

The call goes out from the machine you want unlocked:

$ curl -X PUT https://<your-panel-domain>/api/v1/allowlist/address \
    -H "Authorization: Bearer $NIMBUS_TOKEN" \
    -H 'Content-Type: application/json' \
    -d '{"label":"Home office"}'

The label is required. It is the name the address appears under on Unlocked IPs, so pick something that still means something to whoever reads that page in six months.

A token unlocks the address the call comes from, and nothing else

There is no field for an address, and no way to add one: an address in the request body, in the query string, or in a forwarding header changes nothing at all. The worst a stolen token can do is unlock the machine that leaked it.

That is why every role can hold one, and why it is a reasonable thing to leave in a cron job on your own machine.

Repeating the call is safe, and repeating it is the point. If the address has not changed, nothing changes. If it has, the unlock moves across with it. So a connection whose address wanders — a home line, a mobile hotspot — is handled by a timer rather than by you noticing:

*/15 * * * * curl -fsS -X PUT https://<your-panel-domain>/api/v1/allowlist/address \
    -H "Authorization: Bearer $NIMBUS_TOKEN" -H 'Content-Type: application/json' \
    -d '{"label":"Home office"}' >/dev/null

One token holds one address, exactly as an account does. When a token unlocks a new address it gives up the one it held before — which is what makes the timer above correct rather than a slowly growing list.

Revoking closes the address as well as the token

Revoke does two things, and the second one surprises people: the token stops working, and the address it opened stops being unlocked. The confirmation names the address it is about to close. Deleting an account does the same for every token it held.

Three answers are worth handling in a script. A 401 means the token is wrong or has been revoked — the panel gives the same answer for every such case on purpose, so do not expect to be told which. A 429 means more than ten calls a minute from your address; a quarter-hourly timer is nowhere near it. And a successful reply carrying "enforced": false means the unlock was saved but is not in force yet — repeat the same call. A script that checks only the status code will report success while the site still refuses you. Chapter 09 lists the endpoint and its answers in full.

Addresses nobody is standing behind

The office, a VPN exit, an uptime probe, a partner's fixed address: these need to be on the list and stay there, and there is nobody to sign in and press the button. If the address is fixed, an administrator can put one on by hand; if it moves but there is a machine at the other end of it, a token on a timer covers the same ground without anyone being asked.

The by-hand route is on the same page as before — Whitelisted IPs in the panel's menu, titled Unlocked IPs — in a second card called Well-known addresses. An entry takes a name and one IP address, and every row has a Remove button.

There is still only one list. An address added this way reaches every locked site and folder on the box, exactly as any unlocked address does; this is another way onto the same list, not a second list. What changes is where the entry comes from and how long it lasts.

IP unlockA token on a timerA well-known address
How it gets on You press the button and the panel unlocks whatever address it sees you arriving from. A machine calls the endpoint with its token, and the address that call arrived from goes on. An administrator types the address in, with a name for it.
Whose it is Your account's, one at a time — unlocking from somewhere new replaces it. The token's, one at a time — a new address replaces the one it held. Nobody's. It belongs to the box.
When it goes away When you unlock from elsewhere, or when the account is deleted. When the token opens a different address, when it is revoked, or when the account is deleted. Only when somebody presses Remove. Deleting the administrator who added it changes nothing.
Who can do it Any account that can sign in, including an unlock-only one. Any account at all — every role can hold a token. Administrators only.

If you are a site owner the page is not in your menu at all, so this is something to ask for rather than do: give your administrator the address and a name for it. The name is for people — it is never matched against anything and never appears outside the panel — so make it something still recognisable in six months. Office (Budapest) and Ops VPN exit earn their place; temp does not.

One address, never a range

203.0.113.7 is accepted, and so is an IPv6 address. 203.0.113.0/24 is not — the field refuses a range, and refuses anything that is not a valid address, before the entry is saved. A whole network has to go on one address per row.

An address already on the list is refused too, including when it is written differently: 2001:DB8::1 and 2001:db8::1 are one address as far as the panel is concerned.

An administrator reading that page finds a third card below the other two: the addresses tokens have opened, each with its label, the token that opened it, the account that holds the token, and when that token last called. It stands apart from the other two because these rows change with nobody in the panel doing anything — a machine on a timer rewrites them.

Removing a token's address does not revoke the token

The row comes off the list, and the token opens an address again on its very next call. If the point is to keep that machine out, revoke the token — and only the account holding it can do that, from its own API tokens page.

Who can see what in the panel

Three kinds of account sign in, and they get three different panels. Which one you have decides what is in the menu and, more surprisingly, which sites exist as far as you are concerned.

Site owner
The sites list holds your sites and no others. On any of them you can do everything this guide describes — publish and unpublish, restart or recreate the container, change the image, edit the .env, create and drop the database, turn deployments on, lock the site or a folder of it, restore a backup or download a copy of one, and delete it. There is no reduced tier: a site is yours, with the full run of it, or it is not there.
Administrator
Every site on the box, plus the pages that belong to the box rather than to a site — routes, Site Images, panel accounts, unlocked addresses, backups and settings. Uploading a site image of your own is one of those (chapter 03.1). Handing a site to a site owner happens here.
Unlock only
The IP unlock page and the account page behind it. No site list, no settings, and no view of whose addresses are unlocked. Managing sites is done by your operator.

One thing does not vary by role: every account can hold an API token and unlock its own address with it. Your accountAPI tokens sits outside the administrator area for that reason, and an unlock-only account gets exactly the same page as an administrator does.

A site you cannot see reads as one that never existed

Opening the address of somebody else's site does not refuse you — it says the site is not there. Nothing is greyed out or marked private, because the panel will not confirm a site exists to an account that has no claim on it.

The practical consequence: "gone" and "not yours" are the same page. Before concluding a site was deleted, check which account you are signed in as.

You cannot change who owns a site, including one of your own — only an administrator can move it, and there is no control for it on your side. Nothing about a site changes when it moves: same container, same domain, same certificate, same folder. Only who can see it.

The IP gate is the same gate whichever account you hold. A site owner meets exactly the blank 403 described above, on their own site, and gets past it exactly the way this chapter describes — the lock is a rule at the edge, and the edge does not know your role. It is the first thing a new owner runs into, and it looks like a permissions problem when it is a network one.

If you land on a 403 inside the panel itself, the page always offers a way out: a link to IP unlock and a sign-out button. You should never need to clear cookies to escape. A locked site never offers that link — the bare 403 in the table above comes from the proxy, which has nothing to offer. The way back is the panel's own domain, as described above.

How a new account gets its password

Only an administrator creates accounts, and the New user form offers two ways to give one a password. Both are always on the form; neither is a mode you put the panel into.

Type a password
You choose it and pass it on yourself. Nothing about this has changed, and it is still the right answer when the person is sitting next to you.
Send an invitation
The panel emails a link, the person chooses their own password, and you never see it.
An invited account cannot sign in until the link is used

The account appears in the users list straight away and looks ready. It is not. Until a password is set, signing in as it fails exactly the way a wrong password does — the sign-in form deliberately will not reveal that an account is waiting for its invitation, so watching somebody try tells you nothing. The users list is where the state is shown.

That state is the Sign-in column, and it has four answers:

Active
A password is set. The account can sign in.
Invited
A link is outstanding, with the date it went out.
Invitation expired
Nobody used it in time. A link lasts 7 days by default.
Invitation not sent
The mail service refused the message outright. This is the one mail failure the panel knows about, and it offers a re-send on the spot.

A link is single-use. Re-sending issues a new one and the previous one stops working immediately, which is the answer both to "they never got it" and to "I sent it to the wrong address". Withdraw kills the outstanding link as well, and it is worth being clear about what it leaves behind: the account stays, and stays unusable, until somebody sends another invitation or types a password into its edit form. Typing a password there withdraws any outstanding invitation — so an administrator who runs out of patience has quietly cancelled the link they sent.

On its way is not arrived

The panel hands the message to a mail service and hears nothing back: no bounce, no read receipt, no delivery status. It can say an invitation is on its way and can never say it was received. If the person does not have it, re-send; there is nothing in the panel to check. Invitation not sent above is the different case — the mail service refusing the message rather than silence after accepting it.

The page the link opens asks for a password and a confirmation, with a twelve-character minimum, and then signs the person in and lands them on their own home. It names no account and no email address, and a link that is refused says only that it has expired or is not valid: a link can be forwarded, and the panel will not confirm to a stranger that an address exists on this server.

That page sits outside the gated part of the panel, so the link works from any address. It has to — the recipient has never been to this server and could not be on the unlocked list yet. The email says as much: under the invitation it points at the panel's own /unlock address and at the unlock walkthrough, because letting your own address in is often the first thing a new account needs to do.

Invitations need a mail transport; typing a password never does

Sending mail needs a credential in the server's .envNIMBUS_NOTIFICATION_TOKEN — and only your operator can put it there. Until it exists the invitation option is still shown on the form but disabled, with the reason beside it. Nothing else about creating an account changes. It is the same credential that sends the failed-backup notice in chapter 09.

What every account can read: System information

One page in the panel is not divided by role. System information is in the panel's menu, and on the panel's front page as a second button once your address is unlocked. Any signed-in account can open it, including an unlock-only one. It is read-only and carries no passwords.

General
The link to phpMyAdmin. If none has been set up on the box, the page says so instead of linking nowhere.
Technical
Under Platform, the panel's own version number — the thing to quote when you report a problem, and the first thing anybody looking into one will ask you for. Then the addresses and paths your site or stack needs: the MySQL and Redis hosts — listed separately for sites and for stacks, because they differ (chapter 06) — where site and stack folders live, and which certificate authority this box issues from. Everything on it is something you can act on; rows that were only ever trivia have been taken off.

It exists so you can stop guessing. Anything on it is a fact about this particular box, which is exactly the sort of thing a guide cannot tell you.

If it still refuses you

  • Check the address actually changed. The unlock page shows what the panel sees. If that does not match what you expect, something between you and the box — a VPN or corporate proxy — is rewriting it.
  • Check you are hitting the right site. A 403 from phpMyAdmin and a 403 from your own site look identical.
  • If the panel warns that the change was saved but not enforced, the proxy did not accept it. The API says the same thing as "enforced": false. Repeat it once; if it stays that way it is an operator problem, not yours — report it rather than retrying indefinitely.
  • If you cannot reach the panel at all, because the address it sees is not unlocked, a token is the way in — provided you made one earlier. That is the argument for issuing one on the day you get your account rather than on the day you are locked out.