Adapter Security Contract
Custom adapters are powerful and risky. Neutrx can validate request config before an adapter runs and parse/redact errors after a response returns, but it cannot inspect redirects, DNS, TLS, proxy behavior, or retries that a custom adapter performs internally.
Use built-in adapters for security-sensitive traffic whenever possible.
Required Invariants
A custom adapter must:
- Use
config.urlexactly as passed unless it returns control to Neutrx for redirects. - Not follow redirects internally; return the redirect response so Neutrx can apply redirect policy.
- Not add credentials to cross-origin redirects.
- Not bypass
config.signal,config.timeout,maxBodyLength, ormaxContentLengthsemantics without documenting why. - Preserve
configon the returnedRawHttpResponse. - Return headers without CRLF injection.
- Avoid logging raw URLs, headers, or bodies.
- Treat
legacysecurity settings as trusted migration-only settings.
Secure Wrapper
createSecureAdapter() adds lightweight invariants around a custom adapter:
import neutrx, { createSecureAdapter } from 'neutrx';
const api = neutrx.create({
adapter: createSecureAdapter(async config => {
return {
status: 200,
statusText: 'OK',
headers: { 'content-type': 'application/json' },
data: Buffer.from('{}'),
config,
};
}),
});
The wrapper rejects:
- A response whose
response.config.urldiffers from the request URL. - Redirect responses with a
Locationheader unlessallowRedirectResponsesis set.
This wrapper does not make a custom adapter equivalent to Neutrx’s Node HTTP adapter. DNS pinning, TLS policy, and proxy safety must still be implemented by the adapter or avoided by using built-in adapters.
When Not To Use A Custom Adapter
Avoid custom adapters for:
- User-controlled URLs.
- Webhook target fetches.
- Cloud metadata sensitive environments.
- Requests carrying bearer tokens, cookies, or proxy credentials across redirects.
For those cases, prefer adapter: 'http' with security.profile: 'strict' and an egressPolicy.