diff --git a/trurt/account/forms.py b/trurt/account/forms.py
index b3b1c82c53f79c5e0d285b428cf0444a670df4ab..f5a9f29902aefe5ce7f24a2f2c4a477279acd2c8 100644
--- a/trurt/account/forms.py
+++ b/trurt/account/forms.py
@@ -8,3 +8,11 @@ class LoginForm(flask_wtf.FlaskForm):
     username = fields.StringField(_('Username'), [validators.DataRequired()])
     password = fields.PasswordField(_('Password'), [validators.DataRequired()])
     submit = fields.SubmitField(_('Sign in'))
+
+
+class SignupForm(flask_wtf.FlaskForm):
+    username = fields.StringField(_('Username'), [validators.DataRequired()])
+    password = fields.PasswordField(_('Password'), [validators.DataRequired()])
+    password2 = fields.PasswordField(_('Confirm password'),
+        [validators.DataRequired(validators.EqualTo('password'))])
+    submit = fields.SubmitField(_('Sign in'))
diff --git a/trurt/account/login.py b/trurt/account/login.py
index 3f5cbfe4453210a08b6af0c00767e573343e8326..4a631f4508392598c771b402d9b668f28c510de9 100644
--- a/trurt/account/login.py
+++ b/trurt/account/login.py
@@ -5,8 +5,8 @@ import flask_login
 import flask
 
 
-@blueprint.route("/login", methods=["GET", "POST"])
-def login():
+@blueprint.route("/signin", methods=["GET", "POST"])
+def signin():
     form = forms.LoginForm()
     if form.validate_on_submit():
         user = models.User.login(form.username.data, form.password.data)
@@ -14,17 +14,35 @@ def login():
             flask_login.login_user(user)
             return flask.redirect(utils.url_or_intent(".home"))
         else:
-            flask.flash("Wrong credentials")
-    return flask.render_template("account_login.html",
-        action=utils.url_for(".login"), form=form)
+            flask.flash("Wrong credentials", "danger")
+    return flask.render_template("account_signin.html",
+        action=utils.url_for(".signin"), form=form)
 
 
-@blueprint.route("/logout")
-def logout():
+@blueprint.route("/signout")
+def signout():
     flask_login.logout_user()
-    return flask.redirect("/")
+    return flask.redirect(flask.url_for(".signin"))
 
 
-@blueprint.route("/register")
-def register():
-    return flask.redirect("/")
+@blueprint.route("/signup", methods=["GET", "POST"])
+def signup():
+    form = forms.SignupForm()
+    if form.validate_on_submit():
+        conflict = models.User.query.filter_by(username=form.username.data).first()
+        if conflict:
+            flask.flash("A user with the same username exists already", "danger")
+        else:
+            user = models.User()
+            user.username = form.username.data
+            auth = models.Auth()
+            auth.set_password(form.password.data)
+            user.auths.append(auth)
+            models.db.session.add(user)
+            models.db.session.add(auth)
+            models.log(models.History.SIGNUP,
+                comment="Signed up using the Web form", user=user)
+            models.db.session.commit()
+            flask.flash("User created successfully", "success")
+            return flask.redirect(utils.url_or_intent("account.home"))
+    return flask.render_template("account_signup.html", form=form)
diff --git a/trurt/account/templates/account_home.html b/trurt/account/templates/account_home.html
index e1a375d0c9fa334f52bd9734061ba096513481e6..02dbb6e282710f54a608cbd48930277e698481bf 100644
--- a/trurt/account/templates/account_home.html
+++ b/trurt/account/templates/account_home.html
@@ -1,7 +1,7 @@
 {% extends "base.html" %}
 
 {% block title %}My account{% endblock %}
-{% block subtitle %}overview of {{ current_user.username }}{% endblock %}
+{% block subtitle %}status and history{% endblock %}
 
 {% block content %}
 <div class="row">
