CI/CD & API
Trigger a pentest on every release and gate your pipeline on the result. The REST API is a thin, pollable wrapper around the same engine the dashboard uses.
What you get
The CI/CD integration is a paid Pro add-on (see pricing). It lets your pipeline kick off a test, wait for a decision, and pull a report — no browser involved. Tests triggered from CI always run with destructive actions disabled, so they're safe to run unattended.
1. Create an API key
In Settings, create an API key. Keys are scoped to your workspace and look like
simsec_live_…. The full value is shown once — copy it then and store it as a
secret in your CI system. Keys are hashed at rest and can be revoked anytime.
Authenticate every request with a bearer token:
Authorization: Bearer simsec_live_xxxxxxxxxxxx 2. Trigger a test
POST /api/v1/tests starts a run and returns 202 Accepted with a
run_id immediately — it does not block while the test runs.
# start a test against an engagement, get back a run_id
curl -X POST https://app.simplesec.ai/api/v1/tests \
-H "Authorization: Bearer $SIMPLESEC_API_KEY" \
-H "Content-Type: application/json" \
-d '{"engagement_id": "eng_123", "commit_sha": "$GIT_SHA"}' 3. Poll for the decision
GET /api/v1/tests/{run_id} returns the run's status and, when finished, its
decision: pass, warn, or fail. Poll until the
status is terminal, then act on the decision — fail the build on fail, for example.
curl https://app.simplesec.ai/api/v1/tests/$RUN_ID \
-H "Authorization: Bearer $SIMPLESEC_API_KEY"
# → { "status": "completed", "decision": "warn", ... } 4. Fetch the report
Pull the PDF for the run to attach as a build artifact:
curl https://app.simplesec.ai/api/v1/tests/$RUN_ID/report.pdf \
-H "Authorization: Bearer $SIMPLESEC_API_KEY" \
-o simplesec-report.pdf
You can also DELETE /api/v1/tests/{run_id} to remove a run when you no longer
need it.
Example: GitHub Actions
Put it together — trigger, wait, gate the build on the decision:
name: SimpleSec pentest
on: [push]
jobs:
pentest:
runs-on: ubuntu-latest
steps:
- name: Trigger and gate on SimpleSec
env:
SIMPLESEC_API_KEY: ${{ secrets.SIMPLESEC_API_KEY }}
run: |
RUN_ID=$(curl -s -X POST https://app.simplesec.ai/api/v1/tests \
-H "Authorization: Bearer $SIMPLESEC_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"engagement_id\":\"eng_123\",\"commit_sha\":\"$GITHUB_SHA\"}" \
| jq -r .run_id)
# poll until the run completes
while :; do
BODY=$(curl -s https://app.simplesec.ai/api/v1/tests/$RUN_ID \
-H "Authorization: Bearer $SIMPLESEC_API_KEY")
STATUS=$(echo "$BODY" | jq -r .status)
[ "$STATUS" = "completed" ] && break
sleep 30
done
DECISION=$(echo "$BODY" | jq -r .decision)
echo "SimpleSec decision: $DECISION"
# fail the build on a failing decision
[ "$DECISION" = "fail" ] && exit 1 || true The same three calls work anywhere you can run curl — GitLab CI, Jenkins, CircleCI, Bitbucket Pipelines. Only the secret-injection syntax changes.
Webhooks
Rather than poll, you can have SimpleSec call you. Configure a callback URL and SimpleSec sends a signed
POST when a run completes. Each delivery includes:
X-Simplesec-Signature— an HMAC-SHA256 signature of the body. Verify it with your signing secret before trusting the payload.X-Simplesec-EventandX-Simplesec-Delivery— the event type and a unique delivery ID.
Failed deliveries are retried with backoff, and you can manually resend any delivery from the compliance archive.
Full API reference
A running SimpleSec instance serves interactive OpenAPI docs at /docs (Swagger) with the
complete schema for every endpoint. Use this page for the CI workflow; use Swagger for exact request and
response shapes.