Skip to main content
In ShieldLabs you separate development from production the same way you separate any other configuration: with separate domains and separate key sets, plus the matching snippet host. The API shape is identical in every environment. A webhook from a development domain and a webhook from a production domain carry the same fields, the same request_id join key, and the same Risk Score (0-100) with its signals. Nothing about the integration changes between environments except the credentials and the host you load.

Two things change per environment

The domain and its key set

Register a separate domain for each environment (for example dev.example.com and example.com). Each domain gets its own public key, secret key, webhook endpoints, and request balance.

The snippet host

Production loads the snippet from cdn.shieldlabs.ai. Development loads it from dev.cdn.shieldlabs.ai. Same module, same exports, same call pattern.

Snippet hosts

The only host that differs in your page code is the CDN that serves the module. Both serve the same ES module with the same checkAnonymous, checkAuthenticatedUser, and forceCheck* exports that Install the snippet covers for the full client setup.

Use a separate domain and key set per environment

Register each environment as its own domain in app.shieldlabs.ai. Every domain you add gets an independent public key, secret key, webhook endpoints, and request balance. Keeping them separate buys you:
  • Clean data. Development traffic never lands in your production dashboard, so your visitor counts, traffic sources, and patterns reflect real users only.
  • Isolated webhooks. Each domain registers its own webhook endpoints, so test deliveries hit your local handler and never your production endpoint.
  • Independent balances. Test runs draw down the development domain’s request balance, not your paid production balance. Billing is per request.
  • Blast-radius control. A leaked development secret cannot call the Server API for your production domain. Keys are scoped to a single domain. Webhook whsec_… secrets are scoped per endpoint.
Do not reuse one key set across environments. The public key is bound to the domain it is served from (resolved from the Origin, Referer, or Host), so a production key on dev.example.com will be rejected with a 401. And a single secret shared across environments means a development leak compromises production.

Wire the host and keys through config

Load the host and public key from environment config instead of hardcoding them, so the same build runs in both environments. Keep the Private API Key (for History API reads) and the secret key (for the Management API) server-side only, and store each webhook whsec_… for signature verification. None of them must reach the browser.
A framework component then reads the host and public key from config and loads the module the same way in every environment:
ShieldLabsTracker.jsx
Your strict Content-Security-Policy must allow whichever snippet host that environment uses. A development build pointed at dev.cdn.shieldlabs.ai needs that origin in script-src, not cdn.shieldlabs.ai. Keep the jsDelivr dependency host cdn.jsdelivr.net in script-src in both environments, and the connect-src endpoints (rest.shieldlabs.ai, webrtc.shieldlabs.ai, stun:ice.shieldlabs.ai:3478) stay the same in both. A very strict connect-src may skip the local-network check; the main snapshot and the Risk Score are unaffected.

Receiving webhooks in development

Your development webhook needs a publicly reachable URL. Run a tunnel to your local server and register it as an endpoint on the development domain’s Webhooks tab:
Add https://abc123.ngrok.app/webhooks/shieldlabs as an endpoint in the dashboard, copy that endpoint’s whsec_… secret into SHIELDLABS_WEBHOOK_SECRET, and verify X-Shield-Signature exactly as you will in production. The Webhooks guide carries the verification logic, the single webhook per scored identification (the server waits up to ~60s for follow-up checks, then sends the final score once), and the at-most-once delivery caveat.
Webhooks are at-most-once with no retries, so a tunnel that is down means a missed delivery. When your local handler is offline, read results back with the History API using that domain’s Private API Key. Make handlers idempotent on request_id either way.

Test with real traffic before production

Risk Scores reflect the actual connection and browser environment of whoever loads the page, so the most useful test is real traffic on a real development domain, not synthetic requests.
1

Deploy the snippet on a development domain

Register dev.example.com, drop the dev.cdn.shieldlabs.ai snippet onto a staging or preview deployment, and let real visits flow through it.
2

Watch the data land

Confirm visits appear under your development domain in the dashboard and that webhooks reach your tunnel. Check the signals array to see which signals fired and why.
3

Tune your thresholds against the bands

Decide what your code does at each band (Clean 0-9, Low 10-29, Medium 30-59, High 60-100) and verify the behavior on this real traffic, the way acting on the Risk Score lays out.
4

Promote to production

Swap the host to cdn.shieldlabs.ai and the keys to the production domain’s key set through config. Nothing else in your code changes.
A legitimate visitor can score high (a corporate proxy, a VPN, a privacy browser). Testing with real traffic on a development domain is the best way to see that distribution before you wire scores into a decision your application acts on. Decide on Score plus signals plus context, and tune thresholds gradually.

Promotion checklist

Switch the import URL from dev.cdn.shieldlabs.ai to cdn.shieldlabs.ai, or flip the SHIELDLABS_SNIPPET_HOST config value.
Use the production domain’s public key in the snippet URL.
Register production webhook endpoints in the dashboard Webhooks tab, not your development tunnel.
Load the production Secret Key on your server for Server API auth. It must never reach the browser.
Copy each production endpoint’s whsec_… into your server environment for webhook verification.
Confirm your production Content-Security-Policy allows cdn.shieldlabs.ai in script-src.

Next steps

Public and Secret Keys

Where each key lives and why the secret never ships to the browser.

Domains

Register a domain per environment and manage its webhook endpoints.

Webhooks

Verify X-Shield-Signature and handle the single scored webhook per identification.

Acting on the Risk Score

Turn the bands into allow, challenge, review, or block in your own code.