Auth: semantic-doc-segmenter
Mechanism
All protected endpoints use HS256 JWT bearer tokens.
Implementation: app/auth/jwt_bearer.py, class JWTBearer (extends fastapi.security.HTTPBearer).
Token requirements
The token must be a signed JWT with:
- Algorithm: HS256 (configurable via
JWT_ALGORITHM, defaultHS256) - Secret:
JWT_SECRETenv var (default"secret"-- must be overridden in production) - Required claim:
"role": "admin"-- any other role value is rejected
Example payload:
{
"sub": "1234567890",
"name": "Stan",
"role": "admin",
"iat": 1704024945
}
The JWTBearer class currently only allows role == "admin". The allowed_roles constructor parameter exists but the inner _validate_jwt method only passes "admin" tokens regardless of what roles are passed to the constructor.
Protected routes
Every route in all three routers uses dependencies=[Depends(JWTBearer(allowed_roles=["admin"]))]:
POST /jobsGET /jobs/GET /jobs/{jobid}PATCH /jobs/{jobid}(cancel)DELETE /jobs/{jobid}GET /documents/GET /documents/{documentid}GET /documents/{documentid}/segmentsGET /documents/{documentid}/segments/{segmentid}GET /debug/jobs/{job_id}GET /debug/healthGET /debug/health_with_details
Unprotected routes
GET /-- returns service name and version
Error responses
| Condition | HTTP status | Detail |
|---|---|---|
No Authorization header | 403 | "Invalid authorization code." |
| Non-Bearer scheme | 403 | "Invalid authentication scheme." |
| Invalid or expired token | 403 | "Invalid token or expired token." |
Role not admin | 403 | "Invalid token or expired token." |
Configuration
| Env var | Default | Notes |
|---|---|---|
JWT_SECRET | secret | Shared HMAC secret. Must be a strong random value in production. |
JWT_ALGORITHM | HS256 | PyJWT algorithm identifier. |
No token expiry enforcement
jwt.decode() is called without an options={"verify_exp": True} override -- PyJWT verifies expiry by default when the exp claim is present. If the token has no exp claim it never expires. Callers should embed an exp claim in tokens intended for production use.