PharmVault System Architecture
Project Name: PharmVault Tagline: Secure Digital Fortress Version: 1.0.0
PharmVault is a centralised digital vault designed for managing sensitive personal notes and confidential data.
Unlike standard CRUD applications, this system was architected with a security-first mindset. It operates on a Zero-Trust principle, assuming that the network layer may be compromised. Consequently, the application enforces strict data isolation per user, encrypts all content at rest, and allows access only via authenticated, stateless protocols.
*Technical Stack
The system is built on a standard Java enterprise stack selected for stability and security features:
Backend: Java 17 running Spring Boot 3.2.
Security: Spring Security 6 with a stateless JWT filter chain.
Database: Relational SQL (MySQL/PostgreSQL) for persistent storage.
ORM: Hibernate and Spring Data JPA for data mapping.
Encryption: AES-256 for data privacy and BCrypt for password hashing.
Build Tool: Apache Maven.
*High-Level Design
The application follows a Layered Monolithic Architecture. This ensures a clean separation of concerns where the API layer never touches the database directly.
*The Data Flow:
Client Layer: The user sends an HTTPS request with a JSON payload.
The Security Filter (The "Bouncer"): This is the first line of defense. The request is intercepted before it reaches any business logic. The filter checks the HTTP Header for a valid Bearer Token.
Controller Layer: If the token is valid, the request passes to the controller, which validates the input structure (DTOs).
Service Layer: This contains the core business logic. It performs ownership checks (verifying the user owns the data they are requesting) and handles encryption.
Persistence Layer: Finally, the encrypted binary data is stored in the database.
*Security Architecture
We utilise a multi-layered defense strategy to protect against common web vulnerabilities.
A. The Filter Chain Protocol
We strictly separate Authentication (verifying identity) from Authorization (verifying access).
The JwtAuthenticationFilter inspects every incoming request header. It validates the token's digital signature. If the signature is valid, the user's identity is loaded into the Security Context. Crucially, the Service Layer ignores any User ID sent in the request body (a common attack vector) and relies solely on the identity extracted from the verified token.
B. Data Isolation (Anti-IDOR)
Insecure Direct Object Reference (IDOR) is a common vulnerability where users can access another person's data by guessing an ID. We prevent this by enforcing strict ownership checks on every transaction.
For any action on a specific note (Get, Update, Delete), the service layer compares the ID of the currently logged-in user against the owner ID of the requested record. If they do not match, the transaction is rejected immediately with an Access Denied exception.
C. Encryption Strategy
Passwords: We use BCrypt with 10 rounds of salting. Plain-text passwords are never stored.
Content Data: Sensitive note content is encrypted using the AES-256 standard before it is written to the database. Even if the raw database file were stolen, the content would remain unreadable without the application keys.
*Database Schema Design
The database is normalized and uses foreign keys to maintain referential integrity.
-Users Table stores the unique identity of the account holder.
id: Primary Key (Auto-Increment or UUID)
username: Indexed for fast lookup
email: Unique constraint
password_hash: Securely hashed credential
-Notes Table stores the encrypted user data.
id: Primary Key
title: Nullable field for quick entries
content: BLOB/Text field containing the encrypted data
user_id: Foreign Key linking to the Users table
We implement an ON DELETE CASCADE constraint. This ensures that if a user account is deleted, all associated notes are immediately wiped from the system, preventing orphaned data and ensuring privacy compliance.
*API Design & Business Logic
Data Transfer Objects (DTOs) To prevent data leakage, we never expose raw database entities to the client. We use DTOs to strictly define what comes in (Request objects) and what goes out (Response objects). This ensures sensitive fields like password hashes or internal database IDs never leave the server.
Error Handling To prevent enumeration attacks, we use generic error messages for login failures. The system returns a standard "401 Unauthorized" response rather than specifying whether the username or the password was incorrect.
*Future Roadmap
Dockerization: Containerizing the application for easier cloud deployment.
Frontend Client: Building a React or Thymeleaf dashboard for visual interaction.
OAuth2 Integration: Adding support for Google and GitHub login providers.
Top comments (0)