Security Azure

TeamPass 3.2 Collaborative Password Manager on Ubuntu 24.04 on Azure User Guide

| Product: TeamPass 3.2 Collaborative Password Manager on Ubuntu 24.04 LTS on Azure

Overview

TeamPass is the open source collaborative password manager for teams. It keeps shared credentials in an encrypted vault organised as a folder tree, and grants access through granular per folder and per role rights, so each person sees only what their role allows. It covers the day to day of shared credential management: user groups and roles, item history, full audit logs of who viewed or changed what, one time view links for handing a secret to someone outside the vault, file attachments, a knowledge base, and password generation and expiry policies. Optional LDAP or Active Directory authentication and optional two factor authentication let it slot into an existing identity stack.

The cloudimg image ships TeamPass 3.2 served by nginx and PHP 8.3 FPM on a hardened, fully patched Ubuntu 24.04 LTS base, together with a bundled local MariaDB server so the appliance is complete and useful on its own. The bundled MariaDB listens only on the loopback interface (127.0.0.1:3306) and keeps its data on a dedicated Azure data disk, alongside the encryption saltkey and every encrypted attachment.

Because this is a password manager, the image is built to a stricter rule than most: it contains no vault at all. There is no database, no configuration file, no encryption key and no administrator account inside the image. TeamPass is installed onto your own VM on its first boot, so the saltkey, the database password and the administrator password are all generated there and exist nowhere else. Backed by 24/7 cloudimg support.

What is included:

  • TeamPass 3.2 served by nginx and PHP 8.3 FPM, managed by systemd
  • A bundled MariaDB server holding the encrypted vault, already installed and ready
  • A per VM encryption saltkey, database password and administrator password, all generated on first boot
  • No shipped vault and no shipped secret: the image contains no database, no settings file, no saltkey and no admin account, so there is nothing to leak
  • The install wizard is never reachable from the network, and is removed from the web root once the install completes
  • MariaDB bound to 127.0.0.1 only, never exposed to the network
  • A dedicated Azure data disk carrying the vault database, the saltkey that decrypts it, and encrypted file attachments
  • A systemd timer running TeamPass background tasks every minute

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a sensible starting point for a small team; move up to Standard_D2s_v3 for a larger vault or heavier use. NSG inbound: allow 22/tcp from your management network, 80/tcp for the application and 443/tcp if you terminate TLS on the VM. The bundled MariaDB is never exposed: it listens on 127.0.0.1 only, so port 3306 stays off the network.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for TeamPass by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22), HTTP (80) and HTTPS (443). Review the dedicated data disk on the Disks tab, then Review + create then Create.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name teampass \
  --image <marketplace-image-urn> \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Then open ports 80 and 443:

az vm open-port --resource-group <your-rg> --name teampass --port 80,443

Step 3 - Confirm the services are running

SSH in as azureuser and confirm nginx, PHP FPM, MariaDB and the first boot service are all active. Note that MariaDB listens only on 127.0.0.1:3306 while nginx serves TeamPass on port 80. The 127.0.0.1:8099 listener is the loopback only channel the first boot install uses; it is never reachable from outside the VM.

systemctl is-active nginx php8.3-fpm mariadb teampass-firstboot
ss -tlnp | grep -E ':80 |:3306 |:8099 ' | sed 's/  */ /g'

The nginx, php8.3-fpm, mariadb and teampass-firstboot services active, with nginx on port 80 and both MariaDB and the install listener bound to loopback only

Step 4 - Retrieve the per VM administrator password

Every VM installs its own TeamPass on first boot and generates its own administrator password, database password and encryption saltkey. The administrator login, the generated password and the application URL are written to a root only credentials file. Read it with sudo:

sudo cat /root/teampass-credentials.txt

The per VM TeamPass credentials file, showing the admin login user, the generated password masked, the application URL and the loopback database details

You sign in to TeamPass as user admin with the teampass.admin.pass value from this file. On the box itself you can also run sudo mysql to reach the database directly over the local socket without a password.

Step 5 - Sign in

Browse to http://<vm-public-ip>/. You land on the TeamPass sign in page. Enter the account admin and the password from Step 4.

The TeamPass sign in page showing the account and password fields and the log in button

The first time you sign in, TeamPass generates your personal encryption keys, so that first sign in takes a few seconds longer than later ones. This is normal and happens once per user.

After signing in you land on the administration dashboard, which summarises users, items, folders and system health at a glance. Note Encryption System: Operational, which confirms the per VM saltkey generated on first boot is loaded and the vault is ready.

The TeamPass administration dashboard after signing in, showing active users, total items, total folders and the system health panel with the encryption system operational

Change the administrator password to one of your own once you are in: open the account menu at the top right and choose your profile.

Step 6 - Create your folder tree

Credentials in TeamPass live in folders, and access is granted per folder, so the folder tree is where you plan who gets to see what. Open Folders in the left sidebar and select New to add one, giving it a name and a password complexity requirement.

The TeamPass folder management page listing the Infrastructure, Databases and SaaS Accounts folders with their complexity and access controls

Step 7 - Add your team and grant access

Roles connect people to folders. Create a role under Roles, give it access to the folders it needs, then create your team members under Users and assign them that role. Select New to add a user, and set their login, email and role.

The TeamPass users administration page showing the new, propagate, refresh and inactive users controls above the user list

The admin account is an administration account: it manages settings, folders, roles and users rather than holding credentials itself. Create ordinary user accounts with roles for the people who need to read and store passwords.

Step 8 - No known or default credentials

