Security
Reporting vulnerabilities
Section titled “Reporting vulnerabilities”If you believe you have found a security vulnerability in SpartanAuth, please do not open a public GitHub issue.
Send a message to [email protected] with:
- A description of the vulnerability
- Steps to reproduce
- Potential impact
- Any suggested mitigations (optional)
We will acknowledge receipt promptly and work with you to understand and resolve the issue before any public disclosure.
Security model
Section titled “Security model”JWT signing
Section titled “JWT signing”SpartanAuth signs JWTs with an RSA private key. Verification uses the corresponding public key. As long as your private key is kept secret, tokens cannot be forged.
Tokens include an expiry (exp) claim. Expired tokens are rejected by the introspection endpoint.
Sector isolation
Section titled “Sector isolation”Each sector is a fully isolated namespace. Users, credentials, and settings in one sector have no access to or visibility into another sector.
Server-side verification
Section titled “Server-side verification”JWTs must always be verified server-side via the introspection endpoint before making authorization decisions. Client-side JWT decoding is for display purposes only.
Soft deletes
Section titled “Soft deletes”When a profile is deleted, its PII (email, name, etc.) is cleared immediately, but the sub identifier is retained for referential integrity. This prevents your application database from having orphaned records if it uses sub as a foreign key.
Integration best practices
Section titled “Integration best practices”| Practice | Why |
|---|---|
| Store your sector ID in an environment variable | Avoid hardcoding it; makes environment-switching trivial |
| Store API keys in a secrets manager, not source code | API keys grant admin access to your sector |
| Always verify tokens server-side | Client-side JWT decoding is not verification |
Use sub (not email) as the foreign key in your database | Emails can change; sub is stable and permanent |
| Configure Allowed Origins before testing the login widget | Without a matching origin, all browser-based login attempts are blocked — this is intentional and a security feature |
| Remove development CORS origins before going to production | localhost:5173 should not be an allowed origin in prod |
| Rotate RSA keys if the private key is ever exposed | Existing tokens become forgeable with a compromised key |
| Disable self sign-up for internal or B2B applications | Only allow the user population you control |
Why allowed origins are required
Section titled “Why allowed origins are required”SpartanAuth enforces per-sector origin validation on all authentication endpoints (password, OTP, WebAuthn, OAuth). This prevents a phishing attack where a malicious actor registers their own sector, whitelists an attacker-controlled site, and points the login widget at your sector’s ID to intercept your users’ credentials.
The consequence is that any browser-based login attempt from an origin not listed in your sector’s Domain or Allowed Origins will receive a 403 Forbidden response. This is by design — configure your origins and the widget will work immediately.