diff --git a/greg/management/commands/import_sponsors_from_cerebrum.py b/greg/management/commands/import_sponsors_from_cerebrum.py
new file mode 100644
index 0000000000000000000000000000000000000000..7139e11579117429426f0ca4347251f6ed9ffbe0
--- /dev/null
+++ b/greg/management/commands/import_sponsors_from_cerebrum.py
@@ -0,0 +1,199 @@
+"""
+Fetch sponsors for all units in GREG.
+
+Uses the members of the adm-leder-<legacy_stedkode> groups to
+populate Sponsors and SponsorOrganizationalUnits.
+
+This script does only remove the SponsorOrganizationalUnit.
+The Sponsor objects are kept, even with no units
+"""
+
+from typing import Optional, Tuple
+import cerebrum_client
+
+import structlog
+
+from cerebrum_client import CerebrumClient
+from django.conf import settings
+from django.core.management.base import BaseCommand
+
+from greg.models import OrganizationalUnit, Sponsor, SponsorOrganizationalUnit
+
+logger = structlog.getLogger(__name__)
+
+
+class Command(BaseCommand):
+    help = __doc__
+
+    CEREBRUM_SOURCE = "cerebrum"
+    CEREBRUM_FEIDE_INST = "uio.no"
+    CEREBRUM_NAME_SOURCE_PRIORITY = ["Cached", "Override", "DFO_SAP", "FS", "Manual"]
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.client = CerebrumClient(**settings.CEREBRUM_CLIENT)
+
+    def _has_active_dfo_aff(self, person_id: str):
+        """Check that a person has a valid employee affiliation from DFØ."""
+
+        dfo_employee_affs = [
+            x
+            for x in self.client.get_person_affiliations(person_id)
+            if x.source_system == "DFO_SAP" and x.affiliation == "ANSATT"
+        ]
+
+        return len(dfo_employee_affs) > 0
+
+    def _upsert_sponsor_unit_link(self, sponsor: Sponsor, unit: OrganizationalUnit):
+        """Ensure a link between sponsor and unit."""
+        sunit, created = SponsorOrganizationalUnit.objects.get_or_create(
+            sponsor=sponsor,
+            organizational_unit=unit,
+            source=self.CEREBRUM_SOURCE,
+            automatic=True,
+        )
+        if created:
+            logger.info("sponsor_ou_link_create", sponsor=sponsor.id, sunit=sunit.id)
+        else:
+            logger.info("sponsor_ou_link_found", sponsor=sponsor.id, sunit=sunit.id)
+            sunit.hierarchical_access = settings.CEREBRUM_HIERARCHICAL_ACCESS
+            sunit.save()
+
+        return SponsorOrganizationalUnit.objects.get(id=sunit.id)
+
+    def _remove_sponsor_unit_link(self, sunit: SponsorOrganizationalUnit):
+        logger.info("sponsor_ou_deleted", sunit=sunit.id)
+        sunit.delete()
+
+    def _get_person_name(
+        self, person: cerebrum_client.models.Person
+    ) -> Tuple[Optional[str], Optional[str]]:
+        """Get a persons chosen name."""
+        first_names = {x.source_system: x for x in person.names if x.variant == "FIRST"}
+        last_names = {x.source_system: x for x in person.names if x.variant == "LAST"}
+
+        for source_system in self.CEREBRUM_NAME_SOURCE_PRIORITY:
+            if source_system in first_names and source_system in last_names:
+                return first_names[source_system].name, last_names[source_system].name
+
+        return None, None
+
+    def _get_feide_id(self, person_id: str) -> Optional[str]:
+        """Infer the feide id from the primary user."""
+        primary_uname = self.client.get_person_primary_account_name(person_id)
+
+        if primary_uname:
+            return f"{primary_uname}@{self.CEREBRUM_FEIDE_INST}"
+        return None
+
+    def _upsert_sponsor_from_cerebrum(
+        self, person_id: str, unit: OrganizationalUnit
+    ) -> Optional[Sponsor]:
+        """Insert or update a sponsor from Cerebum data."""
+        person = self.client.get_person(person_id)
+        if not person:
+            logger.warning("cerebrum_person_missing", cerebrum_person_id=person_id)
+            return None
+
+        if not self._has_active_dfo_aff(person_id):
+            logger.warning("cerebrum_not_an_employee", cerebrum_person_id=person_id)
+            return None
+
+        feide_id = self._get_feide_id(person_id)
+        if not feide_id:
+            logger.warning("cerebrum_no_primary_account", cerebrum_person_id=person_id)
+            return None
+
+        first_name, last_name = self._get_person_name(person)
+        if not first_name or not last_name:
+            logger.warning("cerebrum_no_valid_name", cerebrum_person_id=person_id)
+            return None
+
+        try:
+            sponsor = Sponsor.objects.get(feide_id=feide_id)
+            sponsor.first_name = first_name
+            sponsor.last_name = last_name
+            sponsor.save()
+            logger.info(
+                "sponsor_updated", sponsor=sponsor.id, cerebrum_person_id=person_id
+            )
+
+        except Sponsor.DoesNotExist:
+            sponsor = Sponsor.objects.create(
+                first_name=first_name,
+                last_name=last_name,
+                feide_id=feide_id,
+            )
+            logger.info(
+                "sponsor_created", sponsor=sponsor.id, cerebrum_person_id=person_id
+            )
+        return Sponsor.objects.get(id=sponsor.id)
+
+    def handle(self, *args, **options):
+        """Import of Sponsors from Cerebrum."""
+        active_units = OrganizationalUnit.objects.filter(
+            active=True,
+            deleted=False,
+        )
+
+        logger.info("import_start", nr_of_units=len(active_units))
+        for unit in active_units:
+            logger.bind(unit=unit.id)
+            sko = unit.identifiers.filter(name="legacy_stedkode").first()
+            if not sko:
+                logger.warning("orgreg_unit_missing_legacy_stedkode")
+                continue
+            logger.bind(legacy_stedkode=sko.value)
+
+            current_sponsors = unit.link_unit.filter(
+                automatic=True, source=self.CEREBRUM_SOURCE
+            ).all()
+
+            group_name = f"adm-leder-{sko.value}"
+            group = self.client.get_group(group_name)
+            if not group:
+                # No group in cererbum, remove sponsors.
+                logger.info(
+                    "cerebrum_group_not_found",
+                    unit_id=unit.id,
+                    cerebrum_group=group_name,
+                )
+                for sponsor in current_sponsors:
+                    self._remove_sponsor_unit_link(sponsor)
+                continue
+
+            if group.expire_date:
+                # Group is expired, remove sponsors
+                logger.info(
+                    "cerebrum_group_expired",
+                    unit_id=unit.id,
+                    cerebrum_group=group_name,
+                )
+                for sponsor in current_sponsors:
+                    self._remove_sponsor_unit_link(sponsor)
+                continue
+
+            group_members = list(self.client.list_group_members(group_name))
+            if not group_members:
+                # No members in group, remove sponsors
+                logger.info(
+                    "cerebrum_group_empty", unit_id=unit.id, cerebrum_group=group_name
+                )
+                for sponsor in current_sponsors:
+                    self._remove_sponsor_unit_link(sponsor)
+                continue
+
+            cerebrum_sponsors = set()
+            for member in group_members:
+                if member.type == "person":
+                    sponsor = self._upsert_sponsor_from_cerebrum(member.id, unit)
+                    if sponsor:
+                        sponsor_link = self._upsert_sponsor_unit_link(
+                            sponsor=sponsor, unit=unit
+                        )
+                        cerebrum_sponsors.add(sponsor_link)
+
+            for sponsor in set(current_sponsors) - cerebrum_sponsors:
+                self._remove_sponsor_unit_link(sponsor)
+
+        logger.info("import_end")
diff --git a/greg/migrations/0014_add_sponsor_ou_source_data.py b/greg/migrations/0014_add_sponsor_ou_source_data.py
new file mode 100644
index 0000000000000000000000000000000000000000..734591e8d36fa835a19f648cbecbb7f1059ff4d4
--- /dev/null
+++ b/greg/migrations/0014_add_sponsor_ou_source_data.py
@@ -0,0 +1,23 @@
+# Generated by Django 3.2.9 on 2021-11-11 14:35
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('greg', '0013_delete_scheduletask'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='sponsororganizationalunit',
+            name='automatic',
+            field=models.BooleanField(default=False),
+        ),
+        migrations.AddField(
+            model_name='sponsororganizationalunit',
+            name='source',
+            field=models.CharField(blank=True, max_length=256),
+        ),
+    ]
diff --git a/greg/models.py b/greg/models.py
index 168c69d37616bc611e64926fcbf63c741f20eb73..90d54ca027e484855234163dacd07470e4d285d1 100644
--- a/greg/models.py
+++ b/greg/models.py
@@ -458,6 +458,8 @@ class SponsorOrganizationalUnit(BaseModel):
         "OrganizationalUnit", on_delete=models.PROTECT, related_name="link_unit"
     )
     hierarchical_access = models.BooleanField()
