Mountebank Configuration Format¶
The Mountebank JSON format is the recommended way to configure Rift for service virtualization and API mocking.
Configuration File Structure¶
{
"imposters": [
{
"port": 4545,
"protocol": "http",
"name": "Service Name",
"stubs": [...],
"defaultResponse": {...}
}
]
}
Imposter Configuration¶
Core Fields¶
No field is strictly required.
| Field | Type | Default | Description |
|---|---|---|---|
port |
number | auto-assigned | Port to listen on. Omitted or 0 means "pick a free port"; imposters that name a port are created first. A --datadir file must name one |
protocol |
string | http |
http or https; anything else (tcp, smtp) is rejected |
host |
string | the server's --host, or all interfaces dual-stack (::) when none was given |
Address to bind the imposter to. Omitted, the imposter binds the server's --host, or with none listens dual-stack, as in Mountebank, falling back to 0.0.0.0 on a host without IPv6; an explicit 0.0.0.0 is IPv4 only |
Optional Fields¶
| Field | Type | Description |
|---|---|---|
name |
string | Human-readable identifier |
stubs |
array | Request/response mappings |
defaultResponse |
object | Response when no stub matches; also supplies the statusCode, headers, body and _mode that an is or inject response omits (headers is replaced whole; a proxy key in it is ignored, use defaultForward) |
recordRequests |
boolean | Store requests for verification |
recordMatches |
boolean | Accepted, no effect: per-stub matches are not recorded. true is reported as config_key_ignored in _rift.warnings and by rift-lint W017; use recordRequests |
allowCORS |
any | When JavaScript-truthy, answer a CORS preflight (an OPTIONS with Origin, Access-Control-Request-Method and Access-Control-Request-Headers) by echoing those values as Access-Control-Allow-Origin/-Methods/-Headers, on the stub's or default response. Other requests get no CORS headers. Printed back in every view as configured |
key |
string | PEM private key (HTTPS) |
cert |
string | PEM certificate (HTTPS) |
mutualAuth |
boolean | Request and require a client certificate (https only) |
rejectUnauthorized |
boolean | Validate the client certificate against ca; requires ca |
ca |
string or array | PEM trust anchor(s) client certificates must chain to |
defaultForward |
string | Rift extension. Upstream base URL an unmatched request is forwarded to (takes precedence over defaultResponse). Its path prefixes the request's; a trailing / on it is not doubled, and a query or fragment on it is ignored |
strictBehaviors |
boolean | Rift extension. Turn a failing behavior into a 500 — see Strict Behaviors |
enabled |
boolean | Whether the imposter serves traffic (default true); toggled by POST /imposters/{port}/disable and /enable |
A request that matches no stub gets the defaultResponse when there is one, and otherwise a 200
with an empty body — as in Mountebank, never a 404.
TLS fields (key, cert, mutualAuth, rejectUnauthorized, ca) are covered in
TLS/HTTPS.
Rift-Specific Metadata Fields¶
| Field | Type | Description |
|---|---|---|
serviceName |
string | Service name for documentation (alias: service_name) |
serviceInfo |
object | Arbitrary metadata (JSON object) |
_rift |
object | Rift extensions (flow state, faults, scripting) |
Example with metadata:
{
"port": 4545,
"protocol": "http",
"name": "User Service",
"serviceName": "user-api",
"serviceInfo": {
"team": "platform",
"version": "1.2.3",
"documentation": "https://docs.example.com/user-api"
},
"stubs": [...]
}
Stub Configuration¶
Predicates Array¶
Each predicate object can contain:
{
"predicates": [
{
"equals": { "method": "GET", "path": "/api" },
"caseSensitive": false,
"except": ""
}
]
}
Responses Array¶
Predicate Types Reference¶
equals¶
deepEquals¶
contains¶
startsWith¶
endsWith¶
matches¶
exists¶
jsonpath¶
jsonpath is a parameter of another predicate, not a predicate of its own: the selector narrows
the body, and the operator beside it tests what was selected.
xpath¶
Logical Operators¶
{ "and": [ { "equals": {...} }, { "contains": {...} } ] }
{ "or": [ { "equals": {...} }, { "equals": {...} } ] }
{ "not": { "equals": {...} } }
Response Types Reference¶
is (Static)¶
{
"is": {
"statusCode": 200,
"headers": { "Content-Type": "application/json" },
"body": { "key": "value" }
}
}
proxy¶
{
"proxy": {
"to": "https://api.example.com",
"mode": "proxyOnce",
"predicateGenerators": [{ "matches": { "path": true } }]
}
}
inject¶
Behaviors Reference¶
wait¶
decorate¶
copy¶
from is "path", "method" or "body", or {"query": "<name>"} / {"headers": "<name>"}.
A regex selector yields its first capture group (or the whole match when it has none); jsonpath
and xpath selectors apply to the value from picked.
{
"_behaviors": {
"copy": {
"from": "path",
"into": "${id}",
"using": { "method": "regex", "selector": "/users/(\\d+)" }
}
}
}
lookup¶
{
"_behaviors": {
"lookup": {
"key": { "from": { "query": "id" }, "using": { "method": "regex", "selector": ".*" } },
"fromDataSource": { "csv": { "path": "data.csv", "keyColumn": "id" } },
"into": "${row}"
}
}
}
copy and lookup each accept a single object or an array of them. See
Behaviors for shellTransform, repeat and the
error semantics. Unlike Mountebank, a lookup in an imposter posted over the admin API reads
its CSV file only under --scripts-dir, with data.csv above meaning <scripts-dir>/data.csv
(see CSV Lookup).
Behaviors run on is, inject and proxy responses, and repeat on every response. A block
setting anything else on a fault or _rift-only response is kept and returned, and reported as
config_key_ignored in _rift.warnings and by rift-lint W017 — see
Behaviors.
HTTPS Configuration¶
{
"port": 4545,
"protocol": "https",
"key": "-----BEGIN RSA PRIVATE KEY-----\nMIIE...\n-----END RSA PRIVATE KEY-----",
"cert": "-----BEGIN CERTIFICATE-----\nMIID...\n-----END CERTIFICATE-----",
"mutualAuth": false,
"stubs": [...]
}
Using File Paths¶
{
"port": 4545,
"protocol": "https",
"key": "<%- stringify('/path/to/key.pem') %>",
"cert": "<%- stringify('/path/to/cert.pem') %>",
"stubs": [...]
}
Complete Example¶
{
"imposters": [
{
"port": 4545,
"protocol": "http",
"name": "User Service",
"recordRequests": true,
"defaultResponse": {
"statusCode": 404,
"body": { "error": "Not Found" }
},
"stubs": [
{
"predicates": [
{ "equals": { "method": "GET", "path": "/health" } }
],
"responses": [
{ "is": { "statusCode": 200, "body": "OK" } }
]
},
{
"predicates": [
{
"and": [
{ "equals": { "method": "GET" } },
{ "matches": { "path": "/users/\\d+" } }
]
}
],
"responses": [
{
"is": {
"statusCode": 200,
"headers": { "Content-Type": "application/json" },
"body": { "id": "${id}", "name": "User" }
},
"_behaviors": {
"copy": {
"from": "path",
"into": "${id}",
"using": { "method": "regex", "selector": "/users/(\\d+)" }
}
}
}
]
},
{
"predicates": [
{ "equals": { "method": "POST", "path": "/users" } },
{ "exists": { "body": true }, "jsonpath": { "selector": "$.name" } }
],
"responses": [
{
"is": {
"statusCode": 201,
"body": { "id": 999, "message": "Created" }
},
"_behaviors": { "wait": 100 }
}
]
}
]
}
]
}
Loading Configuration¶
From File at Startup¶
# Docker
docker run -p 2525:2525 -p 4545:4545 -v $(pwd)/imposters.json:/imposters.json \
zainalpour/rift-proxy:latest --configfile /imposters.json
# Binary
rift --configfile imposters.json
The file may also be YAML (a sequence of imposters) or a single imposter object, and may use the Mountebank EJS tags — see Document shapes and formats.
Via REST API¶
# Create single imposter
curl -X POST http://localhost:2525/imposters \
-H "Content-Type: application/json" \
-d @imposter.json
# Replace the whole set (imposters absent from the payload are deleted)
curl -X PUT http://localhost:2525/imposters \
-H "Content-Type: application/json" \
-d @imposters.json