diff --git a/Makefile b/Makefile
index ab4d4e72c4987c150b13b6d82ce90c09dd99f3be..41b47141f4d0a23dd20adaf5ca1291163cf8fc3c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 # Makefile to regenerate all the graphviz renderings in
 # the role-specific directories.
 
-DOTS = $(wildcard roles/*/*.dot)
+DOTS = $(wildcard docs/*.dot) $(wildcard roles/*/*.dot)
 SVGS = $(DOTS:%.dot=%.svg)
 PNGS = $(DOTS:%.dot=%.png)
 
diff --git a/docs/authentication.dot b/docs/authentication.dot
new file mode 100644
index 0000000000000000000000000000000000000000..84858cc8390f6dc907aff4cee0d8fd90b8aa4abd
--- /dev/null
+++ b/docs/authentication.dot
@@ -0,0 +1,34 @@
+digraph authentication {
+  {
+    rank=min
+    user [color=gray]
+  }
+
+  {
+    rank=max
+    LDAP [shape=cylinder]
+  }
+
+  "auth-server" -> LDAP
+
+  # Email authentication flows.
+  user -> "postfix-smtp-auth" [label="SMTP"]
+  "postfix-smtp-auth" -> "auth-server-sasl\n@smtp-auth"
+  "auth-server-sasl\n@smtp-auth" -> "auth-server" [label="pam_auth_client"]
+
+  user -> SSO [label="HTTP"]
+  SSO -> roundcube
+  SSO -> "auth-server"
+  roundcube -> "postfix-webmail"
+  "postfix-webmail" -> "auth-server-sasl\n@webmail"
+  "auth-server-sasl\n@webmail" -> "auth-server" [label="pam_sso"]
+  roundcube -> "dovecot\n(backend)"
+  "dovecot\n(backend)" -> "auth-server" [label="pam_sso"]
+
+  user -> "dovecot\n(frontend)" [label="IMAP"]
+  "dovecot\n(frontend)" -> "auth-server" [label="pam_auth_client"]
+
+  # XMPP
+  user -> ejabberd [label="XMPP"]
+  ejabberd -> "auth-server" [label="pam_auth_client"]
+}
diff --git a/docs/authentication.png b/docs/authentication.png
new file mode 100644
index 0000000000000000000000000000000000000000..90271a6ce87322c5935cad932dfc5a5533b7b70e
Binary files /dev/null and b/docs/authentication.png differ
diff --git a/docs/authentication.svg b/docs/authentication.svg
new file mode 100644
index 0000000000000000000000000000000000000000..e03629820021d9f31d363abc995ce9bf05a1f280
--- /dev/null
+++ b/docs/authentication.svg
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by graphviz version 2.40.1 (20161225.0304)
+ -->
+<!-- Title: authentication Pages: 1 -->
+<svg width="680pt" height="686pt"
+ viewBox="0.00 0.00 680.12 685.96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 681.9605)">
+<title>authentication</title>
+<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-681.9605 676.1249,-681.9605 676.1249,4 -4,4"/>
+<!-- user -->
+<g id="node1" class="node">
+<title>user</title>
+<ellipse fill="none" stroke="#c0c0c0" cx="365.1249" cy="-659.9605" rx="27" ry="18"/>
+<text text-anchor="middle" x="365.1249" y="-656.2605" font-family="Times,serif" font-size="14.00" fill="#000000">user</text>
+</g>
+<!-- postfix&#45;smtp&#45;auth -->
+<g id="node4" class="node">
+<title>postfix&#45;smtp&#45;auth</title>
+<ellipse fill="none" stroke="#000000" cx="177.1249" cy="-572.9605" rx="73.387" ry="18"/>
+<text text-anchor="middle" x="177.1249" y="-569.2605" font-family="Times,serif" font-size="14.00" fill="#000000">postfix&#45;smtp&#45;auth</text>
+</g>
+<!-- user&#45;&gt;postfix&#45;smtp&#45;auth -->
+<g id="edge2" class="edge">
+<title>user&#45;&gt;postfix&#45;smtp&#45;auth</title>
+<path fill="none" stroke="#000000" d="M342.8206,-649.6388C312.8723,-635.7798 259.0196,-610.8585 220.8446,-593.1925"/>
+<polygon fill="#000000" stroke="#000000" points="222.0463,-589.892 211.501,-588.8686 219.1065,-596.2448 222.0463,-589.892"/>
+<text text-anchor="middle" x="301.6249" y="-612.7605" font-family="Times,serif" font-size="14.00" fill="#000000">SMTP</text>
+</g>
+<!-- SSO -->
+<g id="node6" class="node">
+<title>SSO</title>
+<ellipse fill="none" stroke="#000000" cx="305.1249" cy="-572.9605" rx="27" ry="18"/>
+<text text-anchor="middle" x="305.1249" y="-569.2605" font-family="Times,serif" font-size="14.00" fill="#000000">SSO</text>
+</g>
+<!-- user&#45;&gt;SSO -->
+<g id="edge5" class="edge">
+<title>user&#45;&gt;SSO</title>
+<path fill="none" stroke="#000000" d="M353.8394,-643.5964C345.0122,-630.7971 332.586,-612.7791 322.4934,-598.1447"/>
+<polygon fill="#000000" stroke="#000000" points="325.1224,-595.792 316.5638,-589.5469 319.3599,-599.7661 325.1224,-595.792"/>
+<text text-anchor="middle" x="356.1249" y="-612.7605" font-family="Times,serif" font-size="14.00" fill="#000000">HTTP</text>
+</g>
+<!-- dovecot\n(frontend) -->
+<g id="node11" class="node">
+<title>dovecot\n(frontend)</title>
+<ellipse fill="none" stroke="#000000" cx="430.1249" cy="-510.0904" rx="50.41" ry="26.7407"/>
+<text text-anchor="middle" x="430.1249" y="-513.8904" font-family="Times,serif" font-size="14.00" fill="#000000">dovecot</text>
+<text text-anchor="middle" x="430.1249" y="-498.8904" font-family="Times,serif" font-size="14.00" fill="#000000">(frontend)</text>
+</g>
+<!-- user&#45;&gt;dovecot\n(frontend) -->
+<g id="edge13" class="edge">
+<title>user&#45;&gt;dovecot\n(frontend)</title>
+<path fill="none" stroke="#000000" d="M372.7084,-642.4751C382.9223,-618.9252 401.3415,-576.4561 414.5661,-545.9643"/>
+<polygon fill="#000000" stroke="#000000" points="417.8922,-547.0914 418.6602,-536.5244 411.4702,-544.306 417.8922,-547.0914"/>
+<text text-anchor="middle" x="404.6249" y="-612.7605" font-family="Times,serif" font-size="14.00" fill="#000000">IMAP</text>
+</g>
+<!-- ejabberd -->
+<g id="node12" class="node">
+<title>ejabberd</title>
+<ellipse fill="none" stroke="#000000" cx="571.1249" cy="-510.0904" rx="40.8928" ry="18"/>
+<text text-anchor="middle" x="571.1249" y="-506.3904" font-family="Times,serif" font-size="14.00" fill="#000000">ejabberd</text>
+</g>
+<!-- user&#45;&gt;ejabberd -->
+<g id="edge15" class="edge">
+<title>user&#45;&gt;ejabberd</title>
+<path fill="none" stroke="#000000" d="M386.1598,-648.4613C398.1171,-641.7001 413.2305,-632.7713 426.1249,-623.9605 468.9398,-594.7045 515.6356,-556.8736 544.1533,-533.0376"/>
+<polygon fill="#000000" stroke="#000000" points="546.6387,-535.5209 552.0459,-526.4097 542.1371,-530.1603 546.6387,-535.5209"/>
+<text text-anchor="middle" x="466.1249" y="-612.7605" font-family="Times,serif" font-size="14.00" fill="#000000">XMPP</text>
+</g>
+<!-- LDAP -->
+<g id="node2" class="node">
+<title>LDAP</title>
+<path fill="none" stroke="#000000" d="M372.1249,-32.7273C372.1249,-34.5331 360.0231,-36 345.1249,-36 330.2267,-36 318.1249,-34.5331 318.1249,-32.7273 318.1249,-32.7273 318.1249,-3.2727 318.1249,-3.2727 318.1249,-1.4669 330.2267,0 345.1249,0 360.0231,0 372.1249,-1.4669 372.1249,-3.2727 372.1249,-3.2727 372.1249,-32.7273 372.1249,-32.7273"/>
+<path fill="none" stroke="#000000" d="M372.1249,-32.7273C372.1249,-30.9214 360.0231,-29.4545 345.1249,-29.4545 330.2267,-29.4545 318.1249,-30.9214 318.1249,-32.7273"/>
+<text text-anchor="middle" x="345.1249" y="-14.3" font-family="Times,serif" font-size="14.00" fill="#000000">LDAP</text>
+</g>
+<!-- auth&#45;server -->
+<g id="node3" class="node">
+<title>auth&#45;server</title>
+<ellipse fill="none" stroke="#000000" cx="345.1249" cy="-91" rx="50.0912" ry="18"/>
+<text text-anchor="middle" x="345.1249" y="-87.3" font-family="Times,serif" font-size="14.00" fill="#000000">auth&#45;server</text>
+</g>
+<!-- auth&#45;server&#45;&gt;LDAP -->
+<g id="edge1" class="edge">
+<title>auth&#45;server&#45;&gt;LDAP</title>
+<path fill="none" stroke="#000000" d="M345.1249,-72.9551C345.1249,-64.8828 345.1249,-55.1764 345.1249,-46.1817"/>
+<polygon fill="#000000" stroke="#000000" points="348.625,-46.0903 345.1249,-36.0904 341.625,-46.0904 348.625,-46.0903"/>
+</g>
+<!-- auth&#45;server&#45;sasl\n@smtp&#45;auth -->
+<g id="node5" class="node">
+<title>auth&#45;server&#45;sasl\n@smtp&#45;auth</title>
+<ellipse fill="none" stroke="#000000" cx="72.1249" cy="-384.3503" rx="72.25" ry="26.7407"/>
+<text text-anchor="middle" x="72.1249" y="-388.1503" font-family="Times,serif" font-size="14.00" fill="#000000">auth&#45;server&#45;sasl</text>
+<text text-anchor="middle" x="72.1249" y="-373.1503" font-family="Times,serif" font-size="14.00" fill="#000000">@smtp&#45;auth</text>
+</g>
+<!-- postfix&#45;smtp&#45;auth&#45;&gt;auth&#45;server&#45;sasl\n@smtp&#45;auth -->
+<g id="edge3" class="edge">
+<title>postfix&#45;smtp&#45;auth&#45;&gt;auth&#45;server&#45;sasl\n@smtp&#45;auth</title>
+<path fill="none" stroke="#000000" d="M165.9791,-555.1217C162.4461,-549.362 158.5659,-542.9241 155.1249,-536.9605 132.2444,-497.3064 107.3156,-451.0212 90.8123,-419.9112"/>
+<polygon fill="#000000" stroke="#000000" points="93.7443,-417.9686 85.9727,-410.7677 87.5574,-421.2433 93.7443,-417.9686"/>
+</g>
+<!-- auth&#45;server&#45;sasl\n@smtp&#45;auth&#45;&gt;auth&#45;server -->
+<g id="edge4" class="edge">
+<title>auth&#45;server&#45;sasl\n@smtp&#45;auth&#45;&gt;auth&#45;server</title>
+<path fill="none" stroke="#000000" d="M64.4074,-357.4496C56.8425,-326.1682 48.5209,-273.4919 64.1249,-231.7401 85.7132,-173.9759 101.6514,-157.714 155.1249,-127 177.1618,-114.3425 239.5819,-104.0656 286.9153,-97.7803"/>
+<polygon fill="#000000" stroke="#000000" points="287.603,-101.2205 297.069,-96.4618 286.7016,-94.2787 287.603,-101.2205"/>
+<text text-anchor="middle" x="109.6249" y="-254.9102" font-family="Times,serif" font-size="14.00" fill="#000000">pam_auth_client</text>
+</g>
+<!-- SSO&#45;&gt;auth&#45;server -->
+<g id="edge7" class="edge">
+<title>SSO&#45;&gt;auth&#45;server</title>
+<path fill="none" stroke="#000000" d="M281.4355,-563.8545C242.4706,-547.1489 169.1249,-507.6742 169.1249,-447.2203 169.1249,-447.2203 169.1249,-447.2203 169.1249,-186.8701 169.1249,-132.0685 235.7432,-108.4104 287.0081,-98.3179"/>
+<polygon fill="#000000" stroke="#000000" points="287.8298,-101.7256 297.0321,-96.4751 286.5641,-94.841 287.8298,-101.7256"/>
+</g>
+<!-- roundcube -->
+<g id="node7" class="node">
+<title>roundcube</title>
+<ellipse fill="none" stroke="#000000" cx="305.1249" cy="-447.2203" rx="48.1917" ry="18"/>
+<text text-anchor="middle" x="305.1249" y="-443.5203" font-family="Times,serif" font-size="14.00" fill="#000000">roundcube</text>
+</g>
+<!-- SSO&#45;&gt;roundcube -->
+<g id="edge6" class="edge">
+<title>SSO&#45;&gt;roundcube</title>
+<path fill="none" stroke="#000000" d="M305.1249,-554.945C305.1249,-534.2414 305.1249,-499.9967 305.1249,-475.6789"/>
+<polygon fill="#000000" stroke="#000000" points="308.625,-475.6113 305.1249,-465.6113 301.625,-475.6114 308.625,-475.6113"/>
+</g>
+<!-- postfix&#45;webmail -->
+<g id="node8" class="node">
+<title>postfix&#45;webmail</title>
+<ellipse fill="none" stroke="#000000" cx="273.1249" cy="-321.4802" rx="68.7879" ry="18"/>
+<text text-anchor="middle" x="273.1249" y="-317.7802" font-family="Times,serif" font-size="14.00" fill="#000000">postfix&#45;webmail</text>
+</g>
+<!-- roundcube&#45;&gt;postfix&#45;webmail -->
+<g id="edge8" class="edge">
+<title>roundcube&#45;&gt;postfix&#45;webmail</title>
+<path fill="none" stroke="#000000" d="M300.5401,-429.2049C295.2173,-408.2896 286.3775,-373.5549 280.1784,-349.196"/>
+<polygon fill="#000000" stroke="#000000" points="283.5595,-348.2902 277.7012,-339.4623 276.7757,-350.0166 283.5595,-348.2902"/>
+</g>
+<!-- dovecot\n(backend) -->
+<g id="node10" class="node">
+<title>dovecot\n(backend)</title>
+<ellipse fill="none" stroke="#000000" cx="372.1249" cy="-258.6102" rx="50.41" ry="26.7407"/>
+<text text-anchor="middle" x="372.1249" y="-262.4102" font-family="Times,serif" font-size="14.00" fill="#000000">dovecot</text>
+<text text-anchor="middle" x="372.1249" y="-247.4102" font-family="Times,serif" font-size="14.00" fill="#000000">(backend)</text>
+</g>
+<!-- roundcube&#45;&gt;dovecot\n(backend) -->
+<g id="edge11" class="edge">
+<title>roundcube&#45;&gt;dovecot\n(backend)</title>
+<path fill="none" stroke="#000000" d="M313.7835,-429.2435C323.7291,-408.1125 340.0918,-371.8184 351.1249,-339.4802 355.987,-325.2293 360.3589,-309.2389 363.8386,-295.2628"/>
+<polygon fill="#000000" stroke="#000000" points="367.2518,-296.0391 366.2091,-285.4957 360.4492,-294.3881 367.2518,-296.0391"/>
+</g>
+<!-- auth&#45;server&#45;sasl\n@webmail -->
+<g id="node9" class="node">
+<title>auth&#45;server&#45;sasl\n@webmail</title>
+<ellipse fill="none" stroke="#000000" cx="269.1249" cy="-186.8701" rx="72.25" ry="26.7407"/>
+<text text-anchor="middle" x="269.1249" y="-190.6701" font-family="Times,serif" font-size="14.00" fill="#000000">auth&#45;server&#45;sasl</text>
+<text text-anchor="middle" x="269.1249" y="-175.6701" font-family="Times,serif" font-size="14.00" fill="#000000">@webmail</text>
+</g>
+<!-- postfix&#45;webmail&#45;&gt;auth&#45;server&#45;sasl\n@webmail -->
+<g id="edge9" class="edge">
+<title>postfix&#45;webmail&#45;&gt;auth&#45;server&#45;sasl\n@webmail</title>
+<path fill="none" stroke="#000000" d="M272.5854,-303.3261C271.9857,-283.1427 271.0006,-249.993 270.2345,-224.2125"/>
+<polygon fill="#000000" stroke="#000000" points="273.7275,-223.921 269.9319,-214.0294 266.7306,-224.129 273.7275,-223.921"/>
+</g>
+<!-- auth&#45;server&#45;sasl\n@webmail&#45;&gt;auth&#45;server -->
+<g id="edge10" class="edge">
+<title>auth&#45;server&#45;sasl\n@webmail&#45;&gt;auth&#45;server</title>
+<path fill="none" stroke="#000000" d="M288.2465,-160.649C296.1085,-150.0755 305.4011,-137.8382 314.1249,-127 316.9951,-123.4341 320.0779,-119.7223 323.1461,-116.0954"/>
+<polygon fill="#000000" stroke="#000000" points="325.9061,-118.2535 329.7516,-108.3811 320.5889,-113.7006 325.9061,-118.2535"/>
+<text text-anchor="middle" x="338.6249" y="-130.8" font-family="Times,serif" font-size="14.00" fill="#000000">pam_sso</text>
+</g>
+<!-- dovecot\n(backend)&#45;&gt;auth&#45;server -->
+<g id="edge12" class="edge">
+<title>dovecot\n(backend)&#45;&gt;auth&#45;server</title>
+<path fill="none" stroke="#000000" d="M373.3453,-231.6303C373.857,-204.6607 372.7262,-162.2449 363.1249,-127 362.3064,-123.9956 361.2275,-120.9463 360.0036,-117.9588"/>
+<polygon fill="#000000" stroke="#000000" points="363.1201,-116.3596 355.7413,-108.7568 356.7684,-119.3017 363.1201,-116.3596"/>
+<text text-anchor="middle" x="398.6249" y="-183.1701" font-family="Times,serif" font-size="14.00" fill="#000000">pam_sso</text>
+</g>
+<!-- dovecot\n(frontend)&#45;&gt;auth&#45;server -->
+<g id="edge14" class="edge">
+<title>dovecot\n(frontend)&#45;&gt;auth&#45;server</title>
+<path fill="none" stroke="#000000" d="M438.2502,-483.3909C445.2128,-458.1278 454.1249,-419.0197 454.1249,-384.3503 454.1249,-384.3503 454.1249,-384.3503 454.1249,-186.8701 454.1249,-150.2133 418.937,-124.2624 388.5472,-108.6853"/>
+<polygon fill="#000000" stroke="#000000" points="389.8366,-105.4202 379.3141,-104.1838 386.7689,-111.7122 389.8366,-105.4202"/>
+<text text-anchor="middle" x="499.6249" y="-317.7802" font-family="Times,serif" font-size="14.00" fill="#000000">pam_auth_client</text>
+</g>
+<!-- ejabberd&#45;&gt;auth&#45;server -->
+<g id="edge16" class="edge">
+<title>ejabberd&#45;&gt;auth&#45;server</title>
+<path fill="none" stroke="#000000" d="M573.4948,-491.8016C576.4519,-467.3599 581.1249,-422.6732 581.1249,-384.3503 581.1249,-384.3503 581.1249,-384.3503 581.1249,-186.8701 581.1249,-147.8278 468.8589,-117.0357 399.1894,-101.6858"/>
+<polygon fill="#000000" stroke="#000000" points="399.7517,-98.2266 389.2378,-99.534 398.2722,-105.0685 399.7517,-98.2266"/>
+<text text-anchor="middle" x="626.6249" y="-317.7802" font-family="Times,serif" font-size="14.00" fill="#000000">pam_auth_client</text>
+</g>
+</g>
+</svg>
diff --git a/roles/auth-server-ldap/README.md b/roles/auth-server-ldap/README.md
index 4983033c869392338479f95664c6cff9029fbcd5..62e75e88236ba117803f581bc5841e44d1b762d2 100644
--- a/roles/auth-server-ldap/README.md
+++ b/roles/auth-server-ldap/README.md
@@ -1 +1,2 @@
-Questo ruolo connette auth-server al database LDAP.
+This role configures the LDAP backend for the
+[auth-server](https://git.autistici.org/id/auth).