diff --git a/trurt/account/templates/account_register.html b/trurt/account/templates/account_register.html
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/trurt/account/templates/account_login.html b/trurt/account/templates/account_signin.html
similarity index 100%
rename from trurt/account/templates/account_login.html
rename to trurt/account/templates/account_signin.html
diff --git a/trurt/account/templates/account_signup.html b/trurt/account/templates/account_signup.html
new file mode 100644
index 0000000000000000000000000000000000000000..2568487461eaf024f5ef2f55b6eef6e180f5334f
--- /dev/null
+++ b/trurt/account/templates/account_signup.html
@@ -0,0 +1,8 @@
+{% extends "base.html" %}
+
+{% block title %}Sign up{% endblock %}
+{% block subtitle %}create a new account{% endblock %}
+
+{% block content %}
+{{ macros.form(form) }}
+{% endblock %}
diff --git a/trurt/manage.py b/trurt/manage.py
index f88e06c616647add442bee53c5f421c4f5cef29f..64f0fba66993937577a0bddb90e25af56e577c58 100644
--- a/trurt/manage.py
+++ b/trurt/manage.py
@@ -23,10 +23,8 @@ def create_user(username, password):
     auth = models.Auth()
     auth.set_password(password)
     user.auths.append(auth)
-    event = models.History()
-    event.user = user
-    event.category = models.History.REGISTER
-    event.comment = "Created from the command line"
+    models.log(models.History.SIGNUP,
+        comment="Created from the command line", user=user)
     models.db.session.add(event)
     models.db.session.add(user)
     models.db.session.add(auth)
@@ -45,13 +43,9 @@ def create_profile(username, service_uuid, profile_username):
     profile.user = user
     profile.service = service
     profile.username = profile_username
-    event = models.History()
-    event.user = user
-    event.service = service
-    event.profile = profile
-    event.category = models.History.CREATE
-    event.value = profile.username
-    event.comment = "Created from the command line"
+    models.log(models.History.CREATE,
+        comment="Create from the command line", user=user,
+        service=service, profile=profile)
     models.db.session.add(event)
     models.db.session.add(profile)
     models.db.session.commit()
diff --git a/trurt/models.py b/trurt/models.py
index 4dc8553f72d3959c500ddda9c5eaae7aac819d79..3fafe9f0e4081dfa57e39d9dcf381e888da607a0 100644
--- a/trurt/models.py
+++ b/trurt/models.py
@@ -9,6 +9,20 @@ import json
 import uuid
 
 
+def log(category, value=None, comment=None, user=None, profile=None, service=None, actor=None):
+    """ Log a history event
+    """
+    event = History()
+    event.category = category
+    event.value = value
+    event.comment = comment
+    event.user = user
+    event.profile = profile
+    event.service = service
+    event.actor = actor
+    db.session.add(event)
+
+
 class Base(flask_sqlalchemy.Model):
     """ Base class for all models
     """
