This guide is a work in progress. A full step-by-step guide with screenshots is coming. Stuck? Contact support.
1. REST blocked with 403 "Forbidden Access" page (seen on suweb.ai and both test sites, same host).
Fix: add a WAF exception for the path /wp-json/ (no full URL needed). Requests still require an app password.
Alternative: allow the bot's IP (may change over time). Last resort: turn the WAF off.
2. HTTP DELETE blocked by host. Bridge supports ?_method=DELETE as a workaround.
---
## SUWEB licensing system (added 2026-10-26, v0.1 built offline)
Store side (the site that runs suweb-license-server):
- REST must be reachable at /wp-json/suweb-license/v1/* (POST activate/deactivate/check, GET/POST update-info, GET download). Security plugins that disable REST for anonymous users (Wordfence "disable REST", iThemes/Solid, Perfmatters, some WAF rules) must allow-list this namespace.
- Never cache these routes (Cloudflare/LiteSpeed/Varnish/host page cache). Responses send Cache-Control: no-store but add a bypass rule for /wp-json/suweb-license/*, or replay protection breaks (stale nonce = rejected by client).
- Rate limiting relies on the real client IP. Behind Cloudflare/a proxy, REMOTE_ADDR is the proxy; map the trusted header (e.g. CF-Connecting-IP) via the sls_client_ip filter, otherwise all customers share one bucket and hit 429. Use a persistent object cache (Redis) so transient counters are reliable.
- Bot-fight / JS challenges (Cloudflare Bot Fight Mode, Sucuri, Imunify360) will block server-to-server calls from customer sites (no browser). Skip challenges for the namespace.
- Zip storage: keep product zips outside the web root (default ../sls-private). On hosts that forbid writes above ABSPATH it falls back to uploads/sls-private-xxxx with .htaccess deny; on nginx hosts add location ~ /sls-private- { deny all; }. X-Sendfile optional via sls_use_xsendfile.
- HTTPS required by default (setting require_https). Ensure is_ssl() is true behind a proxy (set $_SERVER['HTTPS']='on' when X-Forwarded-Proto: https).
- Pin secrets in wp-config.php (SLS_SIGN_SECRET_KEY, SLS_HMAC_SECRET, SLS_ENC_SECRET) so a DB restore/clone can't lose or leak the signing key. Losing the signing key = every client rejects the server until a plugin update ships a new public key.
Client side (customer sites):
- Customer hosts that block outbound HTTP (some managed/enterprise hosts, WP_HTTP_BLOCK_EXTERNAL) need suweb.ai in WP_ACCESSIBLE_HOSTS. Plugins keep working regardless; only updates stop.
- Downloads use WP's download_url() (safe-URL rules: ports 80/443/8080, public hosts). Fine for a public HTTPS store.
- 2026-10-26: no new WAF/Defender/Hummingbird blocks during build. Note: Hummingbird page cache served stale pages (x-cache HIT) right after edits; /cache/clear plus a query string was needed to verify.
