Skip to content

Security & Safety Design

AMP Manager is designed with special consideration for students and junior developers.
This document explains the reasoning behind, and why certain safety decisions were made.

The Problem

When learning local development, students often:

  • Modify config files to "see what happens"
  • Accidentally delete or corrupt important files
  • Break Docker settings while experimenting
  • Lose hours of work trying to recover

AMP Manager implements multiple safety layers to prevent these issues.

Sync on Every Login

Every time a user logs in, AMP Manager runs 5 validation steps:

Why Not Cache?

Caching would be faster, but users wouldn't notice:

  • Docker stopped running
  • CA certificate expired
  • Domain configs broken

For local environments, seeing problems immediately is better than being fast.

Step-by-Step Safety Features

Step 1: Config Integrity Factory

What it does:

  • Copies clean versions of essential config files
  • Stores in users/ folder (encrypted)

Why:

  • If users break angie.conf, they can restore from factory backup
  • No need to re-download or reconfigure

Essential files captured:

  • docker-compose.yml
  • docker-compose.override.yml
  • config/angie.conf
  • config/default.local.conf
  • config/php.ini
  • config/db-init/01-grant-root.sql

Location: src/services/ConfigGuardService.ts

Step 2: Env Status Docker Factory

What it does:

  • Checks Docker is running
  • Verifies all required folders exist
  • Confirms mkcert is installed
  • Validates CA root exists

Why:

  • Prevents "why doesn't my site work?" when Docker isn't running
  • Shows clear errors instead of confusing failures
  • Catches missing tools before they cause issues

Toast Messages:

  • Docker not running -> "Open Docker Desktop to manage your local sites"
  • CA missing -> "Install CA in Settings to enable SSL"

Step 3: CA Status

What it does:

  • Validates mkcert certificate authority
  • Checks certificate expiration

Why:

  • Without valid CA, new domains won't have SSL
  • Students need working SSL to test HTTPS features

If missing:

  • Toast prompts user to install CA in Settings
  • Prevents confusing SSL errors later

Step 4: Scan Domains

What it does:

  • Reads Windows hosts file for .local domains
  • Checks AMP Manager's config folder
  • Validates SSL certificates exist

Why:

  • Syncs current system state to users/ folder
  • Shows domain health on dashboard
  • Catches orphaned domains (deleted files but still in hosts)

Step 5: Sync to JSON Files

What it does:

  • Updates all domain statuses in users/user_{username}/domain_status.json
  • Updates sites in users/user_{username}/sites.json
  • Stores last sync timestamp in users/user_{username}/settings.json
  • JSON files in users/ folder are the single source of truth for the UI
  • Ensures dashboard shows accurate information
  • Persists across app restarts

Defense in Depth

AMP Manager implements multiple security layers:

LayerProtectionFile
UACOS-level admin elevationWindows
nativeAllowListBlocks unauthorized Native API callsneutralino.config.json
AMP_TASKS whitelistOnly approved commands executablepublic/js/main.js
Batch dispatcherControlled command routingamp-tasks.bat

Why This Matters

AMP runs with elevated privileges (admin rights from UAC). If JavaScript is compromised (XSS attack), the allowlists prevent the attacker from:

  • Deleting arbitrary files
  • Running unauthorized commands
  • Accessing sensitive data

Data Persistence

JSON File Storage User Folder

All user data is stored in the users/user_{username}/ folder.
The user_ prefix avoids conflicts with MariaDB databases:

FileContentEncrypted?
users/user_{username}/user.jsonUser auth (salt + validation token)No
users/user_{username}/sites.jsonDomain configurationsNo
users/user_{username}/tags.jsonTagsNo
users/user_{username}/tunnels.jsonActive tunnelsNo
users/user_{username}/activity_logs.jsonActivity historyNo
users/user_{username}/domain_status.jsonDomain health statusNo
users/user_{username}/databases.jsonDatabase metadataNo
users/user_{username}/databases_cache.jsonDatabase cacheNo
users/user_{username}/notes.jsonNotesYES
users/user_{username}/credentials.jsonCredentialsYES
users/user_{username}/settings.jsonUser settingsYES
users/user_{username}/workflows.jsonWorkflowsYES
users/user_{username}/site_configs.jsonConfig backupsYES
config.jsonApp settings (lastUser + instanceId, pid, port, launchedAt)No

