diff --git a/SAS/TMSS/client/bin/CMakeLists.txt b/SAS/TMSS/client/bin/CMakeLists.txt
index a7142728b7503dd6acabf1ac85e4a611c7e8b7c7..d2bd6170e887de5af55d2c6ec98eb1adfcf656bc 100644
--- a/SAS/TMSS/client/bin/CMakeLists.txt
+++ b/SAS/TMSS/client/bin/CMakeLists.txt
@@ -5,3 +5,5 @@ lofar_add_bin_scripts(tmss_get_subtasks)
 lofar_add_bin_scripts(tmss_get_subtask_predecessors)
 lofar_add_bin_scripts(tmss_get_subtask_successors)
 lofar_add_bin_scripts(tmss_schedule_subtask)
+lofar_add_bin_scripts(tmss_get_setting)
+lofar_add_bin_scripts(tmss_set_setting)
diff --git a/SAS/TMSS/client/bin/tmss_get_setting b/SAS/TMSS/client/bin/tmss_get_setting
new file mode 100755
index 0000000000000000000000000000000000000000..34d79f641c2f704a83064f2bc8caf37c49159b18
--- /dev/null
+++ b/SAS/TMSS/client/bin/tmss_get_setting
@@ -0,0 +1,23 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2012-2015  ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This file is part of the LOFAR software suite.
+# The LOFAR software suite is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# The LOFAR software suite is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+
+from lofar.sas.tmss.client.mains import main_get_setting
+
+if __name__ == "__main__":
+    main_get_setting()
diff --git a/SAS/TMSS/client/bin/tmss_set_setting b/SAS/TMSS/client/bin/tmss_set_setting
new file mode 100755
index 0000000000000000000000000000000000000000..e54dd118f9a9bd0967059a004e4d69f87612a6c4
--- /dev/null
+++ b/SAS/TMSS/client/bin/tmss_set_setting
@@ -0,0 +1,23 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2012-2015  ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This file is part of the LOFAR software suite.
+# The LOFAR software suite is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# The LOFAR software suite is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+
+from lofar.sas.tmss.client.mains import main_set_setting
+
+if __name__ == "__main__":
+    main_set_setting()
diff --git a/SAS/TMSS/client/lib/mains.py b/SAS/TMSS/client/lib/mains.py
index f645b9643a195d213ee4411a7cd3e964419afcbe..ca614b9f218c475ec0c4bdca66dba0d259f3838b 100644
--- a/SAS/TMSS/client/lib/mains.py
+++ b/SAS/TMSS/client/lib/mains.py
@@ -125,3 +125,31 @@ def main_schedule_subtask():
     except Exception as e:
         print(e)
         exit(1)
+
+
+def main_get_setting():
+    parser = argparse.ArgumentParser()
+    parser.add_argument("setting_name", type=str, help="The name of the TMSS setting to get")
+    args = parser.parse_args()
+
+    try:
+        with TMSSsession.create_from_dbcreds_for_ldap() as session:
+            pprint(session.get_setting(args.setting_name))
+    except Exception as e:
+        print(e)
+        exit(1)
+
+
+def main_set_setting():
+    parser = argparse.ArgumentParser()
+    parser.add_argument("setting_name", type=str, help="The name of the TMSS setting to set")
+    parser.add_argument("setting_value", type=lambda s: s.lower() in ['true', 'True', '1'], # argparse is noot very good at speaking bool...
+                        help="The value to set for the TMSS setting")
+    args = parser.parse_args()
+
+    try:
+        with TMSSsession.create_from_dbcreds_for_ldap() as session:
+            pprint(session.set_setting(args.setting_name, args.setting_value))
+    except Exception as e:
+        print(e)
+        exit(1)
diff --git a/SAS/TMSS/client/lib/tmss_http_rest_client.py b/SAS/TMSS/client/lib/tmss_http_rest_client.py
index 867a29c05bc2c371bed2c51dfeb88d690f230bd4..1f426c0b52a58d0c33c54cf10583ba0c6e5d2408 100644
--- a/SAS/TMSS/client/lib/tmss_http_rest_client.py
+++ b/SAS/TMSS/client/lib/tmss_http_rest_client.py
@@ -216,3 +216,27 @@ class TMSSsession(object):
         returns the scheduled subtask upon success, or raises."""
         return self.get_path_as_json_object('subtask/%s/schedule' % subtask_id)
 
+    def get_setting(self, setting_name: str) -> {}:
+        """get the value of a TMSS setting.
+        returns the setting value upon success, or raises."""
+        response = self.session.get(url='%s/setting/%s/' % (self.base_url, setting_name),
+                                    params={'format': 'json'})
+
+        if response.status_code >= 200 and response.status_code < 300:
+            return json.loads(response.content.decode('utf-8'))['value']
+
+        content = response.content.decode('utf-8')
+        raise Exception("Could not get setting with name %s.\nResponse: %s" % (setting_name, content))
+
+    def set_setting(self, setting_name: str, setting_value: bool) -> {}:
+        """set a value for a TMSS setting.
+        returns the setting value upon success, or raises."""
+        response = self.session.patch(url='%s/setting/%s/' % (self.base_url, setting_name),
+                                      json={'value': setting_value})
+
+        if response.status_code >= 200 and response.status_code < 300:
+            return json.loads(response.content.decode('utf-8'))['value']
+
+        content = response.content.decode('utf-8')
+        raise Exception("Could not set status with url %s - %s %s - %s" % (response.request.url, response.status_code, responses.get(response.status_code), content))
+
diff --git a/SAS/TMSS/src/remakemigrations.py b/SAS/TMSS/src/remakemigrations.py
index 10c7ac1b29588ed394da76a70ec06e50d925b3bb..03fdec4cec3f94aa2345d79cb6c91d279b51395c 100755
--- a/SAS/TMSS/src/remakemigrations.py
+++ b/SAS/TMSS/src/remakemigrations.py
@@ -77,7 +77,8 @@ class Migration(migrations.Migration):
     operations = [ migrations.RunSQL('ALTER SEQUENCE tmssapp_SubTask_id_seq RESTART WITH 2000000;'),
                    migrations.RunPython(populate_choices),
                    migrations.RunPython(populate_misc),
-                   migrations.RunPython(populate_lofar_json_schemas) ]
+                   migrations.RunPython(populate_lofar_json_schemas),
+                   migrations.RunPython(populate_settings)]
 """
 
 
