Stoplight Prism
Overview
Prism is a popular open-source HTTP mock server and contract validation proxy. Point it at an API description in OpenAPI, Swagger or Postman format, and it stands up a live mock server in seconds. Every endpoint returns realistic, schema-conformant example responses, and every incoming request is validated against the contract, so mismatches are caught immediately.
Prism lets front-end, mobile and integration teams build against an API before the real backend exists. It also lets teams prove that a running service honours its published contract. This guide covers the deployment and configuration of Stoplight Prism on Ubuntu 24.04 on Azure, using SecureAnyCloud Azure Marketplace images.
Secure by default, and clear about what that means. Prism is by design an unauthenticated mock server. Serving a mock API to any client that can reach the port is its normal, intended function, so there is no login, password or token to manage and nothing to rotate.
The image applies a secure-by-default posture around it. The mock returns only synthetic example data from the specification you provide, and it exposes no host secret, no filesystem and no administrative surface. Prism runs as an unprivileged user under a hardened systemd unit, with the operating system kept read-only outside its own state directory. The only network listener is the mock itself. No SSH key and no default operating system credential are baked into the image.
What you get:
- Stoplight Prism 5.16.0 (
@stoplight/prism-cli) from the public npm registry, pinned to an exact version, run under systemd (prism.service) as a dedicated unprivilegedprismuser, serving the mock on port 4010 - Node.js 24 LTS (
Krypton) from NodeSource, the runtime Prism 5.16.0 requires (enginesnode >=24.18.0) - A starter OpenAPI 3.0 specification, the SecureAnyCloud Sample Widgets API, at /opt/prism/spec/sac-sample-api.yaml. It is served on first boot, so you can call a live mock immediately and replace it with your own description when you are ready
- A hardened systemd unit and a run wrapper that selects mock or proxy mode from
/etc/prism/prism.env - An Ubuntu 24.04 LTS base, patched at build time, with unattended security upgrades enabled
- 24/7 SecureAnyCloud support
Prerequisites
- An active Azure subscription, an SSH public key, and a VNet with a subnet in the target region
- A subscription to the Stoplight Prism listing on Azure Marketplace
- Network Security Group rules that allow TCP 22 (admin) and TCP 4010 (the mock API) from the developers, test runners and CI agents that consume the mock
The recommended virtual machine size is Standard_B2s (2 vCPU, 4 GB RAM), which is ample. Prism is a lightweight Node.js process, so increase the size only if you drive very high request concurrency.
Deploy from the Azure Portal
In Marketplace, search for Stoplight Prism, select the SecureAnyCloud publisher, and select Create.
Configure the Network Security Group to allow TCP 4010 from the clients and CI agents that use the mock, and TCP 22 for administration. Keep 4010 restricted to the networks you serve.
Deploy from the Azure CLI
RG="stoplight-prism-prod"; LOCATION="eastus"; VM_NAME="prism1" IMAGE_URN="sac1647283583153:stoplight-prism-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION"
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:stoplight-prism-ubuntu-24-04:default:latest
az vm create \
--resource-group "$RG" --name "$VM_NAME" \
--image "$IMAGE_URN" \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values "$SSH_KEY" \
--public-ip-sku Standard
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 4010 --priority 1001
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 22 --priority 1002First boot and the per-instance info note
On first boot, the image resolves this VM's address, (re)starts Prism with the shipped configuration, and writes a root-only info note that records the reachable mock URL. This completes within seconds. Connect over SSH as azureuser and read the note:
sudo cat /root/prism-info.txtThe note records PRISM_MOCK_URL for this instance, plus ready-to-paste curl examples. Prism is an unauthenticated mock by design, so the note contains no credential. It is purely a convenience.
Confirm the service is running
Check that prism.service is active and that Prism is listening on port 4010:
systemctl is-active prism.service prism --version sudo ss -tlnp | grep ':4010 'Call the mock
The mock serves the endpoints defined in the shipped OpenAPI specification. GET /health is a liveness probe, and GET /widgets returns a schema-conformant example array straight from the spec. These are real mocked responses, not just status codes.
curl -s http://127.0.0.1:4010/health | jq .
curl -s http://127.0.0.1:4010/widgets | jq .
curl -s http://127.0.0.1:4010/widgets/1 | jq .Prism selects the example from the specification and returns it with the correct status code and content type, so your clients receive realistic data before the real backend exists.
Contract validation catches bad requests
Prism validates every incoming request against the contract. It accepts a request that matches the specification and rejects with HTTP 422 a request that violates it, with a body that explains exactly what was wrong. The sample POST /widgets requires a name property, so a request without one is rejected.
# a valid request that matches the contract is accepted (201)
curl -s -o /dev/null -w 'valid POST -> HTTP %{http_code}\n' \
-X POST http://127.0.0.1:4010/widgets \
-H 'Content-Type: application/json' -d '{"name":"Gadget","color":"red"}'
# an invalid request (missing the required name) is rejected (422)
curl -s -o /dev/null -w 'invalid POST -> HTTP %{http_code}\n' \
-X POST http://127.0.0.1:4010/widgets \
-H 'Content-Type: application/json' -d '{"color":"red"}'
# the 422 body explains exactly which part of the contract was violated
curl -s -X POST http://127.0.0.1:4010/widgets \
-H 'Content-Type: application/json' -d '{"color":"red"}' | jq .The validation message reads Request body must have required property 'name', which is how Prism tells a client precisely how it broke the contract.
Verify the appliance end to end
A self-test ships on the image. It proves the whole mock round trip plus contract validation in one command, and you can run it at any time.
sudo /usr/local/bin/prism-selftest grep '^PRISM_MOCK_URL=' /root/prism-info.txtThe self-test prints an OK line after it confirms /health, /widgets, a valid create and the invalid request rejection.
Serve your own API description
Replace the sample specification with your own OpenAPI, Swagger or Postman description. Copy your file onto the VM, point PRISM_SPEC at it, and restart the service:
sudo nano /etc/prism/prism.env
# set PRISM_SPEC=/opt/prism/spec/my-api.yaml (or a URL), then save and:
sudo systemctl restart prism.servicePRISM_SPEC accepts a local file path or an http(s) URL. The rest of the environment file documents every option inline.
Switch between mock, proxy and dynamic modes
Prism runs as a mock by default. It can instead run as a validation proxy that forwards requests to a real upstream and validates both the request and the response against the contract. It can also generate dynamic responses from the schema instead of static examples. Set the mode in the environment file:
# validation proxy: forward to a real backend and validate against the contract
# in /etc/prism/prism.env set:
# PRISM_MODE=proxy
# PRISM_UPSTREAM=<upstream-url>
# dynamic responses generated from the schema instead of static examples:
# PRISM_FLAGS=--dynamic
sudo systemctl restart prism.serviceUse the mock from your clients and CI
On any workstation or CI agent, point your HTTP client at this instance. Replace <vm-ip> with this instance's address, or a DNS name that you point at it. Make sure the Network Security Group allows TCP 4010 from that client.
curl http://<vm-ip>:4010/widgets
curl -X POST http://<vm-ip>:4010/widgets -H 'Content-Type: application/json' -d '{"name":"Sprocket"}'In a test suite or CI pipeline, set the mock base URL as an environment variable and point your integration tests at the instance. Every request then exercises a predictable, controllable endpoint that you own, instead of a shared service or an unfinished backend.
Put a real domain and TLS in front for production
Prism serves plain HTTP because a mock returns only synthetic data. For a shared or internet-facing deployment, place Prism behind your own reverse proxy that terminates TLS and, if you wish, adds authentication.
Bind Prism to loopback by setting PRISM_HOST=127.0.0.1 in /etc/prism/prism.env, so only your proxy can reach it. Then front it with nginx and a CA-signed certificate for <your-domain>.
Security recommendations
- Restrict the NSG. Allow TCP 4010 only from the developers, test runners and CI agents that consume the mock, and TCP 22 only from your administration network.
- Front it with your own TLS proxy for anything shared. Bind Prism to loopback and terminate TLS at nginx with a real certificate when the mock is reachable beyond a trusted subnet.
- Remember that the mock is unauthenticated by design. It serves only synthetic data from your specification, but treat the port as open to whoever can reach it and scope the NSG accordingly.
- Keep the OS patched. Unattended security upgrades remain enabled on the running VM.
Support and licensing
Stoplight Prism is open-source software distributed under the Apache License 2.0. This SecureAnyCloud image bundles the unmodified upstream @stoplight/prism-cli release from the public npm registry.
SecureAnyCloud provides the packaging, the systemd hardening, the dedicated unprivileged service account, the starter OpenAPI specification, the per-instance info automation, the paired deploy guide, and 24/7 support with a guaranteed 24-hour response SLA.
SecureAnyCloud is not affiliated with or endorsed by Stoplight or the Prism project. Stoplight and Prism are marks of their respective owner and are used here only to identify the software.
Deploy on Azure
Find Stoplight Prism on Ubuntu 24.04 LTS on the Azure Marketplace, published by SecureAnyCloud. Deploy from the Portal or the Azure CLI, as shown above.
Need Help?
E-mail sales@secureanycloud.com for deployment help, configuration questions, or licensing enquiries.
Deploy on Azure
Launch Stoplight Prism 5.16.0 on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
Prism is a popular open-source HTTP mock server and contract validation proxy. Point it at an API description in OpenAPI, Swagger or Postman format, and it stands up a live mock server in seconds. Every endpoint returns realistic, schema-conformant example responses, and every incoming request is validated against the contract, so mismatches are caught immediately.
Prism lets front-end, mobile and integration teams build against an API before the real backend exists. It also lets teams prove that a running service honours its published contract. This guide covers deploying and operating Stoplight Prism on AWS, using the SecureAnyCloud AWS Marketplace AMI.
Secure by default. Prism has no native authentication, so this image does not expose an open mock. It binds Prism to the loopback interface (127.0.0.1:8080) and fronts it with nginx on port 4010 enforcing HTTP Basic authentication.
A unique Basic authentication credential (username prism, a random password) is generated for your instance on first boot, before the mock is reachable, and written to a root-only file. No shared or default credential ships in the image, and two instances never share a credential. The mock returns only synthetic example data from the specification you provide, and it exposes no host secret, no filesystem and no administrative surface.
What you get:
- Stoplight Prism 5.16.0 (
@stoplight/prism-cli) from the public npm registry, pinned to an exact version, run under systemd (prism.service) as an unprivilegedprismuser, bound to loopback127.0.0.1:8080 - nginx fronting Prism on port 4010 with per-instance HTTP Basic authentication minted at first boot
- Node.js 24 LTS (
Krypton) from NodeSource, the runtime Prism 5.16.0 requires (enginesnode >=24.18.0) - A starter OpenAPI 3.0 specification, the SecureAnyCloud Sample Widgets API, at /opt/prism/spec/sac-sample-api.yaml. It is served on first boot as a working mock, ready to be replaced with your own description
- A hardened systemd unit and a run wrapper that selects mock or proxy mode from
/etc/prism/prism.env - A fully patched Ubuntu 24.04 LTS base with unattended security upgrades enabled
- 24/7 SecureAnyCloud support
Connecting to your instance
Connect over SSH on port 22 as the default login user for your AMI's operating system. On Ubuntu 24.04, the SSH login user is ubuntu.
ssh ubuntu@<vm-ip>Prerequisites
- An AWS account and a subscription to the Stoplight Prism listing on AWS Marketplace
- An EC2 key pair for SSH access
- A security group that allows TCP 22 (admin) and TCP 4010 (the authenticated mock API) from the developers, test runners and CI agents that consume the mock
The recommended instance type is m5.large, which is ample. Prism is a lightweight Node.js process, so increase the size only if you drive very high request concurrency.
Launch the AMI
Subscribe to Stoplight Prism on AWS Marketplace, then launch the AMI.
In the security group, allow TCP 4010 from the clients and CI agents that use the mock, and TCP 22 for administration. Keep 4010 restricted to the networks you serve.
Retrieve your per-instance credential
On first boot, the AMI mints a unique HTTP Basic authentication credential for this instance, resolves the instance public address, and writes a root-only note that records the reachable mock URL. This completes within seconds. Connect over SSH and read the note:
sudo cat /root/prism-credentials.txtThe note records PRISM_BASIC_AUTH_USER (always prism), the generated PRISM_BASIC_AUTH_PASSWORD, and the PRISM_MOCK_URL for this instance, plus ready-to-paste curl examples. Store the password somewhere safe.
Confirm the services are running
Prism runs on loopback, and nginx fronts it on port 4010. Check both services:
systemctl is-active prism.service nginx.service prism --version sudo ss -tlnp | grep -E ':8080|:4010'prism.service and nginx.service are both active. Prism listens on 127.0.0.1:8080 (loopback only), and nginx listens on 0.0.0.0:4010 (the public, authenticated mock).
Call the mock (authentication required)
The mock serves the endpoints defined in the shipped OpenAPI specification, behind HTTP Basic authentication. A request without the credential is rejected with HTTP 401. A request with the per-instance credential returns a real, schema-conformant mocked response.
# no credentials -> the mock is refused (401)
curl -s -o /dev/null -w 'unauthenticated -> HTTP %{http_code}\n' http://<vm-ip>:4010/widgets
# with the per-instance credential -> a real mocked response (200)
curl -s -u prism:<PRISM_BASIC_AUTH_PASSWORD> http://<vm-ip>:4010/health | jq .
curl -s -u prism:<PRISM_BASIC_AUTH_PASSWORD> http://<vm-ip>:4010/widgets | jq .Prism selects the example from the specification and returns it with the correct status code and content type, so your clients receive realistic data before the real backend exists.
Contract validation catches bad requests
Prism validates every incoming request against the contract. It accepts a request that matches the specification and rejects with HTTP 422 a request that violates it, with a body that explains exactly what was wrong. The sample POST /widgets requires a name property, so a request without one is rejected.
# a valid request that matches the contract is accepted (201)
curl -s -o /dev/null -w 'valid POST -> HTTP %{http_code}\n' \
-u prism:<PRISM_BASIC_AUTH_PASSWORD> -X POST http://<vm-ip>:4010/widgets \
-H 'Content-Type: application/json' -d '{"name":"Gadget","color":"red"}'
# an invalid request (missing the required name) is rejected (422)
curl -s -o /dev/null -w 'invalid POST -> HTTP %{http_code}\n' \
-u prism:<PRISM_BASIC_AUTH_PASSWORD> -X POST http://<vm-ip>:4010/widgets \
-H 'Content-Type: application/json' -d '{"color":"red"}'The validation message reads Request body must have required property 'name', which is how Prism tells a client precisely how it broke the contract.
Verify the appliance end to end
A self-test ships on the image. It proves the whole authenticated mock round trip plus contract validation in one command. It reads the per-instance credential itself, so run it with sudo:
sudo /usr/local/bin/prism-selftestThe self-test prints an OK line after it confirms the Prism loopback health, the unauthenticated 401, the authenticated /health and /widgets, a valid create, and the invalid request rejection.
Serve your own API description
Replace the sample specification with your own OpenAPI, Swagger or Postman description. Copy your file onto the instance, point PRISM_SPEC at it, and restart the service:
sudo nano /etc/prism/prism.env
# point PRISM_SPEC at your own description (a file path or an http(s) URL), save, then:
sudo systemctl restart prism
# your clients now reach the mock at http://<public-ip>:4010/ (Basic auth)PRISM_SPEC accepts a local file path or an http(s) URL. The rest of the environment file documents every option inline.
Prism stays on loopback and nginx keeps enforcing Basic authentication, so your own API is served securely with no extra configuration.
Switch between mock, proxy and dynamic modes
Prism runs as a mock by default. It can instead run as a validation proxy that forwards requests to a real upstream and validates both the request and the response against the contract. It can also generate dynamic responses from the schema instead of static examples. Set the mode in the environment file:
# validation proxy: forward to a real backend and validate against the contract
# in /etc/prism/prism.env set: PRISM_MODE=proxy and PRISM_UPSTREAM=https://<your-domain>
# dynamic responses generated from the schema instead of static examples:
# set PRISM_FLAGS=--dynamic
sudo systemctl restart prismUse the mock from your clients and CI
On any workstation or CI agent, point your HTTP client at this instance with the per-instance credential. Replace <public-ip> with this instance's address, and make sure the security group allows TCP 4010 from that client.
curl -u prism:<password> http://<public-ip>:4010/widgets
curl -u prism:<password> -X POST http://<public-ip>:4010/widgets \
-H 'Content-Type: application/json' -d '{"name":"Sprocket"}'In a test suite or CI pipeline, set the mock base URL and credential as environment variables and point your integration tests at the instance. Every request then exercises a predictable, controllable endpoint that you own, instead of a shared service or an unfinished backend.
Rotate the credential or add TLS for production
The per-instance credential lives in /etc/nginx/.prism_htpasswd. Rotate it at any time. For anything shared or internet-facing, terminate TLS in front of the mock.
# rotate the Basic auth password (username prism), then reload nginx:
sudo htpasswd -bB /etc/nginx/.prism_htpasswd prism '<new-password>'
sudo systemctl reload nginxFor a shared or internet-facing deployment, place the instance behind your own reverse proxy or load balancer that terminates TLS with a certificate for your-domain. Alternatively, run certbot with the nginx plugin on the instance.
Security recommendations
- Restrict the security group. Allow TCP 4010 only from the developers, test runners and CI agents that consume the mock, and TCP 22 only from your administration network.
- Keep the per-instance credential secret. It is generated uniquely per instance and never shipped in the image. Rotate it as needed with
htpasswd. - Terminate TLS for anything shared. The mock is served over plain HTTP behind Basic authentication, so add a TLS-terminating proxy or load balancer when the mock is reachable beyond a trusted subnet.
- Keep the OS patched. Unattended security upgrades remain enabled on the running instance.
Support and licensing
Stoplight Prism is open-source software distributed under the Apache License 2.0. This SecureAnyCloud AMI bundles the unmodified upstream @stoplight/prism-cli release from the public npm registry.
SecureAnyCloud provides the packaging, the systemd hardening, the dedicated unprivileged service account, the per-instance HTTP Basic authentication front door, the starter OpenAPI specification, the per-instance credential automation, the paired deploy guide, and 24/7 support with a one-hour average response for critical issues.
SecureAnyCloud is not affiliated with or endorsed by Stoplight or the Prism project. Stoplight and Prism are marks of their respective owner and are used here only to identify the software.
Need Help?
E-mail sales@secureanycloud.com for deployment help, configuration questions, or licensing enquiries.
Deploy on AWS
Launch Stoplight Prism 5.16.0 on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com