πŸ›‘ Pentestas β€Ί help

API authentication

Pentestas accepts four credential types across the HTTP + WebSocket surfaces.

At a glance

Credential Prefix Used by Scope
JWT (Bearer) eyJ… Browser + mobile clients Logged-in user in their tenant
User API key aa_… CI, scripts, CLI tools Same as user JWT β€” tenant + permissions
Agent key pa_… Deployed agents Tenant β€” no user, no API surface
OAuth cookie pt=… Browser only Same as JWT; HttpOnly cookie

JWT

Issued by POST /api/auth/login or OAuth callback. Bearer-style Authorization: Bearer <JWT> header, or stored as the pt HttpOnly cookie by browser clients.

  • Signing: HS256 with a server-wide 32-byte secret.
  • Lifetime: 24h default, 7d "remember me".
  • Contains: sub (user ID), tenant_id, role, email, exp.

JWTs cannot be revoked server-side short of rotating the secret. Use API keys for long-lived integrations where you need revocation.

User API keys (aa_…)

Generate at /api/auth/api-key (or in Settings β†’ API keys). Opaque random string. Send as either:

Authorization: Bearer aa_...

or

X-API-Key: aa_...

Both work on every HTTP route. API keys are:

  • Immediately revocable (delete β†’ authentication fails within one request).
  • Audit-logged on every use.
  • Tied to the user who created them β€” permissions inherit.
  • Hashed at rest (we store a bcrypt hash, not the key itself).

Creating

bash
curl -X POST https://app.pentestas.com/api/auth/api-key \
     -H "Authorization: Bearer <your_jwt>" \
     -d '{"name":"CI pipeline"}'

Response shows the key exactly once. Save it immediately; you can't recover it.

Rotating

Create a new key, update your integration, delete the old key. Pentestas stores the creation time per key so you can see ordering.

Agent keys (pa_…)

Issued when you create a NetworkAgent in Settings β†’ Agents. Used only over the agent WebSocket at /api/agents/ws/{agent_key}. Cannot be used for HTTP API calls β€” they grant exactly one capability: connect as this agent.

  • Locked to IP allowlist (admin-configurable).
  • Disable / re-enable / delete from the UI or PUT /api/agents/{id}.
  • Stored in DPAPI (Windows) or chmod 0600 env file (Linux) on the agent host.

OAuth (Google, Microsoft)

For browser sign-in only. Completes with a redirect to the app + set-cookie. Doesn't issue API keys directly; use the app's Settings β†’ API keys to mint one after signing in.

Rate limits

Endpoint group Limit
Auth endpoints (login, signup, password reset) 5 / min per IP
Scan endpoints 30 / s per IP (burst 60)
Public read-only endpoints (subdomain, cloudscan anonymous) 10–30 / hour per IP
Agent WebSocket 1 open connection per agent_key; 5 failed handshakes / hour blocks the IP

Tenant scoping

Every authenticated request is scoped to the caller's tenant. You cannot read scans / findings / agents belonging to a different tenant β€” the API returns 404 (not 403, to avoid leaking existence). Row-Level Security policies in Postgres provide defence in depth.

See also