diff --git a/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py b/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py
index af286d3fe40e8f425759edbffbf66f830cb496cd..a20fb8d083719afb7dd0dcd78c279a503bcbda8b 100644
--- a/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py
+++ b/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py
@@ -1,4 +1,4 @@
-# Generated by Django 3.0.6 on 2020-06-09 17:31
+# Generated by Django 3.0.6 on 2020-06-17 15:34
 
 from django.conf import settings
 import django.contrib.postgres.fields
@@ -284,6 +284,15 @@ class Migration(migrations.Migration):
                 'abstract': False,
             },
         ),
+        migrations.CreateModel(
+            name='Flag',
+            fields=[
+                ('value', models.CharField(max_length=128, primary_key=True, serialize=False, unique=True)),
+            ],
+            options={
+                'abstract': False,
+            },
+        ),
         migrations.CreateModel(
             name='GeneratorTemplate',
             fields=[
@@ -628,6 +637,19 @@ class Migration(migrations.Migration):
                 ('validation_code_js', models.CharField(help_text='JavaScript code for additional (complex) validation.', max_length=128)),
             ],
         ),
+        migrations.CreateModel(
+            name='Setting',
+            fields=[
+                ('tags', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=128), blank=True, default=list, help_text='User-defined search keywords for object.', size=8)),
+                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
+                ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
+                ('name', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, primary_key=True, serialize=False, to='tmssapp.Flag', unique=True)),
+                ('value', models.BooleanField()),
+            ],
+            options={
+                'abstract': False,
+            },
+        ),
         migrations.AddConstraint(
             model_name='tasktemplate',
             constraint=models.UniqueConstraint(fields=('name', 'version'), name='TaskTemplate_unique_name_version'),
@@ -1044,6 +1066,10 @@ class Migration(migrations.Migration):
             model_name='subtask',
             index=django.contrib.postgres.indexes.GinIndex(fields=['tags'], name='tmssapp_sub_tags_d2fc43_gin'),
         ),
+        migrations.AddIndex(
+            model_name='setting',
+            index=django.contrib.postgres.indexes.GinIndex(fields=['tags'], name='tmssapp_set_tags_41a1ba_gin'),
+        ),
         migrations.AddIndex(
             model_name='defaulttasktemplate',
             index=django.contrib.postgres.indexes.GinIndex(fields=['tags'], name='tmssapp_def_tags_c88200_gin'),
diff --git a/SAS/TMSS/src/tmss/tmssapp/migrations/0002_populate.py b/SAS/TMSS/src/tmss/tmssapp/migrations/0002_populate.py
index e33461a92950831b9b30d7cec2b13a718689035e..a4fcecd5e9c23454c0158ee93ae88e3d3ecb3321 100644
--- a/SAS/TMSS/src/tmss/tmssapp/migrations/0002_populate.py
+++ b/SAS/TMSS/src/tmss/tmssapp/migrations/0002_populate.py
@@ -18,4 +18,5 @@ class Migration(migrations.Migration):
     operations = [ migrations.RunSQL('ALTER SEQUENCE tmssapp_SubTask_id_seq RESTART WITH 2000000;'),
                    migrations.RunPython(populate_choices),
                    migrations.RunPython(populate_misc),
-                   migrations.RunPython(populate_lofar_json_schemas) ]
+                   migrations.RunPython(populate_lofar_json_schemas),
+                   migrations.RunPython(populate_settings)]
diff --git a/SAS/TMSS/src/tmss/tmssapp/models/specification.py b/SAS/TMSS/src/tmss/tmssapp/models/specification.py
index 2956c3e09c58785fe0948e66f72a0cce770d5ad0..2d93d37047d325562c538c78e1a6b43fda372824 100644
--- a/SAS/TMSS/src/tmss/tmssapp/models/specification.py
+++ b/SAS/TMSS/src/tmss/tmssapp/models/specification.py
@@ -131,8 +131,20 @@ class CopyReason(AbstractChoice):
         REPEATED = "repeated"
 
 
