EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
Secure Credential Management for RMM+PSA Platform

This guide covers secure setup and management of user credentials for production deployments.

🔐 Security Principles

NEVER hardcode passwords in:

  • Migration files
  • Source code
  • Environment variables (except encrypted secrets)
  • Git repositories

ALWAYS:

  • Prompt for passwords during setup
  • Generate strong random passwords when user doesn't provide one
  • Hash passwords with bcrypt (10+ rounds)
  • Save credentials to local files with chmod 600
  • Delete credential files after copying to password manager
  • Use SSL/TLS for all database connections

Initial Setup (Root Tenant & Admin)

After deploying the database schema, initialize the root tenant and admin user:

# Connect to your managed database
export DATABASE_URL="postgresql://user:pass@host:port/db?sslmode=require"
# Run initialization script
bash devops/digitalocean/init_root_tenant.sh

Prompts:

  1. Root tenant name (default: "Root MSP")
  2. Subdomain (default: "root")
  3. Admin email
  4. Admin full name
  5. Admin password (or press Enter to auto-generate)

Output:

  • Creates/updates root tenant with is_msp = true
  • Creates/updates admin user with hashed password
  • Saves credentials to devops/digitalocean/admin_credentials.txt (chmod 600)
  • Displays login URL and credentials

Example:

Root tenant name [Root MSP]: My MSP Company
Root tenant subdomain [root]: mymsp
Admin email: admin@mymsp.com
Admin full name [System Administrator]: John Smith
Admin password (min 8 chars, or leave empty to auto-generate):
[INFO] Generated password: aB3$xY9zQm2#pL7n
[WARN] Save this password securely! It will not be shown again.
========================================
✅ Root Tenant & Admin User Created
========================================
Tenant: My MSP Company (subdomain: mymsp)
Admin: John Smith <admin@mymsp.com>
Password: aB3$xY9zQm2#pL7n
⚠️ SAVE THESE CREDENTIALS SECURELY!
========================================
[INFO] Credentials saved to devops/digitalocean/admin_credentials.txt
[INFO] You can now log in at: https://demo.everydayoffice.au/login

Creating Additional Tenants

To create a new tenant (customer) with an admin user:

bash devops/digitalocean/create_tenant.sh

Prompts:

  1. Tenant name (e.g., "Acme Corporation")
  2. Subdomain (e.g., "acme")
  3. MSP status (yes/no)
  4. Admin email
  5. Admin full name
  6. Admin password (or auto-generate)

Example:

Tenant name: Acme Corporation
Subdomain: acme
Is this an MSP tenant? (y/N): n
Admin email: admin@acme.com
Admin full name: Jane Doe
Admin password (or leave empty): [auto-generated]
========================================
✅ Tenant Created Successfully
========================================
Tenant: Acme Corporation
Subdomain: acme
MSP: false
Admin User:
Name: Jane Doe
Email: admin@acme.com
Password: pQ8$mN4xRz7#vL2k
Login URL: https://demo.everydayoffice.au/login
Use subdomain: acme
⚠️ SAVE THESE CREDENTIALS SECURELY!
========================================

Resetting User Passwords

If a user forgets their password or you need to reset it (e.g., security incident):

bash devops/digitalocean/reset_user_password.sh user@example.com

Prompts:

  1. New password (or press Enter to auto-generate)

Example:

Resetting password for: admin@acme.com
New password (or leave empty to auto-generate):
[INFO] Generated password: zX6$nM9qPl3#vB8k
[WARN] Save this password securely!
========================================
✅ Password Updated Successfully
========================================
User: admin@acme.com
New Password: zX6$nM9qPl3#vB8k
⚠️ SAVE THIS PASSWORD SECURELY!
========================================

Password Requirements

All passwords must meet these criteria:

  • Minimum 8 characters (recommended: 16+)
  • Auto-generated passwords are 16 characters with high entropy
  • Hashed with bcrypt (cost factor 10)
  • Never stored in plaintext

Auto-generated password format:

  • 16 alphanumeric characters
  • Mix of uppercase, lowercase, and numbers
  • Secure random generation via openssl rand

Security Best Practices

1. Password Management

  • ✅ Use a password manager (1Password, Bitwarden, LastPass)
  • ✅ Store credentials immediately after generation
  • ✅ Delete local credential files after copying:
    rm -f devops/digitalocean/admin_credentials.txt
  • ✅ Never share passwords via email or chat
  • ✅ Use unique passwords for each tenant/user

2. Password Rotation

  • Rotate admin passwords every 90 days
  • Rotate after any security incident
  • Rotate when an admin leaves the organization
  • Use the reset_user_password.sh script for rotations

3. Multi-Factor Authentication (MFA)

  • Enable MFA for all admin accounts (if implemented)
  • Use TOTP apps (Google Authenticator, Authy)
  • Store backup codes securely

4. Access Control

  • Limit root/MSP tenant access to essential personnel
  • Use staff role for day-to-day operations
  • Review user access quarterly
  • Disable inactive accounts immediately

5. Audit Trail

  • Monitor failed login attempts
  • Log password changes
  • Review user activity regularly
  • Set up alerts for suspicious activity

Credential File Security

All scripts save credentials to local files with restrictive permissions:

# Files created:
devops/digitalocean/db_credentials.txt # Database connection
devops/digitalocean/admin_credentials.txt # Root admin user
# Permissions:
-rw------- (600) - readable only by owner

After setup:

  1. Copy credentials to password manager
  2. Delete local files:
    rm -f devops/digitalocean/*_credentials.txt
  3. Never commit credential files to git (already in .gitignore)

Troubleshooting

"bcrypt not found" error

Install bcrypt in your backend or globally:

# In backend directory
cd backend
npm install bcrypt
# Or globally
npm install -g bcrypt

"Could not connect to database"

  1. Check database firewall allows your IP
  2. Verify DATABASE_URL or .env variables
  3. Test connection:
    psql "$DATABASE_URL" -c "SELECT version();"

"User already exists" when creating tenant

The script uses ON CONFLICT DO UPDATE, so it's safe to re-run. If you want to create a new user instead, change the email address.

Password too weak

The scripts enforce minimum 8 characters. For production:

  • Use auto-generated passwords (16 chars)
  • Or provide strong passwords with mix of:
    • Uppercase letters
    • Lowercase letters
    • Numbers
    • Symbols

Emergency Access

If you lose root admin credentials:

  1. Connect directly to database:
    psql "$DATABASE_URL"
  2. Find the admin user:
    SELECT id, email, full_name FROM users WHERE role = 'admin' AND tenant_id = (SELECT id FROM tenants WHERE subdomain = 'root');
  3. Use the reset script with the email:
    bash devops/digitalocean/reset_user_password.sh admin@yourdomain.com

Integration with Backend

The backend expects bcrypt-hashed passwords in the users.password_hash column:

// Backend authentication (backend/routes/auth.js)
const bcrypt = require('bcrypt');
// Login
const match = await bcrypt.compare(plainPassword, user.password_hash);
// Change password
const hash = await bcrypt.hash(newPassword, 10);
await pool.query('UPDATE users SET password_hash = $1 WHERE id = $2', [hash, userId]);

All scripts use the same bcrypt configuration (cost factor 10) for consistency.


Last Updated: 4 November 2025
Status: ✅ Production-ready