Stoplight Prism API Mock Server on AWS User Guide
Overview
This guide covers deploying and operating Stoplight Prism on AWS using the cloudimg AWS Marketplace AMI. Prism is a popular open source HTTP mock server and contract validation proxy. You 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. It lets front end, mobile and integration teams build against an API before the real backend exists, and lets teams prove that a running service actually honours its published contract.
The AMI installs Prism 5.16.0 (@stoplight/prism-cli) from the public npm registry, pinned to an exact version, on the Node.js 24 LTS runtime that Prism requires. A sensible starter OpenAPI 3.0 specification, the cloudimg Sample Widgets API, ships at /opt/prism/spec/cloudimg-sample-api.yaml and is served on first boot, so you can call a live mock immediately and then replace it with your own description whenever you are ready.
Secure by default. Prism itself has no native authentication, so rather than expose an open mock this image 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 exposes no host secret, no filesystem and no administrative surface.
What is included:
-
Stoplight Prism 5.16.0 (
@stoplight/prism-cli) from the public npm registry, pinned, 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 cloudimg Sample Widgets API) served as a working mock out of the box, 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
Connecting to your instance
Connect over SSH on port 22 as the default login user for your AMI's operating system:
| Operating system | SSH login user |
|---|---|
| Ubuntu 24.04 | 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 allowing TCP 22 (admin) and TCP 4010 (the authenticated mock API) from the developers, test runners and CI agents that will consume the mock
Recommended instance type: m5.large is ample. Prism is a lightweight Node.js process; increase the size only if you drive very high request concurrency.
Step 1: 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 will use the mock, and TCP 22 for administration. Keep 4010 restricted to the networks you serve.
Step 2: 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 recording the reachable mock URL. This completes within seconds. SSH in and read the note:
sudo cat /root/prism-credentials.txt
The 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.
Step 3: Confirm the services are running
Prism runs on loopback and nginx fronts it on port 4010.
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).

Step 4: 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.

Step 5: Contract validation catches bad requests
Prism validates every incoming request against the contract. A request that matches the specification is accepted; a request that violates it is rejected with HTTP 422 and 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.

Step 6: Verify the appliance end to end
A self test ships on the image and 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-selftest
It prints an OK line after confirming the Prism loopback health, the unauthenticated 401, the authenticated /health and /widgets, a valid create, and the invalid request rejection.
Step 7: 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.
Step 8: 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, or 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 prism
Step 9: Use the mock from your clients and CI
On any workstation or CI agent, point your HTTP client at this instance using 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 you own instead of a shared service or an unfinished backend.
Step 10: Rotate the credential or add TLS for production
The per-instance credential lives in /etc/nginx/.prism_htpasswd. Rotate it at any time, and 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 nginx
For 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, or run certbot with the nginx plugin on the instance.
Step 11: 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; 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.
Step 12: Support and Licensing
Stoplight Prism is open source software distributed under the Apache License 2.0. This cloudimg AMI bundles the unmodified upstream @stoplight/prism-cli release from the public npm registry. cloudimg 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.
cloudimg 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?
Email support@cloudimg.co.uk for deployment help, configuration questions, or licensing enquiries.