diff --git a/hiboo/models.py b/hiboo/models.py
index f4c8f83e3650020c24b453808ab2df01d27c453e..33b7fafd9e62177dfe7976008dbcc4bc45d3358c 100644
--- a/hiboo/models.py
+++ b/hiboo/models.py
@@ -164,6 +164,7 @@ class Service(db.Model):
     description = db.Column(db.String())
     policy = db.Column(db.String(255))
     max_profiles = db.Column(db.Integer(), nullable=False, default=1)
+    profile_regex = db.Column(db.String(255))
     same_username = db.Column(db.Boolean(), nullable=False, default=False)
     config = db.Column(mutable.MutableDict.as_mutable(JSONEncoded))
 
diff --git a/hiboo/profile/login.py b/hiboo/profile/login.py
index 298a75e5a44da8c0037f03f2619217e7e5ba1354..3e4b8af254aa3a1f82d2758b41cd29f33571b604 100644
--- a/hiboo/profile/login.py
+++ b/hiboo/profile/login.py
@@ -2,6 +2,7 @@ from hiboo.profile import blueprint, forms
 from hiboo import models, utils, security
 from hiboo import user as hiboo_user
 from passlib import context, hash
+from wtforms import validators
 
 import flask
 import flask_login
@@ -48,6 +49,10 @@ def create(service_uuid, create_for=False):
             status = models.Profile.REQUEST
     # Actually display the form
     form = forms.ProfileForm()
+    if service.profile_regex:
+        form.username.validators.append(
+            validators.Regexp("^{}$".format(service.profile_regex)),
+        )
     if service.same_username:
         form.username.data = user.username
         form.username.render_kw = {"readonly": True}
diff --git a/hiboo/service/forms.py b/hiboo/service/forms.py
index cd7fafceeb678ffee8c2ca0f494da728ad96c47f..86efd8232dd8916a5593e1511b559dbc7b8f02d8 100644
--- a/hiboo/service/forms.py
+++ b/hiboo/service/forms.py
@@ -16,5 +16,6 @@ class ServiceForm(flask_wtf.FlaskForm):
         choices=list(models.Service.POLICIES.items()))
     max_profiles = fields.IntegerField(_('Maximum profile count'),
         [validators.NumberRange(1, 1000)])
+    profile_regex = fields.StringField(_('Profile usenrame regex'))
     same_username = fields.BooleanField(_('Disable per-profile username'))
     submit = fields.SubmitField(_('Submit'))
diff --git a/migrations/versions/ccae1d6b9c13_add_profile_regex.py b/migrations/versions/ccae1d6b9c13_add_profile_regex.py
new file mode 100644
index 0000000000000000000000000000000000000000..cd1e600564b37fc9326b75d492244f2e48bb3936
--- /dev/null
+++ b/migrations/versions/ccae1d6b9c13_add_profile_regex.py
@@ -0,0 +1,26 @@
+""" Set a regex for constraining profile username
+
+Revision ID: ccae1d6b9c13
+Revises: ebc103f8bc5e
+Create Date: 2020-03-18 11:30:52.611835
+"""
+
+from alembic import op
+import sqlalchemy as sa
+import hiboo
+
+
+revision = 'ccae1d6b9c13'
+down_revision = 'ebc103f8bc5e'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    with op.batch_alter_table('service') as batch_op:    
+        batch_op.add_column(sa.Column('profile_regex', sa.String(length=255), nullable=True))
+
+
+def downgrade():
+    with op.batch_alter_table('service') as batch_op:    
+        batch_op.drop_column('profile_regex')