diff --git a/trurt/account/forms.py b/trurt/account/forms.py
index c6a3d729feeda6193c97a16153ce00d26d41893a..26598641c924b510ef18bc68185d616e1f46a20b 100644
--- a/trurt/account/forms.py
+++ b/trurt/account/forms.py
@@ -38,3 +38,7 @@ class ProfileForm(flask_wtf.FlaskForm):
 
 class ProfilePickForm(flask_wtf.FlaskForm):
     profile_uuid = fields.TextField('profile', [])
+
+
+class AvatarForm(flask_wtf.FlaskForm):
+    submit = fields.SubmitField(_('Sign up'), [])
diff --git a/trurt/account/profiles.py b/trurt/account/profiles.py
index b65c390ab717997425266432ab3826e47300ca1b..f23a7539341050d6ade16b17162cae96a28bbb13 100644
--- a/trurt/account/profiles.py
+++ b/trurt/account/profiles.py
@@ -3,54 +3,61 @@ from trurt.sso import forms as sso_forms
 from trurt import models, utils, security
 
 import flask
+import flask_login
 
 
-def pick_profile(service, **redirect_args):
+def get_profile(service, **redirect_args):
     form = forms.ProfilePickForm()
     if form.validate_on_submit():
         profile = models.Profile.query.get(form.profile_uuid.data)
         if not (profile.user == flask_login.current_user and
-                profile.service == service):
+                profile.service == service and
+                profile.status == models.Profile.ACTIVE):
             return None
         return profile
-    utils.force_redirect(utils.url_for("account.pick", **redirect_args))
+    next = ("account.pick_avatar" if service.max_profiles == 0
+            else "account.pick_profile")
+    utils.force_redirect(utils.url_for(next, **redirect_args))
 
 
-@blueprint.route("/pick")
+@blueprint.route("/profile/pick")
 @security.authentication_required()
-def pick():
+def pick_profile():
     service_uuid = flask.request.args.get("service_uuid") or flask.abort(404)
     service = models.Service.query.get(service_uuid) or flask.abort(404)
-    profiles = models.Profile.query.filter_by(
-        service_uuid=service.uuid,
-        user_uuid=flask_login.current_user.uuid
-    ).all()
+    profiles = models.Profile.filter(service, flask_login.current_user).all()
     form = forms.ProfilePickForm()
-    return flask.render_template("account_pick.html",
+    return flask.render_template("profile_pick.html",
         service=service, profiles=profiles, form=form,
-        action_create=utils.url_for("account.create_profile", intent="account.pick"),
-        action_pick=utils.url_or_intent("account.status"))
+        action_create=utils.url_for("account.create_profile", intent="account.pick_profile"),
+        action_pick=utils.url_or_intent("account.home"))
 
 
 @blueprint.route("/profile/create", methods=["GET", "POST"])
-@security.admin_required()
+@security.authentication_required()
 def create_profile():
     service_uuid = flask.request.args.get("service_uuid") or flask.abort(404)
     service = models.Service.query.get(service_uuid) or flask.abort(404)
-    profiles = models.Profile.query.filter_by(
-        service_uuid=service.uuid,
-        user_uuid=flask_login.current_user.uuid
-    ).all()
-    if len(profiles) >= service.max_profiles:
-        flask.flash("You have reached the maximum number of profiles for that\
-            account", "error")
-        return flask.redirect(utils.url_or_intent("account.home"))
+    status = models.Profile.ACTIVE
+    profiles = models.Profile.filter(service, flask_login.current_user).all()
+    # Do not create profile for reserved or locked services
+    if service.policy in (models.Service.RESERVED, models.Service.LOCKED):
+        flask.flash("You cannot request a profile for this service", "danger")
+        return flask.redirect(flask.url_for("account.home"))
+    # Only burst services are allowed to exceed profile count
+    elif len(profiles) >= service.max_profiles and service.policy != models.Service.BURST:
+        flask.flash("Your reached the maximum number of profiles", "danger")
+        return flask.redirect(flask.url_for("account.home"))
+    # Managed services and bursting accounts require approval
+    elif len(profiles) >= service.max_profiles or service.policy == models.Service.MANAGED:
+        flask.flash("Your profile creation requires approval", "warning")
+        status = models.Profile.REQUEST
+    # Actually display the form
     form = forms.ProfileForm()
     if form.validate_on_submit():
         conflict = models.Profile.query.filter_by(
             service_uuid=service_uuid, username=form.username.data
         ).first()
-        print(conflict)
         if conflict:
             flask.flash("A profile with that username exists already", "danger")
         else:
@@ -59,11 +66,66 @@ def create_profile():
             profile.user = flask_login.current_user
             profile.service = service
             profile.comment = form.comment.data
+            profile.status = status
             models.db.session.add(profile)
             models.log(models.History.CREATE, profile.username, profile.comment,
                 user=flask_login.current_user, service=service, profile=profile)
             models.db.session.commit()
             return flask.redirect(utils.url_or_intent("account.home"))
