diff --git a/app/models.py b/app/models.py
index 760c83e290b4ab2d90f272ca811897b603f390e3..9d641ee5d9d8897326b79379428658dc5b106d3e 100644
--- a/app/models.py
+++ b/app/models.py
@@ -1676,14 +1676,22 @@ class NetworkScope(CreatedMixin, db.Model):
 
     @validates("supernet")
     def validate_supernet(self, key, supernet):
-        """Ensure the supernet doesn't overlap existing supernets"""
+        """Ensure the supernet doesn't overlap existing supernets
+
+        Also ensure it's a supernet of all existing networks (when editing)
+        """
         supernet_address = ipaddress.ip_network(supernet)
-        existing_scopes = NetworkScope.query.all()
+        existing_scopes = NetworkScope.query.filter(NetworkScope.id != self.id).all()
         for existing_scope in existing_scopes:
             if supernet_address.overlaps(existing_scope.supernet_ip):
                 raise ValidationError(
                     f"{supernet} overlaps {existing_scope} ({existing_scope.supernet_ip})"
                 )
+        for network in self.networks:
+            if not network.network_ip.subnet_of(supernet_address):
+                raise ValidationError(
+                    f"{network.network_ip} is not a subnet of {supernet}"
+                )
         return supernet
 
     @validates("networks")
@@ -1696,12 +1704,39 @@ class NetworkScope(CreatedMixin, db.Model):
             )
         existing_networks = Network.query.filter_by(scope=self).all()
         for existing_network in existing_networks:
+            if existing_network.id == network.id:
+                # Same network added again during edit via admin interface
+                continue
             if network.network_ip.overlaps(existing_network.network_ip):
                 raise ValidationError(
                     f"{network.network_ip} overlaps {existing_network} ({existing_network.network_ip})"
                 )
         return network
 
+    @validates("first_vlan")
+    def validate_first_vlan(self, key, value):
+        """Ensure the first vlan is lower than any network vlan id"""
+        if value is None:
+            return value
+        for network in self.networks:
+            if int(value) > network.vlan_id:
+                raise ValidationError(
+                    f"First vlan shall be lower than {network.vlan_name} vlan: {network.vlan_id}"
+                )
+        return value
+
+    @validates("last_vlan")
+    def validate_last_vlan(self, key, value):
+        """Ensure the last vlan is greater than any network vlan id"""
+        if value is None:
+            return value
+        for network in self.networks:
+            if int(value) < network.vlan_id:
+                raise ValidationError(
+                    f"Last vlan shall be greater than {network.vlan_name} vlan: {network.vlan_id}"
+                )
+        return value
+
     @property
     def supernet_ip(self):
         return ipaddress.ip_network(self.supernet)
diff --git a/app/network/views.py b/app/network/views.py
index d8937cfaf0da13462454abf5a7d044aeefbfb39c..e3fd7bc90334db2d2bab3ea89feb08860d20c73f 100644
--- a/app/network/views.py
+++ b/app/network/views.py
@@ -627,6 +627,40 @@ def create_scope():
     return render_template("network/create_scope.html", form=form)
 
 
+@bp.route("/scopes/edit/<name>", methods=("GET", "POST"))
+@login_groups_accepted("admin")
+def edit_scope(name):
+    scope = models.NetworkScope.query.filter_by(name=name).first_or_404()
+    form = NetworkScopeForm(request.form, obj=scope)
+    if form.validate_on_submit():
+        try:
+            for field in (
+                "name",
+                "description",
+                "first_vlan",
+                "last_vlan",
+                "supernet",
+                "domain_id",
+            ):
+                setattr(scope, field, getattr(form, field).data)
+        except ValidationError as e:
+            # Check for error raised by model validation (not implemented in form validation)
+            current_app.logger.warning(f"{e}")
+            flash(f"{e}", "error")
+            return render_template("network/edit_scope.html", form=form)
+        current_app.logger.debug(f"Trying to update: {scope!r}")
+        try:
+            db.session.commit()
+        except sa.exc.IntegrityError as e:
+            db.session.rollback()
+            current_app.logger.warning(f"{e}")
+            flash(f"{e}", "error")
+        else:
+            flash(f"Network Scope {scope} updated!", "success")
+        return redirect(url_for("network.view_scope", name=scope.name))
+    return render_template("network/edit_scope.html", form=form)
+
+
 @bp.route("/_retrieve_first_available_ip/<int:network_id>")
 @login_required
 def retrieve_first_available_ip(network_id):
diff --git a/app/templates/network/edit_scope.html b/app/templates/network/edit_scope.html
new file mode 100644
index 0000000000000000000000000000000000000000..cecafa7390a52e81423e107ee5bb496790b51b4c
--- /dev/null
+++ b/app/templates/network/edit_scope.html
@@ -0,0 +1,30 @@
+{% extends "network/scopes.html" %}
+{% from "_helpers.html" import render_field %}
+
+{% block title %}Edit {{ form.name.data }} network Scope{% endblock %}
+
+{% block scopes_nav %}
+    <li class="nav-item">
+      <a class="nav-link" href="{{ url_for('network.view_scope', name=form.name.data) }}">View network scope</a>
+    </li>
+    <li class="nav-item">
+      <a class="nav-link active" href="{{ url_for('network.edit_scope', name=form.name.data) }}">Edit network scope</a>
+    </li>
+{% endblock %}
+
+{% block scopes_main %}
+  <form id="editScopeForm" method="POST">
+    {{ form.hidden_tag() }}
+    {{ render_field(form.name) }}
+    {{ render_field(form.description) }}
+    {{ render_field(form.first_vlan) }}
+    {{ render_field(form.last_vlan) }}
+    {{ render_field(form.supernet) }}
+    {{ render_field(form.domain_id) }}
+    <div class="form-group row">
+      <div class="col-sm-10">
+        <button type="submit" class="btn btn-primary">Submit</button>
+      </div>
+    </div>
+  </form>
+{%- endblock %}
diff --git a/app/templates/network/view_scope.html b/app/templates/network/view_scope.html
index 47cb6fb0b54aa9aa6b34ac303d0d6443d948e0d5..9e401dd49ed93656f0a529b870720c476d9acb79 100644
--- a/app/templates/network/view_scope.html
+++ b/app/templates/network/view_scope.html
@@ -7,6 +7,9 @@
 <li class="nav-item">
   <a class="nav-link active" href="{{ url_for('network.view_scope', name=scope.name) }}">View network scope</a>
 </li>
