Domain Allowlists
Configure project-level image source domains and authorized websites to control which images can be processed and who can use your service.
OptStuff provides two layers of domain allowlists at the project level, each serving a different purpose.
Two-Layer Architecture
| Layer | Question | Validation | Configured In |
|---|---|---|---|
Authorized Websites (allowedRefererDomains) | WHO can use this service? | HTTP Referer header | Project Settings |
Image Sources (allowedSourceDomains) | WHAT image sources can be processed? | Image URL in request | Project Settings |
Both layers are configured in the project's Settings tab under Domain Security.
Configuring Image Sources (Project Level)
- Navigate to Dashboard → Project → Settings
- In Image Sources, add the domains where your images are hosted
- Use protocol-prefixed entries (for example
https://images.example.com) - Subdomain matching: adding
https://example.comallowsexample.comand all subdomains (cdn.example.com,img.example.com, ...)
| List Status | Production Behavior | Development Behavior |
|---|---|---|
| Empty (default) | Reject all requests (fail closed) | Allow all sources (for convenience) |
| Non-empty | Only listed domains allowed | Only listed domains allowed |
Important: Always configure at least one image source domain before using OptStuff in production. In production, an empty source list rejects all requests.
Configuring Authorized Websites (Project Level)
- Navigate to Dashboard → Project → Settings
- In Authorized Websites, add your website domains
- Use protocol-prefixed entries (for example
https://app.example.com) - Subdomains are not implied for exact host entries; use wildcard when needed:
https://app.example.com→ only this hosthttps://*.example.com→ all subdomains (andexample.com)
| List Status | Behavior |
|---|---|
| Empty (default) | All referers allowed |
| Non-empty | Only listed domains allowed |
Note:
allowedRefererDomainsis a best-effort browser-side signal enforced byvalidateReferer()for hotlinking protection, not a strong authentication guarantee. WhenallowedRefererDomainsis non-empty, OptStuff blocks requests with a missing or non-matchingReferer. Keep this list empty for server-to-server usage, privacy-stripping clients, or health checks that cannot send a browser referer. See Referer Security Model for details.
Wildcard Syntax
Wildcard entries use the *. prefix to match subdomains in Authorized Websites. Image Sources do not accept wildcard entries because a normal source entry already covers the host and its subdomains.
| Entry | Matches | Does NOT Match |
|---|---|---|
https://example.com in Image Sources | example.com and all subdomains, such as cdn.example.com | other-site.com |
https://example.com in Authorized Websites | example.com only | app.example.com |
https://*.example.com in Authorized Websites | example.com and subdomains, such as app.example.com | other-site.com |
https://*.example.com in Image Sources | Not accepted | Use https://example.com instead |
Wildcard semantics differ by scope: for Image Sources, https://example.com includes subdomains automatically (for example, it allows https://cdn.example.com/photo.jpg); for Authorized Websites, subdomains are not implied, so use https://*.example.com when you need to allow referers like https://app.example.com/page.
Practical Example
Project: my-company
allowedSourceDomains: [https://cdn.site-a.com, https://images.site-b.com, https://s3.amazonaws.com]
allowedRefererDomains: [https://app.site-a.com, https://*.site-b.com]All API keys in this project share the same domain restrictions. Different keys are used for credential rotation and access control — not for domain segmentation.
Environment-Specific Configuration
| Environment | Image Sources | Authorized Websites |
|---|---|---|
| Development | Empty list (allows all sources for convenience) | Empty list (allows all) |
| Staging | Same as production | Add your staging domain (https://staging.example.com) |
| Production | Explicitly list all allowed origins | Explicitly list all allowed websites |
In production, an empty allowedSourceDomains list rejects all requests (fail-closed). Always add at least one domain before going live.
Troubleshooting
| Error | Common Cause | Solution |
|---|---|---|
403 Source domain not allowed | Image origin not in project's allowed sources | Add the domain (with https:// prefix) in Dashboard → Settings → Domain Security → Image Sources |
403 Invalid referer | Your website not in allowed referer list | Add your domain in Dashboard → Settings → Domain Security → Authorized Websites |
403 on images that formerly worked | Domain settings changed or cache propagation delay | Wait ~60s for settings to propagate; verify domains are still listed |
| Images work in development but not production | Empty source list allows all in dev, rejects all in prod | Add explicit domains for production |
Common Mistakes
- Missing protocol — Entries must include
http://orhttps://(for example,https://cdn.example.com, notcdn.example.com) - Trailing slashes — Do not include trailing slashes (use
https://cdn.example.com, nothttps://cdn.example.com/) - Port numbers — Include a port only when the incoming request's
Refererwill include that same port (for example,http://localhost:3000for local development).
Related Documentation
- Core Concepts — Overview of the resource hierarchy
- Referer Security Model — Trust model and trade-offs for Referer-based protection
- Security Best Practices — Broader security recommendations
- Error Codes —
403errors for domain violations
Last updated on
CDN and Caching
How to use OptStuff with a CDN for edge-cached image delivery — cache behavior, CDN setup guides for Cloudflare, Vercel, and CloudFront, and cache invalidation strategies.
Referer Security Model
Why the browser Referer header helps with anti-hotlinking, why it is not a substitute for authentication, and how OptStuff enforces it alongside signed URLs.