Why JSON Files?

  • Visible - Students can see their data with any text editor
  • Persistent - Survives app restarts (stored in app folder)
  • Portable - Easy to backup (copy users/ folder)
  • Secure - Sensitive data encrypted with AES-256-GCM

Security: Encryption

FeatureImplementation
AlgorithmAES-256-GCM
Key DerivationPBKDF2 (310,000 iterations)
SaltRandom 16 bytes per user
IVRandom 12 bytes per encryption

Where Data Lives

ComponentLocation
App folderAMP-Manager/users/ (Neutralino's app data path)
Neutralino storageAMP-Manager/.storage/ (for small settings)

Backup & Restore

Built-in Backup

Located in Settings -> Backup/Restore:

  • Export: Copies user_name/ folder to json file
  • Import: Restores from backup json

Factory Restore

Located in Docker -> Config Recovery:

  • Factory: Original config files from Step 1
  • Snapshots: Manual backups before destructive operations

How User Backup Works

The backup system does exactly what is expected: it merges multiple user JSON files into a single JSON file for portability.

Export Flow (Multiple → Single)

text
users/user_name/
├── sites.json        ─┐
├── notes.json         │
├── credentials.json ──┼──►  amp-backup-2026-04-20.json
├── workflows.json     │
└── tags.json        ──┘

Step-by-step:

StepActionCode
1Load ALL data from user JSON filesloadSitesJSON(), loadNotesJSON(), etc. (line 23-29)
2If "includeSensitive" checked: decrypt notes & credentialsdecryptWithKey() (lines 31-58)
3Merge into single object with metadata{ version, timestamp, sites, notes, credentials, workflows, tags } (lines 61-69)
4Save as single JSON fileamp-backup-2026-04-20.json

Import Flow (Single → Multiple)

text
amp-backup-2026-04-20.json  ──►  users/user_name/
                                      ├── sites.json
                                      ├── notes.json
                                      ├── credentials.json
                                      └── ...

Step-by-step:

StepActionCode
1Load JSON fileRead from file picker
2If overwrite: clear all user filessaveXxxJSON(username, []) (lines 73-80)
3Merge with existing dataloadXxxJSON() + [...existing, ...data] (lines 83-95)
4If notes/credentials need re-encryption: encrypt with current keyencryptWithKey() (lines 100-131)
5Save to individual JSON filessaveNotesJSON(), saveCredentialsJSON(), etc.

Key Points

FeatureHow It Works
Decryption on exportGets user's current session key to decrypt notes/credentials before saving to JSON
Re-encryption on importGets current session key to re-encrypt before saving to user files
Merge vs OverwriteImport has two modes: merge (add to existing) or overwrite (replace all)
PortabilitySingle JSON file is easy to transfer, share, or backup
Security warningIf "includeSensitive" is checked, backup contains plain-text secrets

Export JSON

Reads all encrypted user files → decrypts with session key → merges into one JSON → saves to file

Import JSON

Reads JSON file → merges with existing user files → re-encrypts sensitive data with current key → saves to individual files

This design keeps the portability of a single file while maintaining security through on-the-fly encryption/decryption.

Complete Data Deletion

Delete All Data Function

AMP Manager provides a complete data wipe function for testing or reset scenarios:

Function: deleteUserData(username) in src/lib/db.ts

What it deletes:

  • User-specific JSON files in users/user_{username}/
  • Updates config.json to clear lastUser

Location in UI: Settings -> Account -> "Delete All Data"

Use cases:

  • Complete app reset for fresh start
  • Testing clean installation scenarios
  • User wants to remove all data before giving away device
Danger

Warning: This action cannot be undone. All user data, domains, credentials, and settings will be permanently deleted.

Summary

Safety FeaturePurpose
Sequential syncPrevents race conditions
Factory backupOne-click restore
Always validatesCatches problems early
Defense-in-depthLimits damage from attacks
Per-user JSONData isolation

This design prioritizes reliability and stability, making it safe for users to learn through experimentation without breaking the app.

User State Restoration

On app startup, AMP Manager restores user state to enable JSON operations without re-login:

Flow:

  1. main.tsx loads config.json → gets lastUser
  2. Calls setCurrentUser(lastUser) in db.ts
  3. Global _currentUser enables ensureUser() for JSON operations

Why this matters:

  • Users need to re-login after app restart
  • JSON storage functions work immediately without auth errors
  • Dashboard loads correct user data on startup

Key files:

  • src/lib/db.ts:12-14 - setCurrentUser() function
  • src/lib/db.ts:28-31 - ensureUser() throws if not set
  • src/main.tsx:16-18 - Restores user on startup

Security note: The encryption key is NOT stored - users must re-login to decrypt encrypted files. Only the username is persisted in config.json.

Instance Monitoring

Watchdog

AMP Manager includes a built-in watchdog that monitors the app for Neutralino.js zombie states and auto-recovers.

How It Works

Instance Info Flow

StepFileAction
1main.tsxGenerate instanceId, get NL_PID
2db.ts:updateInstanceInfo()Save to config.json (merges with existing)
3AMPBridge.ts:killStaleWatchdogs()Cleanup stale watchdogs on startup
4AMPBridge.ts:spawnWatchdog()Spawn background process
5amp-tasks.bat :WATCHRead config.json, monitor PID, check exitFlag

config.json Contents

json
{
  "lastUser": "nuno",
  "instanceId": "amp-1234567890-abc123",
  "processName": "amp-manager-win_x64.exe",
  "pid": "12345",
  "exitFlag": false,
  "launchedAt": 1234567890123
}

Lock File Mechanism

Prevents duplicate watchdogs from running simultaneously:

%TEMP%\amp_watchdog.lock
StepAction
1Check if lock file exists → if yes, another watchdog running, exit
2Create empty lock file to claim "ownership"
3Run monitoring loop
4On exit: delete lock file

exitFlag Pattern

Distinguishes clean user exit from app crash:

ScenarioexitFlagResult
User clicks Xtrue (set by frontend)Watchdog cleans up lock, exits
App crashfalseWatchdog counts failures, restarts app

Why this matters:

  • User clicks X → app sets exitFlag → watchdog exits cleanly
  • App crashes → exitFlag never set → watchdog detects PID gone → restarts app

Clean Close Flow

When user clicks the X button:

typescript
// src/components/layout/Layout.tsx:245-277
const handleClose = async () => {
  // STEP 1: Set exitFlag = true
  const config = await loadConfigJSON() ?? {};
  config.exitFlag = true;
  config.exitTime = Date.now();
  await saveConfigJSON(config);

  // STEP 2: Delete lock file
  await window.Neutralino.os.execCommand({
    command: 'del "%TEMP%\amp_watchdog.lock" 2>nul'
  });

  // STEP 3: Exit app
  await window.Neutralino.app.exit();
};

Important: Merge Pattern

When updating config.json, always merge with existing data to preserve instance info.

WRONG DON'T do this:
typescript
// WRONG - overwrites entire config
await dataStorage.save('config.json', { lastUser: username });
CORRECT Use merge:
typescript
// CORRECT - merges with existing
const existing = await dataStorage.load('config.json') || {};
await dataStorage.save('config.json', { ...existing, lastUser: username });

Files that update config.json:

  • main.tsx - Saves instance info on startup
  • AuthContext.tsx - Saves lastUser on login/register/logout
  • db.ts:deleteUserData() - Clears lastUser on data deletion

All use the merge pattern to preserve instance info.

Why Watchdog Exists

ProblemSolution
NeutralinoJS single-threaded event loopWatchdog monitors from outside
Backend becomes unresponsive (zombie)PID check detects failure
serverOffline event unreliableIndependent 20s check cycle
App appears frozen but process runsForce restart after 3 failures
No way to distinguish exit vs crashexitFlag pattern enables clean detection

See Also

AMP Manager
Released under the MIT License.