-    return flask.render_template("profile_create.html",
-        title="Create a profile", subtitle="for {}".format(service.name),
-        form=form, service=service)
+    return flask.render_template("profile_create.html", form=form, service=service)
+
+
+@blueprint.route("/avatar/pick")
+@security.authentication_required()
+def pick_avatar():
+    service_uuid = flask.request.args.get("service_uuid") or flask.abort(404)
+    service = models.Service.query.get(service_uuid) or flask.abort(404)
+    avatar = models.Profile.filter(service, flask_login.current_user).first()
+    form = forms.ProfilePickForm()
+    if avatar:
+        if avatar.status == models.Profile.REQUEST:
+            flask.flash("Your account request is awaiting approval", "warning")
+            return flask.redirect(fflask.url_for("account.home"))
+        elif avatar.status == models.Profile.BLOCKED:
+            flask.flash("You are currently blocked", "danger")
+            return flask.redirect(fflask.url_for("account.home"))
+        elif avatar.status in (models.Profile.DELETED, models.Profile.UNCLAIMED):
+            flask.flash("Your avatar is unavailable", "danger")
+            return flask.redirect(fflask.url_for("account.home"))
+    elif service.policy not in (models.Service.OPEN, models.Service.MANAGED):
+        flask.flash("You cannot access this service", "danger")
+        return flask.redirect(fflask.url_for("account.home"))
+    else:
+        return flask.redirect(utils.url_for("account.create_avatar", intent="account.pick_avatar"))
+    return flask.render_template("avatar_pick.html",
+        service=service, avatar=avatar, form=form,
+        action_pick=utils.url_or_intent("account.home"),
+        action_create=utils.url_for("account.create_avatar", intent="account.pick_avatar"))
+
+
+@blueprint.route("/avatar/create", methods=["GET", "POST"])
+@security.authentication_required()
+def create_avatar():
+    service_uuid = flask.request.args.get("service_uuid") or flask.abort(404)
+    service = models.Service.query.get(service_uuid) or flask.abort(404)
+    # Cannot create an avatar if one exists already
+    existing = models.Profile.filter(service, flask_login.current_user).first()
+    existing and flask.abort(403)
+    # Cannot create an avatar for anything but a managed or open service
+    if service.policy == models.Service.OPEN:
+        status = models.Profile.ACTIVE
+    elif service.policy == models.Service.MANAGED:
+        status = models.Profile.REQUEST
+    else:
+        flask.abort(403)
+    form = forms.AvatarForm()
+    if form.validate_on_submit():
+        avatar = models.Profile()
+        avatar.username = flask_login.current_user.username
+        avatar.user = flask_login.current_user
+        avatar.service = service
+        avatar.status = models.Profile.ACTIVE
+        models.db.session.add(avatar)
+        models.db.session.commit()
+        return flask.redirect(utils.url_or_intent("account.home"))
+    return flask.render_template("avatar_create.html", form=form, service=service)
diff --git a/trurt/account/templates/account_home.html b/trurt/account/templates/account_home.html
index 02dbb6e282710f54a608cbd48930277e698481bf..771733d5118462e5d6387ea039ad0b0e61818d94 100644
--- a/trurt/account/templates/account_home.html
+++ b/trurt/account/templates/account_home.html
@@ -20,7 +20,7 @@
           {{ macros.infobox("Pending requests", "0", "green", "hourglass") }}
         </div>
         <div class="col-md-6 col-xs-12">
-          {{ macros.infobox("Role", "registered user", "yellow", "lock") }}
+          {{ macros.infobox("Role", "administrator" if current_user.is_admin else "registered user", "yellow", "lock") }}
         </div>
       </div>
     </section>
diff --git a/trurt/account/templates/avatar_create.html b/trurt/account/templates/avatar_create.html
new file mode 100644
index 0000000000000000000000000000000000000000..ca723579acf2e3569134abff960d5d39c9335f2b
--- /dev/null
+++ b/trurt/account/templates/avatar_create.html
@@ -0,0 +1,16 @@
+{% extends "base.html" %}
+
+{% block title %}Sign-up{% endblock %}
+{% block subtitle %}for the service {{ service.name }}{% endblock %}
+
+{% block content %}
+<div class="box">
+  <div class="box-body">
+    <p>Your are about to sign up for {{ service.name }}.</p>
+  </div>
+  <form method="POST" action="{{ action_pick }}" class="form">
+      {{ form.hidden_tag() }}
+      <input type="submit" value="Sign up" style="opacity: 0.8" class="btn btn-lg btn-flat bg-gray text-black">
+  </form>
+</div>
+{% endblock %}
diff --git a/trurt/account/templates/avatar_pick.html b/trurt/account/templates/avatar_pick.html
new file mode 100644
index 0000000000000000000000000000000000000000..b6314dbbdbe06a355dcca6f41dd19952cd16f03c
--- /dev/null
+++ b/trurt/account/templates/avatar_pick.html
@@ -0,0 +1,17 @@
+{% extends "base.html" %}
+
+{% block title %}Sign-in{% endblock %}
+{% block subtitle %}for the service {{ service.name }}{% endblock %}
+
+{% block content %}
+<div class="box">
+  <div class="box-body">
+    <p>Please confirm that you wish to sign in to {{ service.name }}.</p>
+  </div>
+  <form method="POST" action="{{ action_pick }}" class="form">
+      {{ form.hidden_tag() }}
+      <input type="hidden" name="profile_uuid" value="{{ avatar.uuid }}">
+      <input type="submit" value="Sign in" style="opacity: 0.8" class="btn btn-lg btn-flat bg-gray text-black">
+  </form>
+</div>
+{% endblock %}
diff --git a/trurt/account/templates/profile_create.html b/trurt/account/templates/profile_create.html
index a2d63c0f35212e83a93f7e1f01abdd50c8df7351..1219e0dfa51f232d9e72b4ff2abd281ad1cda2b3 100644
--- a/trurt/account/templates/profile_create.html
+++ b/trurt/account/templates/profile_create.html
@@ -1,5 +1,8 @@
 {% extends "base.html" %}
 
