diff --git a/frontend/src/routes/guest/register/authenticationMethod.ts b/frontend/src/routes/guest/register/authenticationMethod.ts
index f01a26db655697443c98a7e2c6dd9266cb00b920..26315154748ceeab7e74e9cbe6fc07056d89c410 100644
--- a/frontend/src/routes/guest/register/authenticationMethod.ts
+++ b/frontend/src/routes/guest/register/authenticationMethod.ts
@@ -1,9 +1,12 @@
 /**
- * Controls what is shown in the registration form
+ * Lists the different ways the guest can reach the registration page.
+ * Either he can choose login by Feide or ID-porten, or he can use the manual registration,
+ * which means that he only will have the information the sponsor entered when the invite was created attached to him.
  */
 enum AuthenticationMethod {
   Feide,
   Invite,
+  IdPorten,
 }
 
 export default AuthenticationMethod
diff --git a/frontend/src/routes/guest/register/index.tsx b/frontend/src/routes/guest/register/index.tsx
index 44829257c452aff89f5f0cd21adeb7d273b66db9..be680523694705f2fc68c051d0f29f654f73212b 100644
--- a/frontend/src/routes/guest/register/index.tsx
+++ b/frontend/src/routes/guest/register/index.tsx
@@ -10,12 +10,12 @@ import format from 'date-fns/format'
 import parse from 'date-fns/parse'
 import { Box, Button, CircularProgress } from '@mui/material'
 
-import { splitPhoneNumber, submitJsonOpts, fetchJsonOpts } from 'utils'
+import { fetchJsonOpts, splitPhoneNumber, submitJsonOpts } from 'utils'
 import { guestConsentStepEnabled } from 'appConfig'
 import Page from 'components/page'
 import OverviewGuestButton from '../../components/overviewGuestButton'
 import { GuestRegisterCallableMethods } from './guestRegisterCallableMethods'
-import { GuestRegisterData, GuestConsentData } from './enteredGuestData'
+import { GuestConsentData, GuestRegisterData } from './enteredGuestData'
 import { GuestInviteInformation } from './guestDataForm'
 import AuthenticationMethod from './authenticationMethod'
 import GuestRegisterStep from './steps/register'
@@ -116,10 +116,19 @@ export default function GuestRegister() {
     setFetchInvitationDataError(null)
     const data: InvitationData = await response.json()
 
-    const authenticationMethod =
-      data.meta.session_type === 'invite'
-        ? AuthenticationMethod.Invite
-        : AuthenticationMethod.Feide
+    let authenticationMethod = AuthenticationMethod.Invite
+    switch (data.meta.session_type) {
+      case 'feide':
+        authenticationMethod = AuthenticationMethod.Feide
+        break
+
+      case 'idporten':
+        authenticationMethod = AuthenticationMethod.IdPorten
+        break
+
+      default:
+      // Already set to invite
+    }
 
     const [countryCode, nationalNumber] = data.person.private_mobile
       ? splitPhoneNumber(data.person.private_mobile)
diff --git a/frontend/src/routes/guest/register/steps/register.test.tsx b/frontend/src/routes/guest/register/steps/register.test.tsx
index 8ffcf4408d266f48a80459a3e8d441a10705ac7c..8f8c1d83915c53faa1bb97aa5ea7607a06ec1c3b 100644
--- a/frontend/src/routes/guest/register/steps/register.test.tsx
+++ b/frontend/src/routes/guest/register/steps/register.test.tsx
@@ -98,7 +98,7 @@ test('Name editable if missing and invite is Feide', async () => {
   })
 })
 