+<li class="nav-item">
+  <a class="nav-link" href="{{ url_for('network.edit_scope', name=scope.name) }}">Edit network scope</a>
+</li>
 {% endblock %}
 
 {% block scopes_main %}
diff --git a/tests/functional/test_models.py b/tests/functional/test_models.py
index 187918145914b34bdb61e0be4b5bf5f16df8986a..9305190edd6e5c89412fb649508734f79f4f3010 100644
--- a/tests/functional/test_models.py
+++ b/tests/functional/test_models.py
@@ -950,6 +950,55 @@ def test_network_scope_overlapping(address, network_scope_factory):
     )
 
 
+def test_network_scope_supernet_validation(network_scope_factory, network_factory):
+    scope = network_scope_factory(
+        first_vlan=3800, last_vlan=4000, supernet="172.30.0.0/16"
+    )
+    network1 = network_factory(
+        vlan_id=3800,
+        address="172.30.0.0/23",
+        first_ip="172.30.0.3",
+        last_ip="172.30.1.240",
+        scope=scope,
+    )
+    address = "192.168.0.0/16"
+    with pytest.raises(ValidationError) as excinfo:
+        scope.supernet = "192.168.0.0/16"
+    assert f"{network1.network_ip} is not a subnet of {address}" in str(excinfo.value)
+
+
+def test_network_scope_first_vlan_validation(network_scope_factory, network_factory):
+    scope = network_scope_factory(
+        first_vlan=200, last_vlan=400, supernet="172.30.0.0/16"
+    )
+    network1 = network_factory(
+        vlan_id=220,
+        address="172.30.0.0/23",
+        first_ip="172.30.0.3",
+        last_ip="172.30.1.240",
+        scope=scope,
+    )
+    with pytest.raises(ValidationError) as excinfo:
+        scope.first_vlan = 230
+    assert f"First vlan shall be lower than {network1} vlan: 220" in str(excinfo.value)
+
+
+def test_network_scope_last_vlan_validation(network_scope_factory, network_factory):
+    scope = network_scope_factory(
+        first_vlan=200, last_vlan=400, supernet="172.30.0.0/16"
+    )
+    network1 = network_factory(
+        vlan_id=220,
+        address="172.30.0.0/23",
+        first_ip="172.30.0.3",
+        last_ip="172.30.1.240",
+        scope=scope,
+    )
+    with pytest.raises(ValidationError) as excinfo:
+        scope.last_vlan = 210
+    assert f"Last vlan shall be greater than {network1} vlan: 220" in str(excinfo.value)
+
+
 def test_host_sensitive_field_update_on_network_change(
     network_scope_factory, network_factory, interface_factory, host_factory
 ):
diff --git a/tests/functional/test_web.py b/tests/functional/test_web.py
index 07710920e0f071869a6b150392c0cabfea097b7d..4a15dbae0ca7c36cfad26713972ca4ada9772713 100644
--- a/tests/functional/test_web.py
+++ b/tests/functional/test_web.py
@@ -799,6 +799,47 @@ def test_edit_network(
     assert network.sensitive is True
 
 
+def test_edit_network_scope(
+    logged_admin_client, domain_factory, network_scope_factory, network_factory
+):
+    domain1 = domain_factory(name="lab.example.org")
+    name = "MyNetworks"
+    scope = network_scope_factory(
+        name=name,
+        first_vlan=100,
+        last_vlan=200,
+        supernet="192.168.0.0/16",
+        domain_id=domain1.id,
+    )
+    network_factory(
+        vlan_name="my-network",
+        domain=domain1,
+        scope=scope,
+        vlan_id=110,
+        address="192.168.0.0/24",
+        first_ip="192.168.0.11",
+        last_ip="192.168.0.249",
+        gateway="192.168.0.254",
+    )
+    new_domain = domain_factory(name="lab.example.eu")
+    form = {
+        "name": name,
+        "description": "Scope for MyNetworks",
+        "first_vlan": 105,
+        "last_vlan": 150,
+        "supernet": scope.supernet,
+        "domain_id": new_domain.id,
+    }
+    response = logged_admin_client.post(f"/network/scopes/edit/{name}", data=form)
+    assert response.status_code == 302
+    # The scope was updated
+    updated_scope = models.NetworkScope.query.filter_by(name=name).first()
+    assert updated_scope is not None
+    assert updated_scope.first_vlan == 105
+    assert updated_scope.last_vlan == 150
+    assert updated_scope.domain == new_domain
+
+
 def test_create_item_invalid_ics_id(logged_rw_client):
     ics_id = "AAA1100"
     form = {"ics_id": ics_id, "serial_number": "12345"}