Redirects, basic auth and security rules
Redirect paths, put a password on a site or a folder, rate-limit clients and block IPs, countries or bots, all enforced at the edge and applied instantly without a redeploy.
Route rules are checks the edge (OpenResty on ports 80 and 443) runs on every request before it reaches your app. Because the edge turns a request away itself, a blocked or rate-limited visitor costs your app nothing, and you don't have to change or redeploy any code. Saving a rule pushes it to the edge immediately.
A rule can do any mix of:
- redirect a path or a pattern to another path or URL (
301,302,307or308); - basic auth: ask for a username and password;
- rate limit each client IP;
- allow only some HTTP methods or countries, deny IP ranges, ban IPs, countries or user agents;
- hotlink protection: only serve requests whose
Refereris one of your sites.
Where this lives
In a project's menu, Redirects shows only the redirect fields and the rules that redirect; Security shows basic auth, rate limits and the IP, country and user-agent fields and the rules that use them. The same editor, with every field, is the collapsed Route rules card at the bottom of the project's Domains & Routes tab. The entries are shown for projects that run on your own servers.
Add a rule
Open Redirects or Security
Open the project and choose Redirects or Security. Existing rules are listed first: the path they
cover (All paths when there's no prefix), All hostnames, and a one-line summary such as
20/s +40 · ban 2 · auth admin.
Fill in the Add a rule form
Every field is optional; fill in only what you need. Path prefix (optional) limits the rule to one part of
the site, for example /api or /admin. Leave it empty for the whole site. The prefix is a plain text
match, so /admin also covers /administrator and /admin-old.
Save
Press Add rule. "Rule saved" means the edge already enforces it. Use the Enabled / Disabled button on a rule to switch it off and on, and Remove to delete it.
Rules can't be edited in place
The panel lists rules with Enabled / Disabled and Remove. To change a rule, add the new version and
remove the old one. (The API's PATCH /api/projects/{id}/route-rules/{ruleId} can update a rule in place.)
Redirects
Under Redirect:
| Field | What to enter |
|---|---|
| Match | Path prefix or Regex. |
| Status | 301 (permanent, the default), 302, 307 or 308. |
| From | The path to match: /old-blog for a prefix, or a regular expression such as ^/posts/(\d+)$. |
| To (URL or path) | A path starting with / or a full http:// or https:// URL. |
How they behave:
- Path prefix matches on whole path segments:
/oldmatches/oldand/old/post, but not/older. The rest of the path is appended, so/old-blog→/blogsends/old-blog/2024/helloto/blog/2024/hello. - Regex matches the path (without the query string). Use
$1to$9in To for capture groups:^/posts/(\d+)$→/blog/$1. - The query string is kept, unless To already contains a
?. - The redirect is answered at the edge before the request reaches your app.
Examples:
| Match | From | To | Result |
|---|---|---|---|
| Path prefix | /docs | https://docs.example.com | /docs/install?v=2 → https://docs.example.com/install?v=2 |
| Path prefix | /old-blog | /blog | /old-blog/hello → /blog/hello |
| Regex | ^/p/(\d+)$ | /products/$1 | /p/42 → /products/42 |
Limits: a rule holds at most 50 redirects (the panel adds one per rule). A prefix redirect whose relative
destination lies inside its own source (for example /a → /a/b) is refused because it would loop, and so is
a $1 in a prefix redirect. 303 isn't offered, because it changes the request method.
To send a whole domain to another one (for example www to the bare domain), use the domain's Redirect
setting instead; see Redirect one domain to another.
Basic auth
Under Basic auth on the Security page, enter a Username and a Password. Visitors then get the
browser's sign-in prompt, and requests without the right credentials receive 401.
- Put
/adminin Path prefix to protect only that part of the site, or leave it empty to protect everything. - The username can be 1 to 64 characters without
:; the password up to 128 characters. - The password is hashed by the API and never shown again ("The password is stored hashed and can't be shown again."). To change it, add a new rule and remove the old one.
- Enter both fields or neither: the form says "Enter both a username and a password" otherwise.
- Basic auth also applies to API calls and webhooks sent to the protected paths. Leave those paths out, or
your integrations will get
401.
Use HTTPS
Basic auth sends the password with every request, only encoded, not encrypted. Make sure the domain has an active certificate so the redirect to HTTPS is on (see HTTPS redirect).
Rate limits and access control
The remaining Security fields:
| Field | What it does |
|---|---|
| Requests / sec and Burst | Each client IP may make Requests / sec plus Burst requests in any one second on the rule's paths. Over that, the edge answers 429 with Retry-After: 1. |
| Allow only methods | For example GET, POST. Other methods are blocked. |
| Ban IPs / CIDRs | Single addresses or ranges, for example 203.0.113.7, 10.0.0.0/8. |
| Ban countries (ISO) | Two-letter country codes, for example RU, CN. |
| Allow only countries (ISO) | Only these countries get through, for example US, CA, GB. |
| Deny CIDRs | Ranges to refuse, for example 203.0.113.0/24. |
| Hotlink: allow referers | Hostnames allowed to embed or link your files, for example example.com. Requests with another Referer are blocked; requests with no Referer are allowed. |
| Ban user-agents (substring) | Blocks clients whose User-Agent contains one of these, for example curl, python-requests. Separate entries with commas. |
| Block empty user-agent | Blocks requests that send no User-Agent. |
| Block response code | What blocked requests receive: 403 (default), 404, 429, 444 (close the connection), 451 or 503. |
Examples:
- Slow down brute force on a login page: Path prefix
/login, Requests / sec5, Burst5. - Private staging site: no path prefix, Allow only countries
DE, plus basic auth. - Keep scrapers off an API: Path prefix
/api, Ban user-agentspython-requests, scrapy, Block empty user-agent on.
How rules combine
For each request the edge picks one rule for access control: the enabled rule whose Path prefix is the longest match for the request path (a rule without a prefix is the fallback for everything else). That rule's checks run in this order: allowed methods, denied and allowed ranges, allowed countries, bans, hotlink, rate limit. The first check that fails blocks the request.
Basic auth and redirects are different: they look at every rule whose prefix matches. The most specific
basic auth applies, and the first matching redirect of the most specific rule wins. So a site-wide password
still covers /api even if /api has its own rate-limit rule.
This means a rule for /api replaces a site-wide rate limit or ban for requests under /api. Repeat the
settings you want to keep in the more specific rule.
Known limits
- Rules added in the panel apply to all hostnames of the project. To scope a rule to one domain, use the
CLI's
--domainoption or the API. The panel still labels such a rule All hostnames. - Rule path prefixes (for rate limits, access lists, bans and basic auth) match as plain text:
/apialso covers/api-docs. A trailing slash (/api/) keeps a rule inside one folder, but then no longer covers/apiitself. Redirect sources are different: they match whole path segments. - Both Ban countries and Allow only countries block visitors whose country can't be determined. Countries come from the GeoLite2 database built into the edge; if the project's Monitoring tab says "Country data unavailable on this edge", either rule blocks everyone.
- Rules need the Synq edge in front of the app. Projects on Synq Cloud don't have them.
- IP-based checks use the visitor's real address only if the edge can see it. Behind Cloudflare's proxy this
works automatically (the edge trusts Cloudflare's published ranges and reads
CF-Connecting-IP). Behind another proxy or a load balancer, every visitor looks like the proxy and shares one rate-limit bucket.SYNQ_EDGE_TRUSTED_PROXIESandSYNQ_EDGE_REAL_IP_HEADERonly apply to an edge installed directly on a server; the edge container of a standard (Docker Compose) install has its real-IP settings built in and ignores them. See Real visitor IPs.
From the CLI
synq edge rules manages the same rules. The CLI covers rate limits, bans and access lists; redirects and basic
auth are set in the panel or through the API.
# 20 requests/second per client IP on the login path, allowing bursts
synq edge rules add -p <projectId> --path /login --rate-limit 20 --burst 40
# Block two countries and one IP, answering 403
synq edge rules add -p <projectId> --ban-country RU,CN --ban-ip 203.0.113.7 --block-status 403
# Only let an office network in (everyone else is denied)
synq edge rules add -p <projectId> --allow-cidr 198.51.100.0/24
# Scope a rule to one domain of the project
synq edge rules add -p <projectId> --domain <domainId> --rate-limit 50
synq edge rules list -p <projectId>
synq edge rules rm <ruleId> -p <projectId>See the synq edge rules reference for every option.
A server-wide limit too
Each server also has one rate limit for everything it serves, under Servers → your server → Security. Route rules are the finer-grained, per-project tool. See Servers.
Related
HTTPS and certificates
How Synq gets free Let's Encrypt certificates over HTTP-01 without Cloudflare, issues wildcard certificates through a DNS provider, installs your own certificate, redirects HTTP to HTTPS, and renews everything.
Custom proxy config
Add your own OpenResty directives to one domain, who may do it, what is refused, and how Synq tests the config and rolls it back if the edge rejects it.