@@ -154,14 +168,14 @@ class History(db.Model):
     """
     __tablename__ = "history"
 
-    REGISTER = "register"
+    SIGNUP = "signup"
     CREATE = "create"
     DELETE = "delete"
     NOTE = "note"
     STATUS = "status"
 
     DESCRIPTION = {
-        REGISTER: "registered this account",
+        SIGNUP: "signed up for this account",
         CREATE: "created the profile {this.profile.username} on {this.service.name}",
     }
 
diff --git a/trurt/templates/base.html b/trurt/templates/base.html
index 3b7b8f304d880d0a95993bb283acbd0ac875a896..a5718e38898c2b117e6fa9e467a17eefb1585c74 100644
--- a/trurt/templates/base.html
+++ b/trurt/templates/base.html
@@ -16,33 +16,34 @@
         </a>
 
         <nav class="navbar navbar-static-top">
-        <a href="#" class="sidebar-toggle" data-toggle="push-menu" role="button">
-          <span class="sr-only">Toggle navigation</span>
-        </a>
-        <div class="navbar-custom-menu">
-          <ul class="nav navbar-nav">
-            {% if current_user.is_authenticated %}
-            <li class="dropdown user">
-              <a class="dropdown-toggle">
-                Logged in as <strong>{{ current_user.username }}</strong>
-              </a>
-            </li>
-            <li class="dropdown user">
-              <a href="{{ url_for("account.logout") }}" class="dropdown-toggle">
-                <i class="fa fa-sign-out"></i>
-                Log out
-              </a>
-            </li>
-            {% else %}
-            <li class="dropdown user">
-              <a href="{{ url_for("account.login") }}" class="dropdown-toggle">
-                <i class="fa fa-sign-in"></i>
-                Log in
-              </a>
-            </li>
-            {% endif %}
-          </ul>
-        </div>
+          <a href="#" class="sidebar-toggle" data-toggle="push-menu" role="button">
+            <span class="sr-only">Toggle navigation</span>
+          </a>
+          <div class="navbar-custom-menu">
+            <ul class="nav navbar-nav">
+              {% if current_user.is_authenticated %}
+              <li class="dropdown user">
+                <a class="dropdown-toggle">
+                  Logged in as <strong>{{ current_user.username }}</strong>
+                </a>
+              </li>
+              <li class="dropdown user">
+                <a href="{{ url_for("account.signout") }}" class="dropdown-toggle">
+                  <i class="fa fa-sign-out"></i>
+                  Sign out
+                </a>
+              </li>
+              {% else %}
+              <li class="dropdown user">
+                <a href="{{ url_for("account.signin") }}" class="dropdown-toggle">
+                  <i class="fa fa-sign-in"></i>
+                  Sign in
+                </a>
+              </li>
+              {% endif %}
+            </ul>
+          </div>
+        </nav>
 
       </header>
 
@@ -62,6 +63,9 @@
           </h1>
         </section>
         <section class="content container-fluid">
+          {% for category, message in get_flashed_messages(with_categories=True) or [] %}
+          <div class="alert alert-{{ category or "info" }}">{{ message }}</div>
+          {% endfor %}
           {% block content %}{% endblock %}
         </section>
       </div>
diff --git a/trurt/templates/sidebar.html b/trurt/templates/sidebar.html
index 3dc17b70435a6deba7504c5bac1e49d6f427e490..878856350420e82ef16b485c1b5d206f5fc48612 100644
--- a/trurt/templates/sidebar.html
+++ b/trurt/templates/sidebar.html
@@ -11,19 +11,19 @@
   </a>
 </li>
 <li>
-  <a href="{{ url_for("account.logout") }}">
-    <i class="fa fa-sign-out"></i> <span>Log out</span>
+  <a href="{{ url_for("account.signout") }}">
+    <i class="fa fa-sign-out"></i> <span>Sign out</span>
   </a>
 </li>
 {% else %}
 <li>
-  <a href="{{ url_for("account.register") }}">
-    <i class="fa fa-user-plus"></i> <span>Register</span>
+  <a href="{{ url_for("account.signup") }}">
+    <i class="fa fa-user-plus"></i> <span>Sign up</span>
   </a>
 </li>
 <li>
-  <a href="{{ url_for("account.login") }}">
-    <i class="fa fa-sign-in"></i> <span>Log in</span>
+  <a href="{{ url_for("account.signin") }}">
+    <i class="fa fa-sign-in"></i> <span>Sign in</span>
   </a>
 </li>
 {% endif %}
diff --git a/trurt/utils.py b/trurt/utils.py
index bc53f4a130cfd8154b27125973275fdc0cbbf62c..53a05a5fbab8b2beb000b197440a65ff1a0f330f 100644
--- a/trurt/utils.py
+++ b/trurt/utils.py
@@ -15,7 +15,7 @@ INTENTS = "intents"
 @login.unauthorized_handler
 def handle_needs_login():
     return flask.redirect(
-        url_for('account.login', intent=flask.request.endpoint)
+        url_for('account.signin', intent=flask.request.endpoint)
     )