Principle:Neuml Txtai API Security
Overview
txtai secures its REST API endpoints using token-based authentication implemented through FastAPI's dependency injection system. When a security token is configured, every incoming HTTP request must include a valid Authorization header. The server compares a SHA-256 hash of the provided token against the stored hash, ensuring that the plaintext token is never persisted on the server side.
This design provides a lightweight but effective authentication layer suitable for protecting deployed txtai API instances.
Theoretical Foundation
Bearer Token Authentication
txtai implements the Bearer token authentication scheme as defined in RFC 6750. In this scheme:
- The client obtains a secret token (shared out-of-band)
- Each API request includes the header:
Authorization: Bearer <token> - The server validates the token before processing the request
- If validation fails, the server returns HTTP 401 Unauthorized
This is a stateless authentication mechanism -- the server does not maintain sessions. Each request is independently validated, making it well-suited for API deployments where clients may be distributed scripts, applications, or microservices.
SHA-256 Token Hashing
Rather than storing the plaintext token for comparison, txtai stores only the SHA-256 hash of the expected token. When a request arrives:
- The
Authorizationheader value is extracted - The
Bearerprefix is stripped (if present) - The remaining token string is hashed with SHA-256
- The resulting hash is compared to the stored hash
This approach follows the same principle used in password storage: even if the server's configuration is exposed, the actual token cannot be recovered from the hash. The server operator generates the SHA-256 hash of their chosen token and stores that hash in the configuration or environment variable.
FastAPI Dependency Injection
txtai leverages FastAPI's dependency injection system to apply authentication globally. The Authorization class is registered as a dependency on the FastAPI application itself:
dependencies = [Depends(Authorization(token))]
app = FastAPI(dependencies=dependencies)
When dependencies are attached at the application level, FastAPI automatically calls them for every incoming request before the route handler executes. This ensures:
- Uniform enforcement: no endpoint can accidentally bypass authentication
- Separation of concerns: route handlers do not contain authentication logic
- Composability: multiple dependencies can be chained (e.g., token auth + rate limiting)
Security Architecture
The authentication flow proceeds as follows:
- Configuration: The operator sets the
TOKENenvironment variable to the SHA-256 hash of the desired secret token - Startup: The
create()function detects theTOKENenvironment variable and registers anAuthorizationdependency - Request: A client sends a request with
Authorization: Bearer my-secret-token - Validation: The
Authorization.__call__method extracts the header, computes SHA-256 of the provided token, and compares it to the stored hash - Result: If hashes match, the request proceeds. If not, HTTP 401 is returned.
| Step | Component | Action |
|---|---|---|
| Token setup | Operator | Generates SHA-256 hash, sets TOKEN env var
|
| Dependency registration | create() |
Creates Authorization instance, adds as FastAPI dependency
|
| Header extraction | Authorization.__call__ |
Reads Authorization header via FastAPI Header
|
| Hash comparison | Authorization.digest |
Computes SHA-256 of provided token, compares to stored hash |
| Rejection | FastAPI | Returns HTTP 401 with "Invalid Authorization Token" detail
|
Token Generation
To generate the SHA-256 hash for a token, operators can use Python:
import hashlib
token = "my-secret-token"
hashed = hashlib.sha256(token.encode("utf-8")).hexdigest()
print(hashed)
# Set this as TOKEN environment variable
Or from the command line:
echo -n "my-secret-token" | sha256sum
Custom Dependencies
Beyond the built-in token authorization, txtai supports custom dependencies via the DEPENDENCIES environment variable. This is a comma-separated list of fully qualified Python class names. Each class is instantiated and added as a FastAPI dependency, enabling:
- Custom OAuth2 integrations
- IP-based access control
- Rate limiting middleware
- Request logging or auditing
Design Considerations
Why Not OAuth2 or JWT
txtai's built-in authentication is deliberately simple:
- Single-token auth has near-zero operational overhead -- no token issuance server, no key rotation infrastructure, no token expiration logic
- It is sufficient for the common case of protecting an internal API or a cloud-deployed model service
- For production deployments requiring more sophisticated auth, the
DEPENDENCIESmechanism allows plugging in arbitrary authentication schemes
Optional Enforcement
Authentication is only enabled when the TOKEN environment variable is set. When omitted, the API runs without any authentication, which is appropriate for:
- Local development
- Trusted network deployments
- Environments where authentication is handled by a reverse proxy or API gateway
See Also
- Neuml_Txtai_Authorization_Init - Implementation of the
Authorizationclass - Neuml_Txtai_API_Server_Bootstrap - How security dependencies are registered during server startup
- Neuml_Txtai_Production_Deployment - Security considerations in production environments