Production integration
Connect Remnawave to NODIF safely.
Use a narrow ordered response rule for the NODIF-compatible body and an External Squad for the provider-specific signed-brand pointer. This avoids global tokens and cross-tenant branding.
Trust model
A subscription response may carry only two NODIF pointer headers:
X-NODIF-Provider-ID: <public-provider-slug>
X-NODIF-Branding-Token: <opaque-branding-token>The first value is the public slug, such as example-vpn—never the internal tenant UUID. NODIF uses the pair against its fixed control origin, validates an Ed25519 signature and expiry, then accepts only an allowlisted branding schema. A subscription cannot choose a control host or inject HTML, CSS, scripts, fonts, arbitrary images or deep links.
Prerequisites and backup
- NODIF-approved provider profile, public slug and branding token.
- NODIF-issued current User-Agent match value and approved response type.
- A staging or restricted External Squad with dedicated test users.
- Export of current ordered response rules and External Squad configuration.
- Current Remnawave database backup and tested rollback owner.
- Reverse proxy/CDN owners available to verify custom-header preservation and cache behavior.
Remnawave evolves. Validate field names against the installed v3 build before applying an API payload; do not copy a moving upstream example into production without a staging check.
1. Add the ordered NODIF response rule
Remnawave evaluates rules top-to-bottom and stops on the first match. Put the narrow NODIF rule above generic client rules and leave a deliberate fallback last. An empty condition list can match every request and must not be used.
{
"name": "NODIF client",
"description": "Serve the approved NODIF-compatible subscription body",
"enabled": true,
"operator": "AND",
"conditions": [
{
"headerName": "user-agent",
"operator": "CONTAINS",
"value": "<nodif-user-agent-match-issued-during-onboarding>",
"caseSensitive": false
}
],
"responseType": "XRAY_JSON"
}If onboarding supplies an exact prefix, use STARTS_WITH instead of broadening the substring. Do not duplicate provider-specific NODIF headers in the response rule on a multi-provider panel. Matching the app identifies the client, not the tenant.
2. Scope headers with an External Squad
Assign only this provider’s users to the squad. Apply the following v3-shaped fragment through the authenticated Remnawave UI/API. Preserve unrelated existing fields.
{
"uuid": "<external-squad-uuid>",
"responseHeadersAdd": {
"X-NODIF-Provider-ID": "<public-provider-slug>",
"X-NODIF-Branding-Token": "<opaque-branding-token>",
"X-NODIF-Subscription-Status": "{{STATUS:ACTIVE=active|EXPIRED=expired|LIMITED=limited|DISABLED=disabled}}",
"profile-title": "rwEncodeBase64:<provider-display-name>",
"profile-update-interval": "12",
"support-url": "https://provider.example/support",
"profile-web-page-url": "https://provider.example/account",
"announce": "rwEncodeBase64:<short-provider-announcement>"
},
"responseHeadersRemove": [
"X-UMMA-Provider-ID",
"X-UMMA-Branding-Token"
]
}responseHeadersAdd is an object; responseHeadersRemove is an array. They replace the old v2 responseHeaders property. The X-UMMA-* names above are removal targets only and must not be added in a new setup.
Supported standard metadata
| Header | Guidance | Acceptance boundary |
|---|---|---|
profile-title | Configure rwEncodeBase64: plain text. | Keep the decoded name at or below 48 characters. |
profile-update-interval | Integer hours. | 1–168. |
announce | Base64 text through Remnawave. | Use at most 240 plain characters; no secrets or markup. |
support-url | Generic HTTPS support page. | DNS hostname, no userinfo, fragment, token or nonstandard explicit port. |
profile-web-page-url | Generic account/subscription information page. | Same safe URL rules as support. |
subscription-userinfo | Let Remnawave generate bounded numeric upload/download/total/expire data. | Do not hand-build user data into other headers. |
x-hwid-active | Generated by Remnawave when enforcement is enabled. | Do not forge. |
Generic Remnawave remarks
Configure all arrays expected by the installed v3 schema. Keep remarks generic and put actionable links in the approved NODIF profile.
{
"customRemarks": {
"expiredUsers": ["Subscription expired. Open the provider account page."],
"limitedUsers": ["Traffic limit reached. Open the provider account page."],
"disabledUsers": ["Subscription unavailable. Contact provider support."],
"emptyHosts": ["No routes are available. Contact provider support."],
"HWIDMaxDevicesExceeded": ["Device limit reached. Remove an old device or contact support."],
"HWIDNotSupported": ["This subscription requires a supported device identity."]
}
}Never include a username, account ID, subscription URL, token, exact location, support-chat identifier, HTML or embedded link.
HWID test matrix
HWID is optional and provider-controlled. When enabled, test every state rather than only the successful path.
| Case | Expected provider behavior | Client/support check |
|---|---|---|
| HWID disabled | Subscription succeeds without device registration. | NODIF imports and refreshes normally. |
| Valid new device | Device is registered within configured limit. | Refresh and connect succeed. |
| Existing valid device | Stable identity is accepted. | No duplicate device is created unexpectedly. |
| Missing/invalid identity | Typed not-supported behavior or configured generic remark. | Support checks app version/platform; never asks for the raw HWID. |
| Maximum devices | Device-limit behavior or configured remark. | User removes an old device or provider support resets according to policy. |
Proxy, CDN and cache requirements
- Preserve both NODIF response-header names and exactly one value for each.
- Do not cache one user/tenant response and serve it to another. Respect private/no-store provider behavior.
- Do not normalize away underscores/hyphens inside values.
- Remove differently cased duplicates at their source.
- If a response rule applies headers last, verify it cannot overwrite the External Squad’s provider values.
- Keep subscription and branding-token values out of edge access logs or redact the entire value.
Canary verification
- Confirm a NODIF test request matches the narrow rule and a generic client reaches the intended fallback.
- Verify the final response contains exactly one public slug header and one branding-token header, with no legacy alias.
- Refresh the canary in NODIF and verify the correct approved provider name, colors, logo and links.
- Test active, expired, limited, disabled, empty-host and all enabled HWID states.
- Test a user outside the squad and one test user from every other tenant; no cross-tenant brand pointer may appear.
- Connect, disconnect, check routes and perform one intentional speed test on representative Wi‑Fi/mobile/ISP networks.
- Observe before expanding. Define rollback thresholds for import failures, connection success, latency/loss regression and wrong-tenant branding.
Branding-token rotation
- Create a replacement token for the same provider through the portal or approved NODIF process.
- Store it immediately; plaintext is shown once.
- Update only the correct External Squad and refresh a canary.
- Verify the same public slug and correct signed profile; test another tenant for isolation.
- Revoke the old token only after the cutover succeeds.
- Remove temporary captures and redact token values from change evidence.
Rotate immediately after suspected disclosure, staff/automation access changes, incorrect tenant scoping or unexpected profile requests. Rotation does not rotate user subscription URLs, VPN credentials, Remnawave API tokens or provider API keys.
Rollback
- Stop the rollout and preserve only non-secret timestamps/request IDs.
- Restore the exported response-rule ordering and External Squad configuration.
- Remove the two NODIF pointer headers from affected responses if wrong-tenant or malformed values are possible.
- Verify generic clients and provider subscriptions return to their previous behavior.
- Revoke a disclosed branding token.
- Document root cause, affected time range and preventive action without retaining subscription/header values.
