Automation and AI
Headless runs and CI
Record, check and replay API traffic in CI with cloakctl run, and run API-client collections like Newman with JUnit, JSON and HTML reports.
Cloak Proxy works without its window. cloakctl can wrap your test command in a capture proxy, record everything it sends, write a report, and fail the build on server errors, leaked secrets or schema changes. It can also run your API client collections with their tests, like Newman or the Postman CLI. Use this page to set up both on your Mac or on a macOS CI runner.
What you can do headless
Section titled “What you can do headless”| Goal | Command |
|---|---|
| Record every API call your tests make, as HAR | cloakctl run --ssl '*' --record run.har -- npm test |
| Fail the build on server errors or leaked secrets | cloakctl run --ssl '*' --fail-on-5xx --fail-on-secrets -- npm test |
| Get a Markdown report for a pull request | cloakctl run --ssl '*' --report report.md -- npm test |
| Run tests offline against a recording | cloakctl run --mock run.har -- npm test |
| Run a collection’s tests with JUnit output | cloakctl collection run "Shop API" -r cli,junit |
| Load test a collection | cloakctl perf "Shop API" --vus 20 --duration 60 |
| Lint an OpenAPI spec | cloakctl spec lint openapi.yaml |
Requirements
Section titled “Requirements”- macOS 14 Sonoma or later, Apple silicon or Intel.
cloakctlis a Mac program, so CI jobs need a macOS runner. - Cloak Proxy installed, because
cloakctlships inside it at/Applications/Cloak Proxy.app/Contents/Resources/cloakctl. See Install and Put cloakctl on your PATH. - No account and no license key.
cloakctlis free for life, like the app.
cloakctl run creates the root certificate in ~/Library/Application Support/CloakProxy/ the first time it needs one. It doesn’t need the certificate to be trusted in the macOS keychain, because it hands the certificate to the wrapped command through environment variables.
Wrap a test command
Section titled “Wrap a test command”Put your test command after --. cloakctl run starts the proxy, runs the command with the proxy and certificate already set, and stops when the command exits.
-
Choose which HTTPS traffic to decrypt.
--ssl '*'decrypts every host. To be narrower, repeat--sslwith host patterns such asapi.example.comor*.example.com. Without--ssl, HTTPS shows only as encrypted tunnels. -
Add what you want out of the run:
--recordfor the traffic,--reportfor a summary, and any--fail-on-…checks. -
Run it:
Terminal cloakctl run --port 9091 --ssl '*' \--record run.har --redact --report report.md \--fail-on-5xx --fail-on-secrets \-- npm test -
Read the summary on standard error and check the exit code:
Recorded 42 requests to run.harReport written to report.md42 requests, 9 endpoints, 0 errors, 0 possible secrets, 0 schema changes
The environment the command gets
Section titled “The environment the command gets”The wrapped command is started through /usr/bin/env with these variables added to your current environment:
| Variable | Value | Who reads it |
|---|---|---|
HTTP_PROXY, HTTPS_PROXY, http_proxy, https_proxy |
http://127.0.0.1:PORT |
curl, Python, Ruby, Go, git, Deno and most HTTP libraries |
NODE_USE_ENV_PROXY |
1 |
Node.js 24 and later, so its built-in fetch and http use the proxy |
NODE_EXTRA_CA_CERTS |
Path of the root certificate | Node.js |
SSL_CERT_FILE |
Path of the root certificate | OpenSSL-based tools, Ruby, Go |
REQUESTS_CA_BUNDLE |
Path of the root certificate | Python requests |
CURL_CA_BUNDLE |
Path of the root certificate | curl |
GIT_SSL_CAINFO |
Path of the root certificate | git |
Programs that ignore these variables aren’t captured. See Terminal and runtimes for runtimes that need extra setup, such as older Node.js versions or Java.
Run without a command
Section titled “Run without a command”Leave out -- and the command, and the proxy runs until you press Control C, send SIGTERM, or --duration runs out. Point any app at 127.0.0.1:PORT in the meantime. With --duration and a wrapped command, the command is stopped when the time is up.
Fail the build on problems
Section titled “Fail the build on problems”Each --fail-on-… flag adds a check. If any check fails, cloakctl run prints FAILED: with the reasons and exits with 1.
| Flag | Fails when |
|---|---|
--fail-on-5xx |
Any response had a 5xx status. |
--fail-on-error |
Any response had a 4xx or 5xx status, or any request failed (connection error, DNS failure, timeout). |
--fail-on-secrets |
The secret scanner found a high-severity secret in the traffic: for example an AWS, GitHub, Slack, OpenAI or Anthropic key, a live Stripe key, a private key, a card number, or credentials in a URL or sent over plain HTTP. |
--fail-on-schema-change |
An endpoint’s JSON response changed shape during the run: a field was added or removed, or changed type. See Schema changes. |
42 requests, 9 endpoints, 3 errors, 1 possible secrets, 0 schema changesFAILED: 2 server errors, 1 high-severity secretsExit codes
Section titled “Exit codes”| Exit code | Meaning |
|---|---|
0 |
No check failed, and the wrapped command (if any) exited with 0. |
1 |
A --fail-on-… check failed, an option was wrong, or a file couldn’t be read or written. |
| The command’s own code | No check failed, but the wrapped command exited with a non-zero code. Your test failures still fail the build. |
127 |
The wrapped command couldn’t be started (for example, it isn’t installed). |
Record and report
Section titled “Record and report”--record FILE writes the traffic when the run ends. A file ending in .har gets HAR that any HAR viewer opens. Any other name gets a Cloak Proxy session you can open in the app with File › Open Session…. See Save and open sessions.
--redact removes tokens, cookies, API key headers, credential parameters, password-like fields and anything the secret scanner matches, before the recording is written. Use it whenever the recording leaves your Mac, for example as a CI artifact. See Redaction.
--report FILE writes a Markdown report, the same one as Export Report in Insights:
| Section | What it lists |
|---|---|
| Summary line | Requests, endpoints, errors, possible secrets and schema changes. |
| Endpoints | Up to 50 endpoint templates (such as /users/{id}) with calls, errors, p50 and p95. |
| Possible secrets | Each finding’s severity, kind, where it was found, host and request id. Values are masked. |
| Security headers | An A to F grade per host with its issues. |
| Performance | Slow and large responses, missing compression, duplicates, N+1 bursts and similar findings. |
| Schema changes | Added, removed and retyped fields per endpoint. |
Empty sections are left out. The report is made before redaction, but it only ever shows masked secret values.
Replay a recording offline
Section titled “Replay a recording offline”--mock FILE loads a .har or .cloaksession file as a mock set and answers matching requests from it instead of the network. A request to a recorded host that isn’t in the recording gets a 404, so nothing slips through to the real API. Requests to other hosts go to the network as usual. Record once against a real backend, then run the same tests offline or in CI without the backend:
# Once, against the real API:cloakctl run --ssl 'api.example.com' --record fixtures/api.har --redact -- npm test
# Every CI run, with no network access to the API:cloakctl run --mock fixtures/api.har --quiet -- npm testYou can combine --mock with --tools RULES.json to add Map Local, Map Remote or other rules exported from the app with Tools › Export Rules…. See Mock a backend.
Run collections like Newman
Section titled “Run collections like Newman”cloakctl collection run runs a collection from your API client workspace, with its pre-request scripts, tests, auth and variables. It doesn’t need the app or a proxy. Every flag is listed in cloakctl › Run a collection.
cloakctl collection run "Shop API" \ --workspace ./api-workspace \ -e Staging \ -d "Login users" \ --env-var "apiKey=$SHOP_API_KEY" \ -r cli,junit,html \ --reporter-junit-export results/api.xml \ --reporter-html-export results/api.htmlReporters
Section titled “Reporters”| Reporter | Output | Default file |
|---|---|---|
cli |
Live results in the terminal, then a summary line. | Standard output |
json |
The full run as JSON. | cloak-run.json |
junit |
JUnit XML, which most CI systems show as test results. | cloak-run.xml |
html |
A standalone HTML report. | cloak-run.html |
Pick several with commas: -r cli,junit,json. The folder for an export path must already exist.
Secrets in CI
Section titled “Secrets in CI”Secret variable values live in the workspace’s git-ignored .cloak/ folder, and {{vault:name}} values live in the macOS Keychain, so neither is in your repository. On a CI runner, pass secrets in with --env-var KEY=VALUE from your CI system’s secret store. See Variables and environments.
Collection run exit codes
Section titled “Collection run exit codes”collection run exits with 0 when every request and test passed, and 1 when any request failed to send or any test failed. --bail stops the run at the first failure.
Example: GitHub Actions
Section titled “Example: GitHub Actions”This workflow runs on a self-hosted macOS runner that has Cloak Proxy installed in /Applications. It runs a collection with JUnit output, then runs the app’s own tests through the recorder and fails on server errors or leaked secrets.
name: API tests
on: [push, pull_request]
jobs: api: runs-on: [self-hosted, macOS] env: CLOAKCTL: /Applications/Cloak Proxy.app/Contents/Resources/cloakctl steps: - uses: actions/checkout@v4
- name: Prepare results folder run: mkdir -p results
- name: Run the API collection env: SHOP_API_KEY: ${{ secrets.SHOP_API_KEY }} run: | "$CLOAKCTL" collection run "Shop API" \ --workspace ./api-workspace \ -e Staging \ --env-var "apiKey=$SHOP_API_KEY" \ --bail \ -r cli,junit \ --reporter-junit-export results/api.xml
- name: Lint the OpenAPI spec run: '"$CLOAKCTL" spec lint api-workspace/specs/shop-api.yaml'
- name: Record and check the app's API traffic run: | "$CLOAKCTL" run --port 9091 --ssl '*' \ --record results/traffic.har --redact \ --report results/report.md \ --fail-on-5xx --fail-on-secrets \ -- npm test
- name: Upload results if: always() uses: actions/upload-artifact@v4 with: name: api-results path: results/Adjust the collection name, environment, spec path and test command to your project. --port 9091 keeps the job clear of a Cloak Proxy app running on 9090 on the same runner.
Run on a schedule
Section titled “Run on a schedule”The app’s monitors and scheduled flows run only while the app is open. For checks that run around the clock, schedule cloakctl collection run with cron, launchd or your CI system’s scheduled workflows.