How FreeTodo Backend API Authentication and Authorization Works
FreeTodo does not implement user-level authentication or authorization; its FastAPI endpoints are publicly accessible without tokens, relying only on network-level security while using stored API keys solely for external service integrations.
The freeu-group/lifetrace repository provides a personal productivity backend built with FastAPI. Unlike typical SaaS applications, FreeTodo operates without user authentication mechanisms, exposing its entire REST API to any client that can reach the server.
No User Authentication on REST Endpoints
FreeTodo intentionally omits user-oriented security layers. In lifetrace/routers/todo.py, lifetrace/routers/journal.py, and lifetrace/routers/event.py, endpoint declarations lack security parameters or Depends(get_current_user) dependencies. This design choice means no JWT validation, session cookies, or API key checks occur at the application layer.
The FastAPI application initializes in lifetrace/server.py without authentication middleware. Consequently, any request conforming to the OpenAPI schema receives a response. The system assumes deployment behind a trusted firewall or reverse proxy that handles access control.
Example: Accessing Public Endpoints
You can interact with todo items without providing credentials:
# Create a new todo item
curl -X POST http://localhost:8001/todo \
-H "Content-Type: application/json" \
-d '{
"title": "Buy milk",
"due": "2026-04-01T10:00:00",
"source": "user"
}'
The server accepts this request without an Authorization header because the router does not enforce authentication.
Service-Level API Keys for External Integrations
While FreeTodo exposes its own API openly, it requires authentication when communicating with third-party services. Configuration values in lifetrace/util/settings.py store Bearer tokens for LLM providers, ASR services, Dify, and Tavily. These credentials never authenticate end-users; they authorize outbound HTTP requests from the backend to external APIs.
Example: LLM Client Configuration
In lifetrace/llm/llm_client.py, the application retrieves the service key from settings:
client = OpenAI(
base_url=settings.llm.base_url,
api_key=settings.llm.api_key, # <-- token from config, not a user token
)
This token remains internal. When the server calls OpenAI or similar services, it includes the key in the Authorization header, but FreeTodo never exposes this header to its own clients.
Key Files in the Authentication Architecture
Understanding FreeTodo's security model requires examining these specific source files:
lifetrace/server.py: Initializes the FastAPI application with no authentication middleware attached.lifetrace/routers/*.py: All endpoint definitions across todo, journal, and event modules; none include user authentication dependencies.lifetrace/util/settings.py: Contains configuration for external service API keys used in outbound requests.lifetrace/llm/llm_client.pyandlifetrace/services/asr_client.py: Demonstrate how stored tokens authorize requests to external AI and speech recognition services.lifetrace/core/dependencies.py: Supplies database repository dependencies; contains no authentication logic.lifetrace/routers/config.py: Validates third-party API keys, returning HTTP 401 only when external credentials are invalid, not for missing client authentication.
Adding User Authentication (Illustrative Implementation)
If your deployment requires user-level security, you can extend FreeTodo by implementing a FastAPI dependency. Create a security module that validates JWT tokens:
# lifetrace/core/security.py
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
import jwt
bearer = HTTPBearer(auto_error=False)
def get_current_user(
credentials: HTTPAuthorizationCredentials = Depends(bearer),
) -> dict:
if credentials is None:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Missing token"
)
try:
payload = jwt.decode(
credentials.credentials,
"YOUR_SECRET",
algorithms=["HS256"]
)
except jwt.PyJWTError:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid token"
)
return payload
Protect specific routers by injecting the dependency:
from fastapi import APIRouter, Depends
from lifetrace.core.security import get_current_user
router = APIRouter()
@router.get("/secure-data", dependencies=[Depends(get_current_user)])
def read_secure():
return {"msg": "You are authenticated"}
Summary
- FreeTodo operates without user authentication: All endpoints in the lifetrace repository accept requests without tokens, cookies, or session validation.
- Network-level security is required: The application relies on firewalls or reverse proxies to restrict access since the FastAPI layer performs no authorization checks.
- External service tokens are configuration-driven: API keys for LLMs and ASR services reside in
lifetrace/util/settings.pyand authenticate only outbound requests. - Authentication can be added via dependencies: Implement a
get_current_userfunction using FastAPI'sDependssystem to introduce JWT or OAuth2 security if needed.
Frequently Asked Questions
Does FreeTodo require API keys for its own endpoints?
No. FreeTodo does not validate API keys, JWT tokens, or session cookies for incoming requests to its REST API. The endpoints in lifetrace/routers/ are publicly accessible by design.
How are external service credentials stored?
External API keys for services like OpenAI, Dify, and Tavily are stored in the application configuration via lifetrace/util/settings.py. These credentials are loaded at runtime and used internally by clients such as lifetrace/llm/llm_client.py to authorize outbound HTTP requests.
Is FreeTodo suitable for production use without authentication?
FreeTodo is intended for personal or trusted-network deployments. Without authentication middleware, exposing the server directly to the internet would allow anyone to read or modify data. Production deployments should place FreeTodo behind a VPN, firewall, or reverse proxy that handles access control.
What would it take to add JWT authentication to FreeTodo?
You would need to create a security dependency like get_current_user that validates JWT tokens using fastapi.security.HTTPBearer, then apply it to routers using dependencies=[Depends(get_current_user)]. The current codebase in lifetrace/server.py and lifetrace/routers/*.py contains no authentication logic, so this would be a greenfield addition.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →