diff --git a/gracedb/events/migrations/0027_label_protected.py b/gracedb/events/migrations/0027_label_protected.py
new file mode 100644
index 0000000000000000000000000000000000000000..c3dfaeea25d207ed49527793c6e443f5314b30a9
--- /dev/null
+++ b/gracedb/events/migrations/0027_label_protected.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.16 on 2018-10-08 17:42
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('events', '0026_increase_channel_maxlength'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='label',
+            name='protected',
+            field=models.BooleanField(default=False),
+        ),
+    ]
diff --git a/gracedb/events/migrations/0028_make_labels_protected.py b/gracedb/events/migrations/0028_make_labels_protected.py
new file mode 100644
index 0000000000000000000000000000000000000000..b9c64efec757f43dd9c3019f9d476ac3e358a82c
--- /dev/null
+++ b/gracedb/events/migrations/0028_make_labels_protected.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.16 on 2018-10-08 17:43
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+PROTECTED_LABELS = [
+    'H1OK',
+    'H1NO',
+    'L1OK',
+    'L1NO',
+    'V1OK',
+    'V1NO',
+    'ADVOK',
+    'ADVNO',
+]
+
+def protect_labels(apps, schema_editor):
+    Label = apps.get_model('events', 'Label')
+
+    for label in PROTECTED_LABELS:
+        l = Label.objects.get(name=label)
+        l.protected = True
+        l.save(update_fields=['protected'])
+
+
+def unprotect_labels(apps, schema_editor):
+    Label = apps.get_model('events', 'Label')
+
+    for label in PROTECTED_LABELS:
+        l = Label.objects.get(name=label)
+        l.protected = False
+        l.save(update_fields=['protected'])
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('events', '0027_label_protected'),
+    ]
+
+    operations = [
+        migrations.RunPython(protect_labels, unprotect_labels),
+    ]
diff --git a/gracedb/events/models.py b/gracedb/events/models.py
index 7241f4651a4489ca7fdac9dc1b109d7a3affb395..000c450e3a73dacb75dddfea92ff1c1e4b42eddb 100644
--- a/gracedb/events/models.py
+++ b/gracedb/events/models.py
@@ -89,6 +89,11 @@ class Label(models.Model):
     defaultColor = models.CharField(max_length=20, unique=False,
         default="black")
     description = models.TextField(blank=False)
+    # protected = True means that the Label should not be "writeable": i.e.,
+    # users should not be apply to directly apply or remove it.  This is useful
+    # for labels that are added and removed as part of a process, like
+    # signoffs, for examples.
+    protected = models.BooleanField(default=False)
 
     def __unicode__(self):
         return self.name