This image ships with no vault and no secret inside it. There is no database, no settings.php, no saltkey and no administrator account in the image at all, so there is no shared or default credential to discover, and nothing to rotate. On the first boot of your VM, TeamPass is installed onto that VM and three secrets are generated there and only there: the encryption saltkey, the database password and the administrator password.

You can confirm the security properties of your own instance. The administrator password is stored only as a bcrypt hash, TeamPass's temporary install table (which briefly holds the administrator password in clear text during any TeamPass installation) has been dropped, the install wizard is not reachable over the network, and the recorded credential really does authenticate while wrong ones do not:

sudo mysql -uroot -N -e "SELECT CONCAT('admin  pw stored as: ',LEFT(pw,7),'... (bcrypt hash, never plaintext)') FROM teampass.teampass_users WHERE login='admin'"
sudo mysql -uroot -N -e "SELECT COUNT(*) AS plaintext_install_tables FROM information_schema.tables WHERE table_schema='teampass' AND table_name='_install'"
curl -s -o /dev/null -w 'installer on public :80 -> HTTP %{http_code}\n' http://127.0.0.1/install/install.php
sudo bash /usr/local/sbin/teampass-cred-roundtrip.sh

The admin password stored as a bcrypt hash, zero plaintext install tables remaining, the installer returning HTTP 403 on the public listener, and the credential round trip check passing

The round trip check proves, on your own VM, that the password in the credentials file authenticates through TeamPass's own password verification, that a wrong password is refused, that the saltkey is a valid encryption key, and that the installer is not exposed.

Step 9 - Verify the stack and where your data lives

The vault database, the saltkey that decrypts it and every encrypted attachment live on the dedicated data disk mounted at /data, kept separate from the operating system disk so you can snapshot and resize it independently.

sudo grep -E "TP_VERSION'|TP_VERSION_MINOR" /var/www/teampass/app/config/include.php | sed 's/^ *//'
curl -sI http://127.0.0.1/healthz | head -1
findmnt -no SOURCE,TARGET,FSTYPE,SIZE /data; findmnt -no SOURCE,TARGET /var/lib/mysql; findmnt -no SOURCE,TARGET /var/www/teampass/secrets

The installed TeamPass version, the healthz endpoint returning 200, and the ext4 data disk mounted at /data with the database and the secrets directory bind mounted onto it

Layout:

  • /data/mysql bind mounted onto /var/lib/mysql holds the encrypted vault database
  • /data/teampass/secrets bind mounted onto /var/www/teampass/secrets holds the saltkey, readable only by the web server user
  • /data/teampass/storage bind mounted onto /var/www/teampass/storage holds encrypted attachments, uploads and backups
  • /var/www/teampass holds the application code on the OS disk; app/config/settings.php sits outside the web root, so the database credentials are never web reachable

Adding your own domain and TLS

Point a DNS A record at the VM's public IP, then issue a certificate with Certbot. TeamPass renders on whatever hostname you reach it on, so no application change is needed to serve it on a domain.

sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.com --agree-tos -m you@example.com --redirect

Once TLS is in front, sign in and set the instance URL to the https address under Settings then Options, so links TeamPass generates use it. Serving a password manager over plain HTTP is only appropriate while you are setting it up; put TLS in front before storing real credentials.

Scheduled jobs

TeamPass runs background work (notifications, maintenance and cleanup tasks) from a systemd timer rather than a crontab, so you can inspect it with the usual tools:

systemctl is-active teampass-scheduler.timer
systemctl list-timers teampass-scheduler.timer --no-pager --no-legend

Backing up

Two things must be backed up together, and this is the most important thing to understand about running any password manager: the vault cannot be decrypted without its saltkey. The database alone is useless, and the saltkey alone is useless.

  • the vault database, in /data/mysql
  • the saltkey, in /data/teampass/secrets
  • the credentials file /root/teampass-credentials.txt, which records the database password

Because all of the vault data sits on the dedicated /data disk, an Azure managed disk snapshot of that disk captures the database, the saltkey and the attachments together and consistently. Take a logical dump as well if you want a portable copy:

sudo mysqldump --single-transaction teampass > /root/teampass-backup.sql

Store the saltkey somewhere safe and separate. If you lose it, the stored passwords are unrecoverable by design.

Security notes

  • The image contains no vault, no database, no saltkey and no administrator account. Everything secret is generated on the first boot of your own VM.
  • The administrator password is stored only as a bcrypt hash. The database password is encrypted with the per VM saltkey inside settings.php, which lives outside the web root.
  • The credentials file is 0600 root:root. Only root can read it. Change the administrator password to one of your own after your first sign in, and treat the file as a bootstrap record.
  • The install wizard is never served to the network: the public listener refuses /install outright, and TeamPass removes the wizard from the web root once the install completes.
  • MariaDB listens on 127.0.0.1 only. Keep port 3306 closed in your NSG.
  • TeamPass ships internal system accounts (OTV, TP and API) that it uses for one time view links and API access. They hold no usable password and cannot be signed in to.
  • Put TLS in front of the instance before you store real credentials, and restrict 22/tcp to your management network.

Trademark

TeamPass is a trademark of its respective owner. cloudimg is not affiliated with, endorsed by, or sponsored by the TeamPass project. This image packages the official open source TeamPass release, which is distributed under the GNU General Public License v3.0; the licence text ships in the image at /usr/share/doc/teampass/LICENSE.md.

Support

cloudimg provides 24/7 technical support for this image by email (support@cloudimg.co.uk) and live chat, covering deployment, folder and access rights design, LDAP or Active Directory integration, two factor authentication setup, upgrades, backup and restore of the vault and its saltkey, and database administration. Critical issues receive a one hour average response time.