A secure file sharing system implementing Multi-Level Security (MLS), Role-Based Access Control (RBAC), and client-side encryption following strict educational security guidelines.
- Multi-Level Security (MLS): Bell-LaPadula model implementation with hierarchical levels and departmental categories
- Role-Based Access Control (RBAC): Administrator, Security Officer, Trusted Officer, User, and Auditor roles. Role tokens are mutually exclusive: the bootstrap Administrator cannot receive tokens, and Security Officer, Trusted Officer, Auditor, and User tokens cannot be stacked together. The backend rejects incompatible token issuance; the CLI lets you select from existing tokens but cannot bypass these constraints. Clearance tokens are also selectable: you may hold multiple active clearances, but the effective clearance for an action is the first one in your JWT unless you explicitly override it (e.g., via CLI selection).
- Client-Side Encryption: RSA-4096 key pairs for end-to-end encryption with password-encrypted private key storage
- Dual Cipher Support: Two cipher modes as per specification - AES-256-GCM and ChaCha20 + HMAC-SHA256 (Encrypt-then-MAC)
- Department-Based Access Control: Compartmentalized access to organizational departments
- Time-Limited Security Clearances: Cryptographically signed clearance tokens with expiration
- Secure Authentication: One-time password activation and session management
- Encrypted File Transfers: MLS-enforced upload/download with public or user-specific shares and expiry
- Public shares: Only UNCLASSIFIED public links are freely downloadable; higher classifications still require MLS clearance (but no per-recipient key).
- System Signing Keys: Backend signs clearance/role tokens with a configured RSA key pair (
SIGNING_PRIVATE_KEY_PATH/SIGNING_PUBLIC_KEY_PATH, e.g.,app/signing_keys/β¦) - Strong Password Hashing: User credentials hashed with PBKDF2-HMAC-SHA256 (600,000 iterations)
- TLS Support: Uvicorn can serve over HTTPS when
TLS_CERT_PATHandTLS_KEY_PATHare set, or place Nginx in front usingdeployment/nginx.conf(CLI defaults to HTTPS and skips verification in the self-signed setup)
- Nginx reverse proxy config:
deployment/nginx.conf(HTTPS termination + HTTPβHTTPS redirect) mounted at/etc/nginx/nginx.confin thenginxservice. - Dev CA + cert generator:
deployment/generate-certs.sh(writesdeployment/certs/ca.crt,server.crt, andserver.keyby default). Only the server cert/key are mounted into Nginx; clients/CLI should trustca.crtlocally. - Docker assets: root
Dockerfile,docker-compose.yml, andentrypoint.sh. Compose mountsdeployment/certsinto Nginx at/etc/nginx/certsand exposesapi:8000+nginx:80/443.- Run with
docker compose up --build.
- Run with
deployment/nginx.confterminates TLS and proxies toapi:8000(service name indocker-compose.yml).- Generate CA + server cert:
bash deployment/generate-certs.sh(createsdeployment/certs/ca.crt,server.crt, andserver.keywith SAN for localhost/127.0.0.1). - Compose mounts only
server.crtandserver.keyat/etc/nginx/certs; adjust paths insidenginx.confif you change the filenames. - Clients/CLI can trust
ca.crt(defaultVERIFY_SSLpoints to it); no HTTP fallback.
The system follows a clean architecture pattern with clear separation of concerns:
βββ app/
β βββ models/ # SQLAlchemy ORM models (users, clearances, keypairs, audits, file transfers)
β βββ services/ # Business logic (clearance, transfers, audit, users, roles, keypairs)
β βββ routes/ # FastAPI routers mounted at `/api/*` (auth, users, departments, audit, transfers)
β βββ shcemas/ # Pydantic request/response schemas (typo kept for compatibility)
β βββ utils/ # Database/session, RBAC helpers, crypto utilities
βββ app/main.py # FastAPI application wiring routers (entrypoint for uvicorn)
βββ requirements.txt # Python dependencies
- Python CLI (
cli/) performs all end-to-end cryptography on the client: RSA-4096 keygen, password-encrypted private vault, symmetric file encryption (AES-256-GCM or ChaCha20+HMAC), and recipient key wrapping. - Token selection: supports choosing role/clearance tokens via stored JWT payload, sending them in
X-Role-Token/X-Clearance-Token. - Entry points:
python cli/secureshare_cli.py(interactive) andpython cli/scriptable_secureshare_cli.py(for scripted use). Install deps withpip install -r cli/requirements.txt. - Configuration: see
cli/config.py(DEFAULT_BASE_URL,VERIFY_SSL,KEYS_DIR,SESSION_PATH). Keys are stored locally underKEYS_DIR; server never sees plaintext keys.
- User login with credential validation
- Account activation using one-time passwords
- User logout functionality
- Endpoints:
POST /auth/login,POST /auth/activate,POST /auth/logout
- Department creation and deletion (Administrator only)
- Department listing for access control
- Endpoints:
POST /departments,GET /departments,DELETE /departments/{deptId}
- User creation with OTP generation (Administrator only)
- User listing and retrieval (Administrator, Security Officer)
- User role management (Security Officer, Administrator)
- Security clearance issuance and revocation (Security Officer only)
- Public key distribution for encryption (All authenticated users)
- Private key vault management (User self-service)
- User profile management (User self-service)
- All 12 endpoints specified in guidelines implemented
- User Model: Complete role hierarchy and permission system
- Department Model: Organizational units for MLS categories
- UserClearance Model: Time-limited, signed security clearances with Bell-LaPadula enforcement
- UserKeyPair Model: RSA-4096 key storage with client-side encryption
- UserService: User management, role validation, permission checks
- ClearanceService: MLS enforcement, Bell-LaPadula rules, clearance lifecycle
- DepartmentService: Department CRUD with security validation
- KeypairService: RSA key generation, encryption, vault management
- FileTransferService: Encrypted upload/download storage, MLS read/write enforcement, transfer lifecycle
- Comprehensive Pydantic schemas for all entities
- Input validation and output serialization
- Type safety and data integrity
Seed the database with one user per role for manual testing:
- Run
uvicorn app.main:app --reload --host 127.0.0.1 --port 8000to start the API locally (usesapp/main.py; no rootapp.pyentrypoint). - To seed manually, run
python3 deployment/db-start/populate_db.pyfrom the project root. - Creates accounts with emails
admin@example.com,security@example.com,trusted@example.com,auditor@example.com,user@example.com. - Default password for all accounts:
TestPassword123!. - Existing users are left untouched; role tokens are issued using the first administrator found.
- Copy
.env.exampleto.envand adjust values (DB path, signing key paths, TLS cert/key if terminating TLS at uvicorn or via Nginx). - Build and run with compose:
docker compose up -d --build - API will be available at
http://localhost:8000; database stored in thesecureshare-datavolume (mounted at/datain the container). - Container startup ensures tables exist and runs
populate_db.pyso seed users are always present (idempotent).
- Create and activate a virtualenv.
- Install deps:
pip install -r app/requirements.txt - Configure env (see below) and run:
uvicorn app.main:app --reload --host 127.0.0.1 --port 8000 - Seed test data (optional):
python deployment/db-start/populate_db.py
Key variables referenced by the app:
DATABASE_URL: e.g.,sqlite:///./secureshare.dbFILE_STORAGE_PATH: path for encrypted blobs (defaultstorage/transfers)SIGNING_PRIVATE_KEY_PATH/SIGNING_PUBLIC_KEY_PATH: RSA keys for signing tokensJWT_SECRET: HS256 secret for access tokens (use strong value in production)ACCESS_TOKEN_EXPIRE_MINUTES: token lifetime (default 60)TLS_CERT_PATH/TLS_KEY_PATH: for direct HTTPS via uvicorn (optional if using Nginx)CLEANUP_INTERVAL_SECONDS: expired-transfer cleanup interval (default 900)- CLI-side:
DEFAULT_BASE_URL,VERIFY_SSL,KEYS_DIRincli/config.py
- Security Levels: UNCLASSIFIED β CONFIDENTIAL β SECRET β TOP_SECRET
- Security Categories: Department-based compartmentalization
- Simple Security Property: No read up (Level(Subject) β₯ Level(Object))
- Star Property: No write down (Level(Subject) β€ Level(Object))
- Category Enforcement: Department subset/superset rules
| Role | Permissions |
|---|---|
| Administrator | Full system access, user/department management, cannot be modified |
| Security Officer | Clearance issuance/revocation, user role assignment |
| Trusted Officer | Emergency MLS bypass with mandatory justification |
| User | Basic file access within clearance constraints |
| Auditor | Read-only audit log access and validation |
- RSA-4096 key pairs per user
- Client-side private key encryption using PBKDF2-derived keys
- Server-side public key distribution for inter-user encryption
- Password-encrypted key vault for cross-device synchronization
Two cipher modes are supported for file encryption:
| Cipher Mode | Algorithm | Integrity | Notes |
|---|---|---|---|
| AES-256-GCM | AES-256 in GCM mode | Built-in AEAD | Default, NIST-approved |
| ChaCha20-HMAC-SHA256 | ChaCha20-Poly1305 + HMAC | Encrypt-then-MAC | Alternative for non-AES environments |
Both modes provide:
- 256-bit symmetric encryption
- Authenticated encryption (integrity protection)
- Random nonce/IV per file
- Hybrid encryption: file encrypted with symmetric key, key encrypted with recipient's RSA public key
- Dev CA + server certs:
deployment/generate-certs.shmintsca.crt/ca.keyand a server leafserver.crt/server.keywith SANs for localhost/127.0.0.1. The CA signs the server cert; do not regenerate the CA on every run. - Termination: Nginx listens on 443 and serves
server.crt/server.keyfromdeployment/certs(mounted at/etc/nginx/certs). No HTTP fallback. - Trust: Clients/CLI should validate against
ca.crt(defaultVERIFY_SSLpoints there). Browsers will warn unless you import the CA; for CLI/tests, pass the CA bundle. - Root CA container: Not used hereβrunning a CA as a separate long-lived container adds little security unless you also harden it (HSM, strict access, no network). For dev, keeping
ca.keyoffline/tightly permissioned and only mounting the leaf cert/key into Nginx is simpler and avoids expanding the attack surface. In case of scaling of more servers it would make sense.
- Each audit entry stores the previous hash and its own SHA-256 over
(event_type|action|actor_id|created_at|prev_hash|details), so any insertion/removal/edit breaks the chain on validation. - Auditor validations sign the previous entryβs hash with the auditorβs key; signatures are checked against stored public keys.
- Tamper detection depends on protecting the DB/log store and the signing/auditor keys (e.g., backups with integrity checks, restricted access, off-box log shipping) to prevent wholesale replacement. As-is, an attacker with DB + key control could rewrite the entire log and recompute hashes; hardening options include append-only/WORM storage, off-site immutable backups, or anchoring entry hashes in an external trusted system (e.g., HSM or ledger) to make wholesale tampering detectable.
- Backend Framework: FastAPI 0.104.1
- Database: SQLite with SQLAlchemy 2.0.23
- Cryptography: Python Cryptography 41.0.7 (RSA-4096)
- Data Validation: Pydantic 2.5.0
- Server: Uvicorn 0.24.0
- Environment: Python-dotenv 1.0.0
- Storage: Set
FILE_STORAGE_PATHto control where encrypted blobs are stored (defaults tostorage/transfers). - MLS enforcement: Uploads require
ClearanceService.can_write_file_with_classification; downloads requirecan_read_file_with_classificationunless owner/public. - Public links: UNCLASSIFIED public shares can be downloaded without clearance; public shares at higher classifications still require the caller to pass MLS checks (no per-recipient key needed once cleared).
- Endpoints:
GET /api/transfersβ list callerβs transfersPOST /api/transfersβ multipart upload (file,classification_level,departmentsJSON list string,is_public, optionalencrypted_file_keysJSON map,expires_atISO,integrity_hash)GET /api/transfers/{transferId}β metadata plus callerβs encrypted key (if present)DELETE /api/transfers/{transferId}β delete metadata and blob (uploader or admin)GET /api/download/{transferId}β download encrypted blob
- Metadata: Stores classification level, department labels, expiry, optional integrity hash, share token, and per-recipient encrypted keys (for non-public shares).
- Auth:
POST /api/auth/login,POST /api/auth/activate,POST /api/auth/logout - Departments:
POST /api/departments,GET /api/departments,DELETE /api/departments/{deptId} - Users/Roles:
POST /api/users,GET /api/users,DELETE /api/users/{userId},PUT /api/users/{userId}/role,PUT /api/users/{userId}/role/revoke/{tokenId} - Clearances:
PUT /api/users/{userId}/clearance,GET /api/users/{userId}/clearance,PUT /api/users/{userId}/revoke/{tokenId} - Audit:
GET /api/audit/log,PUT /api/audit/validate - File Transfers:
GET /api/transfers,POST /api/transfers,GET /api/transfers/{transferId},DELETE /api/transfers/{transferId},GET /api/download/{transferId}