Skip to content

Commit 8ab2e6a

Browse files
authored
Enhance README with architecture and security details
Expanded the README to provide detailed architecture, security design, and usage instructions for the secure notes API.
1 parent 7802d7b commit 8ab2e6a

1 file changed

Lines changed: 177 additions & 21 deletions

File tree

README.md

Lines changed: 177 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,183 @@
11
# secure-notes-api
2-
A secure-by-design REST API for encrypted-at-rest notes, with JWT auth, password hashing, basic security headers, Docker, tests, and CI.
32

4-
# vaultlight-secure-notes-api
3+
Architecture and Security Design
54

6-
A secure notes API built with FastAPI:
7-
- JWT authentication
8-
- Password hashing (bcrypt)
9-
- Notes encrypted at rest (Fernet)
10-
- SQLite for demo, easy to swap to Postgres
11-
- Docker + docker-compose
12-
- Tests + CI
5+
The Secure Notes API is designed as a small but realistic example of a security-aware backend service. The application allows authenticated users to store and retrieve personal notes while ensuring that sensitive information is protected using modern security practices. The architecture intentionally emphasizes defensive design, clear data boundaries, and responsible credential management.
136

7+
System Overview
8+
9+
The system consists of a REST API built with FastAPI, a lightweight and high-performance Python framework for building web services. The API exposes endpoints for user registration, authentication, and note management. Internally, the service separates authentication logic, encryption logic, database access, and API routing to maintain clean architectural boundaries.
10+
11+
At a high level, the workflow operates as follows:
12+
13+
A user registers or logs in using the authentication endpoints.
14+
15+
The system validates credentials and issues a signed JSON Web Token (JWT).
16+
17+
The client includes the token in future API requests.
18+
19+
Authenticated requests can create, retrieve, or delete notes.
20+
21+
Note content is encrypted before it is written to the database.
22+
23+
When a note is retrieved, the system decrypts the content before returning it to the user.
24+
25+
This flow ensures that authentication, authorization, and data protection occur at distinct stages of request processing.
26+
27+
Authentication Model
28+
29+
Authentication is implemented using JSON Web Tokens (JWT). After a successful login, the server generates a signed token that represents the authenticated user. The token includes a short expiration window and is verified on every protected API request.
30+
31+
Using token-based authentication provides several benefits:
32+
33+
Stateless authentication suitable for distributed systems
34+
35+
Clear separation between authentication and application logic
36+
37+
Reduced reliance on server-side session storage
38+
39+
Compatibility with modern API clients and microservices
40+
41+
The token payload contains the user identity and expiration timestamp, and the signature is verified using a server-side secret.
42+
43+
Password Security
44+
45+
User passwords are never stored in plaintext. Instead, they are processed using bcrypt hashing through the passlib library. Bcrypt is intentionally computationally expensive, which significantly reduces the effectiveness of brute-force password attacks.
46+
47+
The authentication workflow follows these steps:
48+
49+
The user submits a password during registration.
50+
51+
The password is hashed using bcrypt.
52+
53+
The hash is stored in the database.
54+
55+
During login, the submitted password is verified against the stored hash.
56+
57+
Because bcrypt includes built-in salting, identical passwords do not produce identical hashes, which helps mitigate rainbow table attacks.
58+
59+
Encryption at Rest
60+
61+
One of the primary goals of this project is to demonstrate application-level encryption of sensitive data.
62+
63+
The content of each note is encrypted using the Fernet symmetric encryption scheme provided by the cryptography library. This encryption occurs before the data is written to the database.
64+
65+
The workflow is as follows:
66+
67+
A user submits note content.
68+
69+
The application encrypts the content using a Fernet key.
70+
71+
The encrypted ciphertext is stored in the database.
72+
73+
When the note is retrieved, the ciphertext is decrypted before returning the response.
74+
75+
This approach ensures that even if the database is accessed directly, the stored note contents remain unreadable without the encryption key.
76+
77+
In a production environment, encryption keys should be managed using a dedicated key management system such as:
78+
79+
AWS KMS
80+
81+
Azure Key Vault
82+
83+
HashiCorp Vault
84+
85+
Hardware Security Modules (HSMs)
86+
87+
For demonstration purposes, this project loads the encryption key from environment configuration.
88+
89+
Database Design
90+
91+
The service uses SQLAlchemy as the Object Relational Mapper (ORM) to interact with the database. SQLAlchemy allows the application to define structured models for users and notes while keeping database access organized and maintainable.
92+
93+
The core models include:
94+
95+
User
96+
97+
Unique username
98+
99+
Password hash
100+
101+
Relationship to stored notes
102+
103+
Note
104+
105+
Note identifier
106+
107+
Owner identifier
108+
109+
Encrypted note content
110+
111+
Title metadata
112+
113+
SQLite is used as the default database to keep the project easy to run locally, but the architecture allows straightforward migration to PostgreSQL or other production-grade databases.
114+
115+
API Security Controls
116+
117+
Several defensive security practices are implemented throughout the service:
118+
119+
Credential Protection
120+
Passwords are hashed using bcrypt and never stored in plaintext.
121+
122+
Token-Based Authorization
123+
All note-related endpoints require a valid JWT access token.
124+
125+
Encryption at Rest
126+
Sensitive note content is encrypted before database storage.
127+
128+
Security Headers
129+
Basic HTTP security headers are applied to reduce common browser-based attack surfaces.
130+
131+
Environment-Based Secrets
132+
Sensitive configuration such as signing keys and encryption keys are loaded from environment variables rather than embedded in the source code.
133+
134+
Project Structure
135+
136+
The repository is organized to separate responsibilities clearly across modules.
137+
138+
app/
139+
config.py Application configuration
140+
db.py Database initialization
141+
models.py Database models
142+
schemas.py API request/response schemas
143+
security.py Authentication and encryption logic
144+
routes_auth.py Authentication endpoints
145+
routes_notes.py Note management endpoints
146+
main.py FastAPI application entry point
147+
148+
This separation makes the code easier to maintain, test, and extend.
149+
150+
Testing and Validation
151+
152+
The project includes automated tests that validate authentication and note management workflows. These tests confirm that:
153+
154+
Users can register and log in successfully
155+
156+
JWT authentication protects note endpoints
157+
158+
Notes are stored and retrieved correctly
159+
160+
Deletion operations behave as expected
161+
162+
Automated testing helps ensure the API behaves consistently as new features are added.
163+
164+
Intended Use
165+
166+
This project is intended as a learning and portfolio example demonstrating secure backend design patterns. It is not intended to be deployed as a production system without additional controls such as:
167+
168+
key management services
169+
170+
rate limiting
171+
172+
audit logging
173+
174+
database migrations
175+
176+
monitoring and alerting
177+
178+
infrastructure hardening
179+
180+
However, the architectural patterns used here mirror those commonly implemented in real-world secure API services.
14181
## Run locally
15182

16183
```bash
@@ -21,19 +188,8 @@ pip install -e ".[dev]"
21188
cp .env.example .env
22189
uvicorn app.main:app --reload
23190

24-
Open docs:
191+
## Run with Docker
25192

26-
http://127.0.0.1:8000/docs
27-
28-
Run with Docker
29193
cp .env.example .env
30194
docker compose up --build
31195
Security notes (intended design)
32-
33-
Passwords are hashed with bcrypt.
34-
35-
Notes are encrypted before storage using a server-side key (FERNET_KEY).
36-
37-
JWT access tokens are signed with JWT_SECRET.
38-
39-
This is a demo architecture; for production, move secrets to a vault/KMS, add refresh tokens, and use Postgres with migrations.

0 commit comments

Comments
 (0)