docker-mailserver / docker-mailserver/docker-mailserver

[FR] Application-Specific Passwords (with Working Approach)

Open
#3,198 5 comments 2 reactions 1 assignee View on GitHub

@so-rose is already working on this.

Since Apr 14, 2023.

area/configuration (file) area/documentation area/features area/tests kind/new feature priority/low service/dovecot stale-bot/ignore
Dominant language
Shell
Stars
18.9k
Forks
2k
Avg merge
5h 15m
Merged PRs (30d)
28

Description

Feature Request

Tl;dr: Extra, revocable passwords for users using non-SSO email clients in tandem with SSO approaches.

In my organization, I'd like to keep each user's "real" password (I call this the "master key", not to be confused with dovecot master accounts) far away from them.

I would therefore like to make it easier to create revocable, "application-specific passwords" separate from the "master key" using an opt-in environment variable and setup.

Context

Even once #2713 is implemented, not all email clients can do OAuth. Notable examples include K9 for Android.

By making it easier (it is totally possible, right now, just not obvious) to create and revoke "application-specific passwords" using setup, server-side OAuth adoption will be much easier to encourage.

Is your Feature Request related to a Problem?

When the user accesses their webmail via our SSO, our backend uses the master key to create a one-time URL that logs the user into Roundcube, without them needing to know the password. When they want to use a traditional email client, however, they currently need this master key, which is problematic (users tend to be terrible at password management).

We are working on implementing the Manual Procedure (described below).

Describe the Solution you'd like

It's very simple, and is a very slightly modified version of this: https://www.happyassassin.net/posts/2014/08/26/adding-application-specific-passwords-to-dovecot-when-using-system-user-accounts/

Manual (Current) Procedure

  1. Add the following passdb entry before the existing one, in /etc/dovecot/conf.d/auth-passwdfile.inc:
passdb {
  driver = passwd-file
  args = /etc/dovecot/app_specific_passwd
}
  1. Bind a file /etc/dovecot/conf.d/app_specific_passwd:
mobile-email@example.com:{SHA512-CRYPT}123456789...::::::user=email@example.com
thunderbird-email@example.com:{SHA512-CRYPT}0123abcd...::::::user=email@example.com
outlook-email@example.com:{SHA512-CRYPT}987654321...::::::user=email@example.com

You'll notice that there's also a device-specific username associated with each password, making it easy to identify the behavior of users that are making use of this feature.

  1. Implement external logic and/or alerts (ex. cronjob that deletes new entries after a year, anomaly detection on login metrics to alert the admin to misuse) to decide when to make revocations and/or automated expiration.

Ideal Procedure
Ideally, managing app_specific_passwd would be done through setup:

  1. Set an environment variable, ex. DOVECOT_USE_APP_PASS=1, to enable the extra passdb in auth-passwdfile.inc .
  2. In the container, run setup add app-pass <DEVICE_NAME> <EMAIL>
  3. For revocation, run setup revoke app-pass <DEVICE_NAME> <EMAIL>

Notes on the setup implementation I have in mind:

  • It should print a 48-bit base64-encoded password sourced from /dev/urandom.
  • After generation, it should not be retrievable again.
  • DEVICE_NAME should pass the regex ^[a-z\-]$
  • If DOVECOT_USE_APP_PASS is not set, this setup command should fail.

Bonus: External Logic
This essentially adds a few security features without making use of them. docker-mailserver could implement the most important ones out of the box:

  • Expiration: I would love to see this setup script automatically setup app password expiration in cron, which allows the mail server admin to force the user to rotate their keys once in awhile (ex. default it to one year).
  • fail2ban Revocation: Misuse (as defined by fail2ban) of a device-specific password could lead to an automatic revocation of the application-specific password.
Are you going to implement it?

Yes, because I know the probability of someone else doing it is low and I can learn from it.

I have hacked my way around this; however, I would like to hear whether this is something others might be interested in, especially considering interest in #2713 and the inability of clients like K9 to use its result.

What are you going to contribute??

I would suggest a multi-step process:

  1. Documentation: Documenting the above approach for now.
  2. setup Implementation: Making the documented approach easy with setup.
  3. Bonuses: Making use of the security gains from this approach by default.

Additional context

Alternatives you've considered

Waiting for OAuth
OAuth doesn't quite solve the problem of clients that don't support server-side OAuth.

Moreover, some non-human clients (ex. self-hosted software that sends email, or quick sender scripts) will simply never support OAuth. I'd like to enable OAuth for 95% of cases, and have the backup plan be better than just giving out the one password.

Giving out the Master Key
There are several problems with having one shared password across all devices. It's difficult to revoke access for the client that leaked the key. Revoking one leaked key completely disables all devices. Statistical anomaly detection of login patterns is less effective. And so on.

Who will that Feature be useful to?

See Context.

What have you done already?

See Manual (Current) Procedure.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.