A browser-based zero-trust file management dashboard. Every request is independently authenticated. Unauthenticated users see the file list but not file names or content — all data is AES-256-CBC encrypted until you log in. Every access attempt is recorded in a live activity log.
Prerequisites: Python 3.8+
make webOpens at http://127.0.0.1:8080. On first run (or whenever requirements.txt changes) the Makefile installs all dependencies automatically — no manual pip install needed.
| Username | Password | Tier | Permissions |
|---|---|---|---|
admin |
admin123 |
Admin | Full access — create, edit, delete, approve, repair, reset |
general |
gen789 |
General | Edit existing files; delete unapproved files; cannot create or delete approved files |
viewer |
view456 |
Viewer | Read-only; approved files only |
Override at runtime: ADMIN_PASSWORD, GENERAL_PASSWORD, VIEWER_PASSWORD.
| Feature | Behaviour |
|---|---|
| Zero-trust auth | Every API request independently verifies the session token |
| AES-256-CBC encryption | Unauthenticated requests receive a ciphertext blob, not readable data |
| Tiered access control | Three roles — Admin, General, Viewer — each with distinct permissions |
| File approval system | New files start unapproved (only Admin/General can see them); Admin must approve before Viewers can access |
| File integrity monitoring | SHA-256 hash of each file is compared against the original on every read |
| File regeneration | All files auto-restore on server start; individual repair and full reset available |
| Activity log | Every access attempt — authenticated or not — is recorded and displayed |
| Session tokens | 256-bit random tokens, server-side only, 1-hour expiry |
┌────────────────────────────────────────────────────────────────┐
│ MCP Security Gateway [● admin (admin)] [Logout] │
├──────────────────┬─────────────────────────────────────────────┤
│ FILE STORE 5 │ secrets.env [⚠ TAMPERED] │
│ ───────────── │ ───────────────────────────────────────── │
│ ● config.json │ DATABASE_URL=postgresql://... │
│ ⚠ secrets.env │ AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE │
│ ● user_db.csv │ ... │
│ ● audit.txt │ [🔍 Check] [↺ Repair] [🗑 Delete] │
│ ● enc_keys.txt │ │
│ ───────────── │ │
│ [+ Add File] │ │
│ [⚡ Scan] [↺ Reset All] │
├──────────────────┴─────────────────────────────────────────────┤
│ ACTIVITY LOG [↻] │
│ 14:05:22 admin write_file filestore/secrets written… │
│ 14:05:10 admin list_files filestore success… │
└────────────────────────────────────────────────────────────────┘
- File count is visible in the sidebar header
- File names are masked (
████████████) — count reveals files exist, nothing more - Clicking any file shows the AES-256 encrypted blob, not the content
- Activity log is hidden entirely
| Button | Who | What it does |
|---|---|---|
| Select file | any | View content; integrity badge shown next to filename (✓ intact / ⚠ TAMPERED / ◎ pending) |
| ✏️ Edit → 💾 Save | General, Admin | Edit content in-browser and save |
| 🗑 Delete | Admin (any); General (unapproved only) | Remove file from the store |
| 🔍 Check | any auth | Re-hash and compare against original SHA-256 |
| ✓ Approve | Admin | Mark a pending file as approved, making it visible to all tiers |
| ↺ Repair | Admin | Restore one file to its original content |
| + Add File | Admin | Create a new file (starts unapproved) |
| ⚡ Scan | any auth | Scan all files and report any with hash mismatches |
| ↺ Reset All | Admin | Restore every file to original content at once |
Five pre-populated files simulate sensitive server data. All are automatically restored on every server start.
| File | Contents |
|---|---|
config.json |
Server config with database credentials and API keys |
secrets.env |
Environment variables including AWS keys and OAuth secrets |
user_database.csv |
User records with password hashes and API tokens |
audit_log.txt |
Historical access log with a brute-force attempt example |
encryption_keys.txt |
Key rotation schedule with AES-256-GCM and break-glass key |
make web
# Server starts at http://127.0.0.1:8080All state is in memory. Restarting the server resets every file to its original content and clears the session and activity log.
1. Encryption — verify unauthenticated access is blocked
- Open
http://127.0.0.1:8080without logging in - Sidebar shows 5 files with masked names (
████████████) - Click any masked entry — the main panel shows the AES-256 ciphertext blob
- Log in as
viewer/view456 - File names and content are now visible in plaintext
Expected: unauthenticated users cannot read any file content.
2. File integrity — detect and repair tampering
- Log in as
admin/admin123 - Select
secrets.env— integrity badge shows ✓ intact - Click ✏️ Edit, change a line (e.g. append
# TAMPERED), click 💾 Save - Integrity badge immediately changes to ⚠ TAMPERED; sidebar dot turns red
- Click 🔍 Check — confirms hash mismatch with original SHA-256
- Click ↺ Repair — file content restored; badge returns to ✓ intact
Expected: any modification is detected by SHA-256 comparison; admin can repair individual files.
3. Bulk scan and reset
- Log in as
admin - Edit
config.jsonandaudit_log.txt(change any content, save each) - Click ⚡ Scan — toast reports "2 tampered: config.json, audit_log.txt"
- Click ↺ Reset All and confirm — toast reports all 5 files restored
Expected: scan identifies all modified files; reset restores everything in one action.
4. Access control — viewer cannot repair
- Log in as
viewer/view456 - Edit any file so it shows ⚠ TAMPERED
- The ↺ Repair button is not visible; ↺ Reset All button is not shown in the sidebar
Expected: repair and reset are restricted to the admin role.
5. Activity log — audit trail
- Open the page without logging in and click a few masked file entries
- Log in as
admin - The activity log shows the earlier unauthenticated attempts, tagged
[UNAUTH]
Expected: all access attempts are logged regardless of authentication state.
6. Attack simulation — automated attacker scenario
- Click ⚡ Simulate Attack in the header (no login required)
- The panel runs 7 steps automatically:
- Unauthenticated file list → Blocked (masked names only)
- Unauthenticated file read → Blocked (AES-256 ciphertext)
- Brute-force login with wrong passwords → Blocked
- Viewer login with correct credentials → Visible (token obtained)
- File tamper as viewer → Visible (viewer can write)
- Audit log read as viewer → Visible (viewer can see log)
- Viewer logout → token invalidated
- After the run, click View Activity Log to see every step recorded in the audit trail
Expected: each step is tagged Blocked, Visible, or Exposed with a one-line explanation; the full scenario is captured in the activity log.
| Method | Path | Auth | Description |
|---|---|---|---|
POST |
/api/auth/login |
— | Authenticate; returns session token |
POST |
/api/auth/logout |
required | Invalidate session |
GET |
/api/files |
optional | List files (names masked if unauthenticated; unapproved hidden from Viewer) |
GET |
/api/files/{name} |
optional | Read file (encrypted if unauthenticated; unapproved blocked for Viewer) |
PUT |
/api/files/{name} |
General, Admin | Write existing file (General); create or write file (Admin) |
DELETE |
/api/files/{name} |
General (unapproved only), Admin | Delete a file |
GET |
/api/files/{name}/integrity |
required | Check SHA-256 against original |
POST |
/api/files/{name}/approve |
Admin | Approve a pending file |
POST |
/api/files/{name}/repair |
Admin | Restore one file to original |
GET |
/api/scan |
required | Scan all files for tampering |
POST |
/api/reset |
Admin | Restore all files to original |
GET |
/api/activity |
required | Full activity log (most recent first) |
MCP-Security-Simulation/
├── webapp.py # FastAPI server — REST API, config, audit log, serves the SPA
├── static/
│ └── index.html # Single-page web UI (self-contained HTML/CSS/JS)
├── filestore.py # In-memory file store with SHA-256 integrity monitoring
├── auth.py # AuthManager — bcrypt password hashing, session tokens
├── crypto.py # CryptoManager — AES-256-CBC encryption, HMAC-SHA256 signing
├── requirements.txt # Python dependencies
└── Makefile # make web
| Variable | Default | Description |
|---|---|---|
ADMIN_PASSWORD |
admin123 |
Password for the admin account |
GENERAL_PASSWORD |
gen789 |
Password for the general account |
VIEWER_PASSWORD |
view456 |
Password for the viewer account |
MCP_ENCRYPTION_KEY |
mcp-v2-demo-key-change-in-prod!! |
32-char AES-256 key |
SESSION_DURATION_SECONDS |
3600 |
Token lifetime in seconds |