-test('Identifier fields disabled if invite if Feide and national ID present', async () => {
+test('Identifier fields disabled if invite is Feide and national ID present', async () => {
   const nextHandler = (registerData: GuestRegisterData) => {
     console.log(`Entered data: ${registerData}`)
   }
@@ -124,7 +124,33 @@ test('Identifier fields disabled if invite if Feide and national ID present', as
   })
 })
 
-test('Identifier fields enabled if invite if Feide but national ID number missing', async () => {
+test('Identifier fields enabled if invite is Feide but national ID number missing', async () => {
+  const nextHandler = (registerData: GuestRegisterData) => {
+    console.log(`Entered data: ${registerData}`)
+  }
+
+  const testData = getEmptyGuestData()
+  testData.authentication_method = AuthenticationMethod.Feide
+  testData.fnr = ''
+
+  render(
+    <LocalizationProvider dateAdapter={AdapterDateFns}>
+      <GuestRegisterStep
+        nextHandler={nextHandler}
+        initialGuestData={testData}
+        registerData={null}
+      />
+    </LocalizationProvider>
+  )
+
+  await waitFor(() => {
+    expect(screen.queryByTestId('national-id-number-input')).toBeEnabled()
+    expect(screen.queryByTestId('passport_number_input')).toBeEnabled()
+    expect(screen.queryByTestId('passport-nationality-input')).toBeEnabled()
+  })
+})
+
+test('Identifier fields disabled and name fields enabled if invite is ID-porten', async () => {
   const nextHandler = (registerData: GuestRegisterData) => {
     console.log(`Entered data: ${registerData}`)
   }
diff --git a/frontend/src/routes/guest/register/steps/register.tsx b/frontend/src/routes/guest/register/steps/register.tsx
index a07cf65d5a32a217576ab0d9eb515704ab03a972..4da19a725000abbc8625da05179cc4d55dccf5c6 100644
--- a/frontend/src/routes/guest/register/steps/register.tsx
+++ b/frontend/src/routes/guest/register/steps/register.tsx
@@ -8,7 +8,7 @@ import {
   TextField,
   Typography,
 } from '@mui/material'
-import { SubmitHandler, Controller, useForm } from 'react-hook-form'
+import { Controller, SubmitHandler, useForm } from 'react-hook-form'
 import React, {
   forwardRef,
   Ref,
@@ -17,7 +17,7 @@ import React, {
   useImperativeHandle,
   useState,
 } from 'react'
-import { useTranslation, Trans } from 'react-i18next'
+import { Trans, useTranslation } from 'react-i18next'
 import {
   CountryCallingCode,
   CountryCode,
@@ -224,20 +224,24 @@ const GuestRegisterStep = forwardRef(
           countryTuple1[1].localeCompare(countryTuple2[1])
       )
 
+    const inviteOrIdPorten =
+      initialGuestData.authentication_method === AuthenticationMethod.Invite ||
+      initialGuestData.authentication_method === AuthenticationMethod.IdPorten
+
+    // There is no name coming from ID-porten so allow the name to be editable
     const formSetup: FormSetup = {
       allowFirstNameEditable:
-        initialGuestData.authentication_method ===
-          AuthenticationMethod.Invite ||
-        initialGuestData.first_name.length === 0,
+        inviteOrIdPorten || initialGuestData.first_name.length === 0,
       allowLastNameEditable:
-        initialGuestData.authentication_method ===
-          AuthenticationMethod.Invite ||
-        initialGuestData.last_name.length === 0,
-      // If there is a national ID number (presumably from Feide),
+        inviteOrIdPorten || initialGuestData.last_name.length === 0,
+      // If there is a national ID number (presumably from Feide or ID porten),
       // already present, then do not allow the user to change the data
       // in the identifier fields
       disableIdentifierFields:
-        initialGuestData.authentication_method === AuthenticationMethod.Feide &&
+        (initialGuestData.authentication_method ===
+          AuthenticationMethod.Feide ||
+          initialGuestData.authentication_method ===
+            AuthenticationMethod.IdPorten) &&
         initialGuestData.fnr !== null &&
         initialGuestData.fnr?.length !== 0,
     }
diff --git a/gregui/api/views/invitation.py b/gregui/api/views/invitation.py
index d4027b0224f375134a0179459c1b9a250579aa27..eda7fa6244364a24e72b32a4b16d9ef65fc470bb 100644
--- a/gregui/api/views/invitation.py
+++ b/gregui/api/views/invitation.py
@@ -176,6 +176,7 @@ class CheckInvitationView(APIView):
 class SessionType(Enum):
     INVITE = "invite"
     FEIDE = "feide"
+    ID_PORTEN = "idporten"
 
 
 class InvitedGuestView(GenericAPIView):
@@ -198,7 +199,7 @@ class InvitedGuestView(GenericAPIView):
         "consents",
         "gender",
     ]
-    fields_allowed_to_update_if_feide = [
+    fields_allowed_to_update_if_feide_or_idporten = [
         "private_mobile",
         "passport",
         "consents",
@@ -233,12 +234,7 @@ class InvitedGuestView(GenericAPIView):
         person = role.person
         sponsor = role.sponsor
 
-        # If the user is not logged in then tell the client to take him through the manual registration process
-        session_type = (
-            SessionType.INVITE.value
-            if request.user.is_anonymous
-            else SessionType.FEIDE.value
-        )
+        session_type = self._determine_session_type(person, request)
 
         data = {
             "person": {
@@ -265,10 +261,32 @@ class InvitedGuestView(GenericAPIView):
                 "end": role.end_date,
                 "contact_person_unit": role.contact_person_unit,
             },
-            "meta": {"session_type": session_type},
+            "meta": {"session_type": session_type.value},
         }
         return JsonResponse(data=data, status=status.HTTP_200_OK)
 
+    @staticmethod
+    def _determine_session_type(person, request) -> SessionType:
+        # We do not store the login used in the session, and it is not necessary either, we will
+        # just look at the information registered on the person attached to the user to figure
+        # out how he logged in
+        if request.user.is_anonymous:
+            # If the user is not logged in then tell the client to take him through the manual registration process
+            return SessionType.INVITE
+        elif person.fnr and person.fnr.source == "idporten":
+            # If the user has logged in through ID-porten the national ID number should have been
+            # added to the person at this stage
+            return SessionType.ID_PORTEN
+        elif person.feide_id:
+            # User is logged in and has a Feide ID attached to him, assume information about him has come from Feide
+            return SessionType.FEIDE
+        else:
+            # Not expected, default to invite
+            logger.warning(
+                "unexpected_state_when_determining_session_type", person_id=person.id
+            )
+            return SessionType.INVITE
+
     def post(self, request, *args, **kwargs):
         """
         Endpoint for confirmation of data updated by guest
@@ -290,7 +308,10 @@ class InvitedGuestView(GenericAPIView):
         person = invite_link.invitation.role.person
         data = request.data
 
-        optional_response = self._verify_only_allowed_updates_in_request(person, data)
+        session_type = self._determine_session_type(person, request)
+        optional_response = self._verify_only_allowed_updates_in_request(
+            person, data, session_type
+        )
         if optional_response:
             # Some illegal update was in the data
             return optional_response
@@ -317,7 +338,7 @@ class InvitedGuestView(GenericAPIView):
         return Response(status=status.HTTP_200_OK)
 
     def _verify_only_allowed_updates_in_request(
-        self, person: Person, data
+        self, person: Person, data, session_type: SessionType
     ) -> Optional[Response]:
         # This is not a case that is expected to happen, but having the check here as a safeguard
         # since it is an indication of a bug if does
@@ -343,8 +364,9 @@ class InvitedGuestView(GenericAPIView):
             data,
             self.fields_allowed_to_update_if_invite
             if feide_id is None
-            else self.fields_allowed_to_update_if_feide,
+            else self.fields_allowed_to_update_if_feide_or_idporten,
             person,
+            session_type,
         )
         if illegal_fields:
             return Response(
@@ -356,7 +378,9 @@ class InvitedGuestView(GenericAPIView):
             )
 
     @staticmethod
-    def _illegal_updates(request_data, changeable_fields, person) -> List[str]:
+    def _illegal_updates(
+        request_data, changeable_fields, person, session_type: SessionType
+    ) -> List[str]:
         person_data = request_data.get("person", {})
         changed_fields = person_data.keys()
 
@@ -366,6 +390,13 @@ class InvitedGuestView(GenericAPIView):
                 # Consents can be inserted and updated, no need for further checks on them
                 continue
 
+            if (
+                changed_field == "first_name" or changed_field == "last_name"
+            ) and session_type == SessionType.ID_PORTEN:
+                # From ID-porten only the national ID-number is given, so the name must be what the
+                # sponsor wrote, and can be changed
+                continue
+
             try:
                 attribute = getattr(person, changed_field)
             except AttributeError:
diff --git a/gregui/tests/api/views/test_invitation.py b/gregui/tests/api/views/test_invitation.py
index bc3ed9170eac34316636364a28216e45adf71397..152c1b367e55bc071122454ad3f9e4a4e72e2830 100644
--- a/gregui/tests/api/views/test_invitation.py
+++ b/gregui/tests/api/views/test_invitation.py
@@ -609,8 +609,100 @@ def test_invalid_gender_rejected(client, invited_person_verified_nin):
         }
     }
     response = client.post(url, data, format="json")
-
     assert response.status_code == status.HTTP_400_BAD_REQUEST
 
     person = Person.objects.get()
     assert person.gender is None
+
+
+@pytest.mark.django_db
+def test_session_type_feide_id(
+    client, invited_person_feide_id_set, log_in, user_no_profile
+):
+    _, invitation_link = invited_person_feide_id_set
+    # get a session
+    client.post(
+        reverse("gregui-v1:invite-verify"), data={"invite_token": invitation_link.uuid}
+    )
+    log_in(user_no_profile)
+
+    response = client.get(reverse("gregui-v1:invited-info"))
+    assert response.json().get("meta").get("session_type") == "feide"
+
+
+@pytest.mark.django_db
+def test_session_type_feide_id_name_update_fails(
+    client, invited_person_feide_id_set, log_in, user_no_profile
+):
+    person, invitation_link = invited_person_feide_id_set
+    # get a session
+    client.post(
+        reverse("gregui-v1:invite-verify"), data={"invite_token": invitation_link.uuid}
+    )
+    log_in(user_no_profile)
+
+    # Try to update the name, this should fail. Also need to specify a mobile phone in the input,
+    # since this is a required field the user has to fill in
+    data = {
+        "person": {
+            "first_name": "Updated",
+            "last_name": "Updated2",
+            "private_mobile": "+4797543992",
+        }
+    }
+    url = reverse("gregui-v1:invited-info")
+
+    session = client.session
+    session["invite_id"] = str(invitation_link.uuid)
+    session.save()
+
+    response = client.post(url, data, format="json")
+
+    assert response.status_code == status.HTTP_400_BAD_REQUEST
+    person.refresh_from_db()
+
+    # The name should not have changed
+    assert person.first_name == "Victor"
+    assert person.last_name == "Verified"
+
+
+@pytest.mark.django_db
+def test_session_type_id_porten(
+    client,
+    invited_person_id_porten_nin_set,
+    log_in,
+    user_no_profile,
+    confirmation_template,
+):
+    person, invitation_link = invited_person_id_porten_nin_set
+    # get a session
+    client.post(
+        reverse("gregui-v1:invite-verify"), data={"invite_token": invitation_link.uuid}
+    )
+    log_in(user_no_profile)
+
+    response = client.get(reverse("gregui-v1:invited-info"))
+    assert response.json().get("meta").get("session_type") == "idporten"
+
+    # Try to update the name, this is allowed since the name is not coming from ID-porten and
+    # can be updated by the user
+    data = {
+        "person": {
+            "first_name": "Updated",
+            "last_name": "Updated2",
+            "private_mobile": "+4797543992",
+        }
+    }
+    url = reverse("gregui-v1:invited-info")
+
+    session = client.session
+    session["invite_id"] = str(invitation_link.uuid)
+    session.save()
+
+    response = client.post(url, data, format="json")
+
+    assert response.status_code == status.HTTP_200_OK, response.data
+    person.refresh_from_db()
+
+    assert person.first_name == "Updated"
+    assert person.last_name == "Updated2"
diff --git a/gregui/tests/conftest.py b/gregui/tests/conftest.py
index 565bebeee7f10b53429e37b01f4b7bac907c068b..2ce271496c8bef763cbce72eee760b66700c3e32 100644
--- a/gregui/tests/conftest.py
+++ b/gregui/tests/conftest.py
@@ -294,7 +294,6 @@ def create_invitation_link(
     def create_invitation_link(
         invitation: Invitation, expire_date: datetime.datetime = invitation_valid_date
     ) -> InvitationLink:
-
         invitation_link = InvitationLink(
             invitation=invitation,
             expire=expire_date,
@@ -489,6 +488,72 @@ def invited_person_verified_nin(
     )
 
 
+@pytest.fixture
+def invited_person_feide_id_set(
+    create_person,
+    create_role,
+    create_invitation,
+    create_invitation_link,
+    sponsor_foo,
+    unit_foo,
+    role_type_foo,
+) -> Tuple[Person, InvitationLink]:
+    person = create_person(
+        first_name="Victor",
+        last_name="Verified",
+        email="foo@bar2.com",
+    )
+    person.identities.create(
+        type=Identity.IdentityType.NORWEGIAN_NATIONAL_ID_NUMBER,
+        value="12042335418",
+        source="feide",
+    )
+    person.identities.create(
+        type=Identity.IdentityType.FEIDE_ID, value="foo@bar2.com", source="feide"
+    )
+
+    role = create_role(
+        person=person, sponsor=sponsor_foo, unit=unit_foo, role_type=role_type_foo
+    )
+
+    invitation = create_invitation(role=role)
+    invitation_link = create_invitation_link(invitation=invitation)
+    return Person.objects.get(id=person.id), InvitationLink.objects.get(
+        id=invitation_link.id
+    )
+
+
+@pytest.fixture
+def invited_person_id_porten_nin_set(
+    create_person,
+    create_role,
+    create_invitation,
+    create_invitation_link,
+    sponsor_foo,
+    unit_foo,
+    role_type_foo,
+) -> Tuple[Person, InvitationLink]:
+    person = create_person(
+        first_name="Victor",
+        last_name="Verified",
+        email="foo@bar2.com",
+    )
+    person.identities.create(
+        type=Identity.IdentityType.NORWEGIAN_NATIONAL_ID_NUMBER,
+        value="12042335418",
+        source="idporten",
+    )
+    role = create_role(
+        person=person, sponsor=sponsor_foo, unit=unit_foo, role_type=role_type_foo
+    )
+
+    invitation = create_invitation(role=role)
+    invitation_link = create_invitation_link(invitation=invitation)
+    return Person.objects.get(id=person.id), InvitationLink.objects.get(
+        id=invitation_link.id
+    )
+
+
 @pytest.fixture
 def log_in(client) -> Callable[[UserModel], APIClient]:
     def _log_in(user):