+class Flag(AbstractChoice):
+    """Defines the model and predefined list of possible Flags to be used in Setting.
+    The items in the Choises class below are automagically populated into the database via a data migration."""
+    class Choices(Enum):
+        AUTOSCHEDULE = "allow_scheduling_observations"
+
+
 # concrete models
 
+class Setting(BasicCommon):
+    name = ForeignKey('Flag', null=False, on_delete=PROTECT, unique=True, primary_key=True)
+    value = BooleanField(null=False)
+
+
 class TaskConnector(BasicCommon):
     role = ForeignKey('Role', null=False, on_delete=PROTECT)
     datatype = ForeignKey('Datatype', null=False, on_delete=PROTECT)
@@ -381,4 +393,3 @@ class TaskRelationBlueprint(BasicCommon):
             validate_json_against_schema(self.selection_doc, self.selection_template.schema)
 
         super().save(force_insert, force_update, using, update_fields)
-
diff --git a/SAS/TMSS/src/tmss/tmssapp/populate.py b/SAS/TMSS/src/tmss/tmssapp/populate.py
index 7a16ac32591fc47cb543e0bdf719c70d4b2a5af7..8d0daea2ee277a864da2f27f58422d691b243119 100644
--- a/SAS/TMSS/src/tmss/tmssapp/populate.py
+++ b/SAS/TMSS/src/tmss/tmssapp/populate.py
@@ -32,9 +32,12 @@ def populate_choices(apps, schema_editor):
     :return: None
     '''
     for choice_class in [Role, Datatype, Dataformat, CopyReason,
-                         SubtaskState, SubtaskType, StationType, Algorithm, ScheduleMethod]:
+                         SubtaskState, SubtaskType, StationType, Algorithm, ScheduleMethod, Flag]:
         choice_class.objects.bulk_create([choice_class(value=x.value) for x in choice_class.Choices])
 
+def populate_settings(apps, schema_editor):
+    Setting.objects.create(name=Flag.objects.get(value='allow_scheduling_observations'), value=True)
+
 
 def populate_lofar_json_schemas(apps, schema_editor):
     _populate_dataproduct_specifications_templates()
@@ -98,6 +101,7 @@ def populate_resources(apps, schema_editor):
     ResourceType.objects.create(name="cep_storage", description="Amount of storage at CEP processing cluster", resource_unit=ru_bytes)
     ResourceType.objects.create(name="cep_processing_hours", description="Number of processing hours for CEP processing cluster", resource_unit=ru_hours)
 
+
 def populate_misc(apps, schema_editor):
     cluster = Cluster.objects.create(name="CEP4", location="CIT")
     fs = Filesystem.objects.create(name="LustreFS", cluster=cluster, capacity=3.6e15)
diff --git a/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py b/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py
index a745c8e18e36f4995e1e2a75020b5d4142010258..afbc1b2ed5e7c32e5f2f222b313da3e87acac3a3 100644
--- a/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py
+++ b/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py
@@ -148,6 +148,18 @@ class ResourceTypeSerializer(RelationalHyperlinkedModelSerializer):
         extra_fields = ['name']
 
 
+class FlagSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = models.Flag
+        fields = '__all__'
+
+
+class SettingSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = models.Setting
+        fields = '__all__'
+
+
 class SchedulingSetSerializer(RelationalHyperlinkedModelSerializer):
 
     # Create a JSON editor form to replace the simple text field based on the schema in the template that this
diff --git a/SAS/TMSS/src/tmss/tmssapp/subtasks.py b/SAS/TMSS/src/tmss/tmssapp/subtasks.py
index 781a4512802f0f627376966fb9a5043fb719d7e9..80f76dd09e646e544159f99c6b2c29f1c6a9cfa2 100644
--- a/SAS/TMSS/src/tmss/tmssapp/subtasks.py
+++ b/SAS/TMSS/src/tmss/tmssapp/subtasks.py
@@ -417,6 +417,13 @@ def schedule_observation_subtask(observation_subtask: Subtask):
                                                                                                           observation_subtask.specifications_template.type,
                                                                                                           SubtaskType.Choices.OBSERVATION.value))
 
+    # check if settings allow scheduling observations
+    # (not sure if this should be in check_prerequities_for_scheduling() instead....?)
+    setting = Setting.objects.get(name='allow_scheduling_observations')
+    if not setting.value:
+        raise SubtaskSchedulingException("Cannot schedule subtask id=%d because setting %s=%s does not allow that." %
+                                         (observation_subtask.pk, setting.name, setting.value))
+
     # step 1: set state to SCHEDULING
     observation_subtask.state = SubtaskState.objects.get(value=SubtaskState.Choices.SCHEDULING.value)
     observation_subtask.save()
diff --git a/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py b/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py
index 4516d434acbf9e031a0c6daad5d01a019668cea2..b8d0b66260b3477bc662f5967fc9d64a2cc21593 100644
--- a/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py
+++ b/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py
@@ -162,6 +162,16 @@ class SchedulingSetViewSet(LOFARViewSet):
     serializer_class = serializers.SchedulingSetSerializer
 
 
+class FlagViewSet(LOFARViewSet):
+    queryset = models.Flag.objects.all()
+    serializer_class = serializers.FlagSerializer
+
+
+class SettingViewSet(LOFARViewSet):
+    queryset = models.Setting.objects.all()
+    serializer_class = serializers.SettingSerializer
+
+
 class SchedulingUnitDraftViewSet(LOFARViewSet):
     queryset = models.SchedulingUnitDraft.objects.all()
     serializer_class = serializers.SchedulingUnitDraftSerializer
diff --git a/SAS/TMSS/src/tmss/urls.py b/SAS/TMSS/src/tmss/urls.py
index e6c2a1d6c0c277299ebc64dd55555f18af3eee05..5edc14292953efb714e45c777d36f3444ad608fa 100644
--- a/SAS/TMSS/src/tmss/urls.py
+++ b/SAS/TMSS/src/tmss/urls.py
@@ -71,6 +71,7 @@ router.register(r'role', viewsets.RoleViewSet)
 router.register(r'datatype', viewsets.DatatypeViewSet)
 router.register(r'dataformat', viewsets.DataformatViewSet)
 router.register(r'copy_reason', viewsets.CopyReasonViewSet)
+router.register(r'flag', viewsets.FlagViewSet)
 
 # templates
 router.register(r'generator_template', viewsets.GeneratorTemplateViewSet)
@@ -89,6 +90,7 @@ router.register(r'project', viewsets.ProjectViewSet)
 router.register(r'resource_unit', viewsets.ResourceUnitViewSet)
 router.register(r'resource_type', viewsets.ResourceTypeViewSet)
 router.register(r'project_quota', viewsets.ProjectQuotaViewSet)
+router.register(r'setting', viewsets.SettingViewSet)
 
 router.register(r'scheduling_set', viewsets.SchedulingSetViewSet)
 router.register(r'scheduling_unit_draft', viewsets.SchedulingUnitDraftViewSet)
diff --git a/SAS/TMSS/test/t_subtasks.py b/SAS/TMSS/test/t_subtasks.py
index 4988e783d4e5be2e253456c370778c9d5b450d51..86df10801234222c82ef1e856058096dc30775be 100755
--- a/SAS/TMSS/test/t_subtasks.py
+++ b/SAS/TMSS/test/t_subtasks.py
@@ -42,7 +42,6 @@ from lofar.sas.tmss.tmss.tmssapp import models
 from lofar.sas.tmss.tmss.tmssapp.subtasks import *
 
 
-
 class SubtaskInputSelectionFilteringTest(unittest.TestCase):
 
     # todo: merge in tests from TMSS-207 and deduplicate staticmethods
@@ -134,6 +133,17 @@ class SubtaskInputSelectionFilteringTest(unittest.TestCase):
         self.assertEqual(set(pipe_in2.dataproducts.all()), {dp2_2})
 
 
+class SettingTest(unittest.TestCase):
+
+    def test_schedule_observation_subtask_raises_when_flag_is_false(self):
+        setting = Setting.objects.get(name='allow_scheduling_observations')
+        setting.value = False
+        setting.save()
+        obs_st = SubtaskInputSelectionFilteringTest.create_subtask_object('observation', 'defined')
+
+        with self.assertRaises(SubtaskSchedulingException):
+            schedule_observation_subtask(obs_st)
+
 if __name__ == "__main__":
     os.environ['TZ'] = 'UTC'
     unittest.main()