Skip to content

How to Protect Your App Servers with Sunray Zero Trust

Who this page is for. Setting Sunray up touches the Traefik server, the Traefik Application Definitions and the Manganese instance's own settings — screens a Manganese tenant does not see. If you are the tenant of an App Server and want to know who can reach it and what you control, read Protect Your App Server with Sunray Zero Trust instead.

The chain

Visitor → Traefik router  ──ForwardAuth──→  Sunray Server
                                                │
                                                │ polls, Bearer token
                                                ▼
                                       Manganese  /inouk-scp/v1

Traefik matches the requested host name, then asks Sunray whether this visitor may pass. Sunray answers from a configuration it polls off the Muppy server acting as your Manganese instance: the list of protected host names, who is allowed on each, and which addresses pass without being asked.

That list is derived, never typed. Muppy publishes one entry per name served by an application carrying the Sunray ForwardAuth middleware — the application's own FQDN and its Custom Domain (CNAME) when it has one. Only active applications are published: a deactivated one leaves the list, which is how a protected host is withdrawn.

When a change takes effect

Sunray reads the SCP on its own schedule — the Auto-Register: Sync all SCPs scheduled action on the Sunray Server, every 5 minutes by default. Everything follows from that one poll:

  • a name that appears in the response becomes a protected host;
  • a name that leaves it — its application deactivated, its Definition detached, its Custom Domain cleared — has its host deactivated, with the users it carried named in the Sunray log;
  • an edited Allowed CIDRs list is applied.

So every change made in Muppy is one synchronisation away, and testing sooner measures the previous state. Press Sync Now on the Configuration Proxy to read the endpoint immediately instead of waiting.

Setup checklist

Do these in order. Steps 1 to 4 make Traefik ask; steps 5 and 6 let Sunray answer.

1. A reachable Sunray Server. Note the URL of its verify endpoint, for example http://sunray.example.com:9091/api/verify.

2. The Traefik server's defaults. On the Traefik Server record, set Default ForwardAuth Middleware to Sunray and Default ForwardAuth URL to that endpoint. Every application that activates ForwardAuth inherits both, so a wrong value here is wrong everywhere at once.

3. The Traefik Application Definition. Tick Activate ForwardAuth on each Definition whose applications must be guarded. This is the switch: an application generated by a Definition without it is served in the open.

4. Attach and reconfigure. Attach the Definition to the App Definition or the App Server, then reconfigure the reverse proxy. Until that runs, the middleware exists in Muppy and not in Traefik.

5. Verify what Muppy publishes. On your Muppy server acting as Manganese instance, open Settings ▸ Sunray and tick Show credentials. The Test Command field hands you a ready-made curl, already carrying the configured token — if the Bearer Token box is empty, mint one first (step 6). Run it and read the answer:

{
    "version": "1.0.0",
    "protected_hosts": [
        {"fqdn": "myapp-main-prod-acme.acme.muppy.cloud", "rules": [], "allowed_users": ["ops@acme.example"]},
        {"fqdn": "erp.acme.com", "rules": [], "allowed_users": ["ops@acme.example"]}
    ],
    "users": [{"username": "Ops", "email": "ops@acme.example", "active": true}]
}

Every name you expect to be guarded must appear. A name that is missing is a name served in the open.

6. The shared token. On the same screen, press Generate Token and save. It is a shared secret: every Sunray Server reading this instance holds the same value. Allowed CIDRs on that screen is the instance-wide list, applied to the Manganese backoffice itself.

7. Declare Muppy on the Sunray Server. Go to your Sunray Server and configure your Muppy server as a Configuration Proxy, under Protected Systems ▸ Configuration Proxies. The two fields that matter are the endpoint URL — https://<your-muppy-server>/inouk-scp/v1/ — and the Bearer Token from step 6:

A Configuration Proxy on the Sunray Server: the Muppy SCP URL and its Bearer Token

FQDN Regex Pattern narrows which of the published names this proxy takes. Sync Now reads the endpoint immediately rather than waiting for the next cycle, and the Managed Hosts tab then lists what came back, each row carrying its Last SCP Sync.

Rotating the token

Generate Token mints a token into an empty box only. It refuses while one is set, and that refusal is deliberate: writing a new token over a live one locks out every Sunray Server polling this instance, and they find out by starting to get 401s with nothing on their side saying why.

To rotate on purpose:

  1. Clear the Bearer Token box and save.
  2. Press Generate Token.
  3. Carry the new token to each Sunray Server.

Between steps 2 and 3, the Sunray Servers are working from the configuration they last read. Keep the window short.

What each side controls

Control Where Effect
Activate ForwardAuth Traefik Application Definition whether the application is guarded at all
Default ForwardAuth Middleware / URL Traefik Server which Sunray answers, for every application of that server
Bearer Token, Allowed CIDRs Manganese ▸ Settings ▸ Sunray the poll, and the backoffice's own bypass list
the Configuration Proxy: URL, Bearer Token, FQDN Regex Pattern Sunray Server ▸ Protected Systems ▸ Configuration Proxies which Muppy instance this Sunray reads, and which of its names it takes
Sunray Allowed CIDRs each App Server, Access tab that server's bypass list — the tenant's control
Owner, the admin role each App Server, and Manganese users who may sign in

Troubleshooting

Symptom Where to look
a name is missing from /inouk-scp/v1 its application is inactive, or its Definition has no Activate ForwardAuth, or the reverse proxy was not reconfigured
the whole answer is 401 no Bearer token on the request, or none configured on the instance
the whole answer is 403 the Sunray Server is presenting a token that no longer matches — see Rotating the token
400 protected_host_fqdn not found for one name no active guarded application serves it; check the name's spelling and the application's Custom Domain
a Custom Domain is refused while the Muppy name works the application serving it has not been reconfigured since the name was set
an edited CIDR list has no effect Sunray applies it at its next synchronisation — see When a change takes effect

Names are matched leniently

A name is looked up in lower case and a trailing dot is ignored, so a Custom Domain typed ERP.Acme.com. resolves to the same application as erp.acme.com.