Scanner accounts

Dedicated user accounts for automated security scanners (Intruder.io, Burp, ZAP). Designed to bypass MFA at login and receive long-lived JWTs, while being explicitly blocked from anything destructive.

The problem we solved

Automated security scanners need to log in to test post-authentication pages. They can't generate TOTP codes, so MFA-required login is a wall. The temptation is to disable MFA on a regular user account โ€” but that's a real security regression: that account still has full user permissions, and "MFA off" is exactly how rogue accounts get exploited.

Scanner accounts solve this with a dedicated identity type that's clearly tagged, narrowly scoped, and easy to disable.

What a scanner account can do

  • Log in without MFA (bypass at the auth layer)
  • Receive a 90-day JWT (vs. the 7-day standard)
  • Browse the app as a basic user
  • Hit any read endpoint that a basic user can

What a scanner account cannot do

  • Access vault routes. All 32 password vault endpoints explicitly check for the scanner flag and refuse with SCANNER_DENIED.
  • Hold any admin role. When enabling scanner mode, the system refuses if the user has Principal, IT Admin, or Enterprise Admin in any user_org_roles row.
  • Be a platform admin. The flag refuses to apply to platform admins.
  • Bypass the audit log. Every scanner action is tagged scanner: true in the audit log so it's distinguishable from real user activity.
โœ๏ธ
Defense in depth
Even if the scanner credentials are compromised, the blast radius is small. No vault access. No admin actions. No high-privilege endpoints. The 90-day token can be revoked by toggling the scanner flag off (existing tokens still work until expiry โ€” see FAQ).

Enabling scanner mode

  1. 1
    Create a dedicated user account
    Don't reuse a real user. Create something like scanner@thoushaltnotclick.com with no org roles. The account exists solely for scanning.
  2. 2
    Set a strong password
    Long, random, stored only in the security team's secure password manager โ€” not in TSNC's vault (since vault is blocked for scanners anyway).
  3. 3
    Platform โ†’ Scanner Accounts โ†’ Enable
    Search for the user's email, fill out the optional Notes field (e.g., "Intruder.io continuous scanning"). The system refuses if the user has admin roles.
  4. 4
    Capture the 90-day JWT
    Log in to TSNC as the scanner via curl or a browser. The login response includes "scanner": true and a 90-day JWT. Save the token.
  5. 5
    Configure the scanner
    In Intruder/Burp/ZAP, configure header-based authentication: Authorization: Bearer <token>. Run the scan.

Disabling scanner mode

  1. 1
    Platform โ†’ Scanner Accounts
    Find the account and click Disable.
  2. 2
    Existing tokens remain valid
    Until the token expires (up to 90 days). To force-revoke immediately, rotate the user's password โ€” this prevents re-login and starts the clock on token expiry.
  3. 3
    Confirm the audit log entry
    The disable action appears in your platform audit log so future you can verify what happened.

Configuring Intruder.io

For the most common scanner we work with, here's the canonical config:

  • Entrypoint URL: https://thoushaltnotclick.com/dashboard
  • Logout URL: Leave blank (TSNC has no server-side logout)
  • Logged-in pattern: Log Out (text in sidebar)
  • Auth method: Custom Headers
  • Header: Authorization: Bearer <90-day-jwt>
โš ๏ธ
Don't include destructive endpoints in scans
Configure your scanner to exclude /api/auth/login from active fuzzing โ€” repeated bad credentials will lock the scanner account out via TSNC's persistent login-attempt tracker. Also exclude /api/auth/forgot-password (sends real emails) and /api/billing/* (real payment events).

FAQ

Why 90 days instead of 7?+
Long-running scans, weekly scheduled scans, and CI integrations all need a token that survives. 90 days strikes a balance: long enough to be operationally useful, short enough that a stolen token has a finite lifespan. The flag itself can be toggled off any time โ€” disabling and rotating the user's password is the immediate revoke path.
Can I have multiple scanner accounts?+
Yes. We use one per scanner tool โ€” separate accounts for Intruder, Burp, ZAP โ€” so we can identify which scanner triggered which event. Audit cleanliness over marginal cost.
Can a scanner account also be used by a real human?+
Don't. The whole point is that scanner accounts have no human attached. If a human logs in to a scanner account, every action they take is tagged as scanner activity in the audit log, which makes future incident response much harder. Use a regular account for human activity.
Is there a way to fully revoke a JWT immediately?+
Right now, no โ€” JWTs are stateless and we don't have a denylist. The two practical options: rotate JWT_SECRET (invalidates EVERY token in the system, not just the scanner's), or wait for the 90-day expiry. Rotating the user's password prevents re-login but doesn't invalidate existing tokens. We've started discussions about adding a JWT denylist for scanner accounts specifically; it's on the roadmap.
โ† Previous
Impersonation safeguards