Extra SSH/SFTP/FTPS accounts per client
By default an Octopus instance has one tenant account pair (oN / oN.ftp).
BOA can provision one extra subaccount per Aegir Client — a separate
SSH/SFTP/FTPS account scoped to only that client's sites. The Unix-account side is
driven by manage_ltd_users.sh (its _manage_sec secondary-user pass, iterating
the main tenant's clients/ directories); the Aegir-side request originates from
a Client node's Users assignment.
The granularity is per Client, not per individual developer: each Aegir Client maps to exactly one shell subaccount, shared by everyone assigned to that Client. To give two people independent shell credentials, give each their own Aegir Client (see the accountability discussion below).
The Client + subaccount model
Octopus instance o1
└── main account: o1 + o1.ftp ← operator + primary tenant
│
└── Aegir Client "AcmeCorp"
│ ├── subaccount: o1.acme ← one shell account for this Client
│ └── sites: acme-prod.example.com
│ acme-staging.example.com
│
└── Aegir Client "WidgetCo"
├── subaccount: o1.widget
└── sites: widget.example.com
Each subaccount has its own SSH key and password, its own lshell config, sees only sites belonging to its parent Client, and cannot touch other Clients' sites within the same Octopus.
Provisioning lifecycle
A subaccount is requested by assigning Drupal user(s) to a Client node in the
Aegir UI (Client → Users). On submit, Aegir creates a Task to provision the
account; within a few minutes the cron-driven manage_ltd_users.sh (the */3
root crontab entry) picks up the request and creates the Unix account.
The subaccount username format is <octopus>.<client> — e.g. o1.acme — where
<client> is the Client's directory name reduced to lowercase alphanumerics. It
carries no .ftp suffix (unlike the main oN.ftp tenant) and no
per-developer segment.
What the subaccount can do
Same as the main oN.ftp account (lshell-restricted), but scoped to the sites
of one Client:
cdinto the Drupal codebase directories belonging to that Client's sites.- Run
vdrush/composeragainst those sites only. - SSH key + SFTP file upload for those site directories.
It cannot see other Clients' sites, touch the host system, or bypass lshell.
Per-subaccount SSH keys
The subaccount's ~/.ssh/authorized_keys is at the standard path
(home is /home/<oN>.<client>, mirroring the username):
/home/<oN>.<client>/.ssh/authorized_keys
The owner (or a manager with shell access) populates it via SFTP or by editing directly.
Password rotation
Subaccounts follow the same 90-day rotation policy as the main oN.ftp account.
New passwords are emailed to the Aegir user's email address.
Removal lifecycle
Removing the user from the Client's Users list, or otherwise breaking the
subaccount's state, is what triggers deletion — there is no dedicated removal
Task. manage_ltd_users.sh's _kill_zombies pass (run from the */3 cron)
detects a subaccount whose state has diverged and deletes it. State is considered
diverged when any of these is true: the ~/sites symlink is missing, its target
no longer exists, or the /home/<oN>.ftp/users/<oN>.<client> marker file is gone.
Deletion is immediate on that detection — there is no grace period and
nothing configurable about the timing. The account is removed with deluser --remove-home, and the deleted home is written once as a backup tarball under
/var/backups/zombie/deleted/<timestamp>/. That tarball is an archival copy for
recovery, not a retained or reactivatable home — the live account and its home are
gone at that point. A second sweep catches orphaned home directories with no
matching passwd entry and moves them to the same backup location as
.leftover-<name>.
Why per-Client subaccounts vs. a shared oN.ftp
Sharing the main oN.ftp account across customers carries operational risks that
per-Client subaccounts remove:
- Cross-Client snooping —
oN.ftpcan see every site on the instance, whereas a Client subaccount sees only its own Client's sites. - Blast radius on disable — rotating or disabling
oN.ftpaffects everyone; a Client subaccount can be retired independently.
This is BOA's preferred pattern for the agency model (one Octopus, one Aegir Client per customer, one shell subaccount per Client).
Because the shell account is per Client, not per person, individual-developer
accountability is achieved by mapping one Aegir Client per individual — each
person then gets their own oN.<client> account, key and log identity. Putting
several developers under a single Client gives them a shared subaccount, so the
log shows oN.<client> did X, not which person — the same accountability gap as
sharing oN.ftp, just narrowed to one Client's sites.
Related
- lshell + manage_ltd_users — the lshell layer per account and the orchestrator that creates/removes these subaccounts.
- Security model — the broader multi-tenant model.
- SSH + SFTP hardening — the SSH server config that applies to every subaccount.