+{% block title %}New profile{% endblock %}
+{% block subtitle %}for the service {{ service.name }}{% endblock %}
+
 {% block content %}
 <div class="box">
   <div class="box-body">
diff --git a/trurt/account/templates/account_pick.html b/trurt/account/templates/profile_pick.html
similarity index 78%
rename from trurt/account/templates/account_pick.html
rename to trurt/account/templates/profile_pick.html
index 4f6e81647f661763c54d0ec634eff8d09843d76d..ebd3ec51656f4df2ccd36092dcac81a842a149a5 100644
--- a/trurt/account/templates/account_pick.html
+++ b/trurt/account/templates/profile_pick.html
@@ -27,11 +27,17 @@
   <div class="col-md-4 col-s-6 col-xs-12">
     <div class="box box-widget widget-user-2">
       <div class="widget-user-header bg-{{ colors[loop.index0 % 7] }}">
+        {% if profile.status == "active" %}
         <form method="POST" action="{{ action_pick }}" class="form">
             {{ form.hidden_tag() }}
             <input type="hidden" name="profile_uuid" value="{{ profile.uuid }}">
-            <input type="submit" value="Use this" style="opacity: 0.8" class="btn btn-lg btn-flat bg-gray text-black pull-right">
+            <input type="submit" value="Sign in" style="opacity: 0.8" class="btn btn-lg btn-flat bg-gray text-black pull-right">
         </form>
+        {% elif profile.status == "blocked" %}
+        <span class="btn btn-lg btn-flat bg-red text-black pull-right">Blocked</span>
+        {% elif profile.status == "request" %}
+        <span class="btn btn-lg btn-flat bg-orange text-black pull-right">Awaiting approval</span>
+        {% endif %}
         <h3 class="widget-header-username">{{ profile.username }}</h3>
         <h5 class="widget-header-desc">{{ profile.comment or "No profile description" }}&nbsp;</h5>
       </div>
diff --git a/trurt/models.py b/trurt/models.py
index 7f94c2ec43f24bac02106fb38be521bfca65b2d1..79ee76c2d7197eca0e049a5a71e6e7dac358ffa9 100644
--- a/trurt/models.py
+++ b/trurt/models.py
@@ -168,7 +168,10 @@ class Profile(db.Model):
     """
     __tablename__ = "profile"
 
+    UNCLAIMED = "unclaimed"
+    REQUEST = "request"
     ACTIVE = "active"
+    BLOCKED = "blocked"
     DELETED = "deleted"
 
     user_uuid = db.Column(db.String(36), db.ForeignKey(User.uuid))
@@ -179,12 +182,19 @@ class Profile(db.Model):
         backref=db.backref('profiles', cascade='all, delete-orphan'))
 
     username = db.Column(db.String(255), nullable=False)
-    status = db.Column(db.String(25), nullable=False, default=ACTIVE)
+    status = db.Column(db.String(25), nullable=False)
 
     @property
     def email(self):
         return "{}@{}".format(self.uuid, app.config.get("MAIL_DOMAIN"))
 
+    @classmethod
+    def filter(cls, service, user):
+        return cls.query.filter_by(
+            service_uuid=service.uuid,
+            user_uuid=user.uuid,
+        ).filter(cls.status.in_((cls.ACTIVE, cls.BLOCKED, cls.REQUEST)))
+
 
 class History(db.Model):
     """ Records an even in an account's or profile's lifetime.
diff --git a/trurt/sso/saml.py b/trurt/sso/saml.py
index f9191da325837ac56bd240aa3c349f3b96f9fa28..ffd137d34f0ad3d2fd1853865e0598ee5bf79027 100644
--- a/trurt/sso/saml.py
+++ b/trurt/sso/saml.py
@@ -159,7 +159,7 @@ def saml_redirect(service_uuid):
     # Get the profile from user input (implies redirects)
     service = models.Service.query.get(service_uuid) or flask.abort(404)
     service.protocol == "saml" or flask.abort(404)
-    profile = account.profiles.pick_profile(
+    profile = account.profiles.get_profile(
         service, intent="sso.saml_redirect", service_uuid=service_uuid
     ) or flask.abort(403)
     # Parse the authentication request and check the ACS