+    automatic = models.BooleanField(default=False)
+    source = models.CharField(max_length=256, blank=True)
 
     class Meta:
         constraints = [
diff --git a/gregsite/settings/dev.py b/gregsite/settings/dev.py
index 5120e02bafbd65944f622b2e137410fb0b27b672..e989299f3e37394bcb514220b71ec4a9ba6d2d1a 100644
--- a/gregsite/settings/dev.py
+++ b/gregsite/settings/dev.py
@@ -17,6 +17,12 @@ ORGREG_CLIENT = {
     "headers": {"X-Gravitee-Api-Key": "bar"},
 }
 
+CEREBRUM_CLIENT = {
+    "url": "https://example.com/fake/",
+    "headers": {"X-Gravitee-Api-Key": "bar"},
+}
+CEREBRUM_HIERARCHICAL_ACCESS = True
+
 Q_CLUSTER = {
     "name": "greg",
     "workers": 4,
diff --git a/mypy.ini b/mypy.ini
index 67b5755d1536d9ff082523fd6e614ed10ab59839..971a70a5197920f3f192089742afbf4f9a15e0c7 100644
--- a/mypy.ini
+++ b/mypy.ini
@@ -14,6 +14,9 @@ django_settings_module = gregsite.settings.dev
 # Ignore problems in auto generated modules.
 ignore_errors = True
 
+[mypy-cerebrum_client.*]
+ignore_missing_imports = True
+
 [mypy-dirtyfields]
 ignore_missing_imports = True
 
diff --git a/poetry.lock b/poetry.lock
index 84dfd0d43707f484dd0d7cda23a9436dce94e3b1..2c491b9f065beb6b15d7b64b570a041e97d5b0c0 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -119,6 +119,25 @@ jinxed = {version = ">=1.1.0", markers = "platform_system == \"Windows\""}
 six = ">=1.9.0"
 wcwidth = ">=0.1.4"
 
+[[package]]
+name = "cerebrum-client"
+version = "1.9.2"
+description = "Client for the Cerebrum REST API"
+category = "main"
+optional = false
+python-versions = "*"
+develop = false
+
+[package.dependencies]
+pydantic = "*"
+requests = "*"
+
+[package.source]
+type = "git"
+url = "https://git.app.uib.no/it-bott-integrasjoner/cerebrum-client.git"
+reference = "v1.9.2"
+resolved_reference = "95a183956ddd164f2a9fa86ed219ef640e72b7be"
+
 [[package]]
 name = "certifi"
 version = "2021.10.8"
@@ -1099,14 +1118,14 @@ test = ["fixtures", "mock", "purl", "pytest", "sphinx", "testrepository (>=0.0.1
 
 [[package]]
 name = "rope"
-version = "0.21.0"
+version = "0.21.1"
 description = "a python refactoring library..."
 category = "dev"
 optional = false
 python-versions = "*"
 
 [package.extras]
-dev = ["pytest", "pytest-timeout"]
+dev = ["build", "pytest", "pytest-timeout"]
 
 [[package]]
 name = "sentry-sdk"
@@ -1284,7 +1303,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
 [metadata]
 lock-version = "1.1"
 python-versions = "^3.9"
-content-hash = "45574277e3b663b9eb9b18a24ef0996878944461d137b084199690e9683e32f7"
+content-hash = "9887d688cf3c515273b5ccbc7313ba2795d6fbf6e6828091537761c376dbee87"
 
 [metadata.files]
 ansicon = [
@@ -1327,6 +1346,7 @@ blessed = [
     {file = "blessed-1.19.0-py2.py3-none-any.whl", hash = "sha256:1f2d462631b2b6d2d4c3c65b54ef79ad87a6ca2dd55255df2f8d739fcc8a1ddb"},
     {file = "blessed-1.19.0.tar.gz", hash = "sha256:4db0f94e5761aea330b528e84a250027ffe996b5a94bf03e502600c9a5ad7a61"},
 ]
+cerebrum-client = []
 certifi = [
     {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"},
     {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"},
@@ -2012,7 +2032,8 @@ requests-mock = [
     {file = "requests_mock-1.9.3-py2.py3-none-any.whl", hash = "sha256:0a2d38a117c08bb78939ec163522976ad59a6b7fdd82b709e23bb98004a44970"},
 ]
 rope = [
-    {file = "rope-0.21.0.tar.gz", hash = "sha256:366789e069a267296889b2ee7631f9278173b5e7d468f2ea08abe26069a52aef"},
+    {file = "rope-0.21.1-py3-none-any.whl", hash = "sha256:7fa433eb946bf806a419a3da354cd9b56d565cadf7159952c8e71c72d4b1a8ec"},
+    {file = "rope-0.21.1.tar.gz", hash = "sha256:4fe61ea25ca64f1819be57fbb44ee07ca98b3dce08a0ceaaf3c6d6166b603f7f"},
 ]
 sentry-sdk = [
     {file = "sentry-sdk-1.4.3.tar.gz", hash = "sha256:b9844751e40710e84a457c5bc29b21c383ccb2b63d76eeaad72f7f1c808c8828"},
diff --git a/pyproject.toml b/pyproject.toml
index 8759d5092c85427677c13f4bbf5dae3cf1fdfcb0..dd8482696de3ff89475606814de131dcb169ef89 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -27,6 +27,7 @@ django-q = "^1.3.9"
 django-structlog = "^2.1.3"
 structlog = "^21.2.0"
 phonenumbers = "^8.12.35"
+cerebrum-client = {git = "https://git.app.uib.no/it-bott-integrasjoner/cerebrum-client.git", rev = "v1.9.2"}
 
 [tool.poetry.dev-dependencies]
 Faker = "*"