diff --git a/Makefile b/Makefile
index c504d228d7..d89e01b199 100644
--- a/Makefile
+++ b/Makefile
@@ -21,7 +21,7 @@ pg_name := $(shell python -m authentik.lib.config postgresql.name 2>/dev/null)
 CODESPELL_ARGS = -D - -D .github/codespell-dictionary.txt \
 		-I .github/codespell-words.txt \
 		-S 'web/src/locales/**' \
-		-S 'website/developer-docs/api/reference/**' \
+		-S 'website/docs/developer-docs/api/reference/**' \
 		-S '**/node_modules/**' \
 		-S '**/dist/**' \
 		$(PY_SOURCES) \
diff --git a/authentik/blueprints/v1/importer.py b/authentik/blueprints/v1/importer.py
index a86e62c4a8..700a32ad73 100644
--- a/authentik/blueprints/v1/importer.py
+++ b/authentik/blueprints/v1/importer.py
@@ -50,7 +50,6 @@ from authentik.enterprise.providers.microsoft_entra.models import (
     MicrosoftEntraProviderGroup,
     MicrosoftEntraProviderUser,
 )
-from authentik.enterprise.providers.rac.models import ConnectionToken
 from authentik.enterprise.providers.ssf.models import StreamEvent
 from authentik.enterprise.stages.authenticator_endpoint_gdtc.models import (
     EndpointDevice,
@@ -72,6 +71,7 @@ from authentik.providers.oauth2.models import (
     DeviceToken,
     RefreshToken,
 )
+from authentik.providers.rac.models import ConnectionToken
 from authentik.providers.scim.models import SCIMProviderGroup, SCIMProviderUser
 from authentik.rbac.models import Role
 from authentik.sources.scim.models import SCIMSourceGroup, SCIMSourceUser
diff --git a/authentik/core/tasks.py b/authentik/core/tasks.py
index 1a565d8f7f..c2e6929a20 100644
--- a/authentik/core/tasks.py
+++ b/authentik/core/tasks.py
@@ -67,6 +67,8 @@ def clean_expired_models(self: SystemTask):
                 raise ImproperlyConfigured(
                     "Invalid session_storage setting, allowed values are db and cache"
                 )
+    if CONFIG.get("session_storage", "cache") == "db":
+        DBSessionStore.clear_expired()
     LOGGER.debug("Expired sessions", model=AuthenticatedSession, amount=amount)
 
     messages.append(f"Expired {amount} {AuthenticatedSession._meta.verbose_name_plural}")
diff --git a/authentik/enterprise/providers/rac/apps.py b/authentik/enterprise/providers/rac/apps.py
deleted file mode 100644
index 6359c5594b..0000000000
--- a/authentik/enterprise/providers/rac/apps.py
+++ /dev/null
@@ -1,14 +0,0 @@
-"""RAC app config"""
-
-from authentik.enterprise.apps import EnterpriseConfig
-
-
-class AuthentikEnterpriseProviderRAC(EnterpriseConfig):
-    """authentik enterprise rac app config"""
-
-    name = "authentik.enterprise.providers.rac"
-    label = "authentik_providers_rac"
-    verbose_name = "authentik Enterprise.Providers.RAC"
-    default = True
-    mountpoint = ""
-    ws_mountpoint = "authentik.enterprise.providers.rac.urls"
diff --git a/authentik/enterprise/settings.py b/authentik/enterprise/settings.py
index a032fbd016..7f735eb312 100644
--- a/authentik/enterprise/settings.py
+++ b/authentik/enterprise/settings.py
@@ -16,7 +16,6 @@ TENANT_APPS = [
     "authentik.enterprise.audit",
     "authentik.enterprise.providers.google_workspace",
     "authentik.enterprise.providers.microsoft_entra",
-    "authentik.enterprise.providers.rac",
     "authentik.enterprise.providers.ssf",
     "authentik.enterprise.stages.authenticator_endpoint_gdtc",
     "authentik.enterprise.stages.source",
diff --git a/authentik/outposts/api/outposts.py b/authentik/outposts/api/outposts.py
index ba84cf42e3..b4723ce3a6 100644
--- a/authentik/outposts/api/outposts.py
+++ b/authentik/outposts/api/outposts.py
@@ -19,7 +19,6 @@ from authentik.core.api.used_by import UsedByMixin
 from authentik.core.api.utils import JSONDictField, ModelSerializer, PassiveSerializer
 from authentik.core.models import Provider
 from authentik.enterprise.license import LicenseKey
-from authentik.enterprise.providers.rac.models import RACProvider
 from authentik.lib.utils.time import timedelta_from_string, timedelta_string_validator
 from authentik.outposts.api.service_connections import ServiceConnectionSerializer
 from authentik.outposts.apps import MANAGED_OUTPOST, MANAGED_OUTPOST_NAME
@@ -31,6 +30,7 @@ from authentik.outposts.models import (
 )
 from authentik.providers.ldap.models import LDAPProvider
 from authentik.providers.proxy.models import ProxyProvider
+from authentik.providers.rac.models import RACProvider
 from authentik.providers.radius.models import RadiusProvider
 
 
diff --git a/authentik/outposts/tasks.py b/authentik/outposts/tasks.py
index 7a80ce9be4..e09dcf769f 100644
--- a/authentik/outposts/tasks.py
+++ b/authentik/outposts/tasks.py
@@ -18,8 +18,6 @@ from kubernetes.config.kube_config import KUBE_CONFIG_DEFAULT_LOCATION
 from structlog.stdlib import get_logger
 from yaml import safe_load
 
-from authentik.enterprise.providers.rac.controllers.docker import RACDockerController
-from authentik.enterprise.providers.rac.controllers.kubernetes import RACKubernetesController
 from authentik.events.models import TaskStatus
 from authentik.events.system_tasks import SystemTask, prefill_task
 from authentik.lib.config import CONFIG
@@ -41,6 +39,8 @@ from authentik.providers.ldap.controllers.docker import LDAPDockerController
 from authentik.providers.ldap.controllers.kubernetes import LDAPKubernetesController
 from authentik.providers.proxy.controllers.docker import ProxyDockerController
 from authentik.providers.proxy.controllers.kubernetes import ProxyKubernetesController
+from authentik.providers.rac.controllers.docker import RACDockerController
+from authentik.providers.rac.controllers.kubernetes import RACKubernetesController
 from authentik.providers.radius.controllers.docker import RadiusDockerController
 from authentik.providers.radius.controllers.kubernetes import RadiusKubernetesController
 from authentik.root.celery import CELERY_APP
diff --git a/authentik/policies/geoip/api.py b/authentik/policies/geoip/api.py
index 5ea0b1e4aa..6d171c1378 100644
--- a/authentik/policies/geoip/api.py
+++ b/authentik/policies/geoip/api.py
@@ -42,6 +42,12 @@ class GeoIPPolicySerializer(CountryFieldMixin, PolicySerializer):
             "asns",
             "countries",
             "countries_obj",
+            "check_history_distance",
+            "history_max_distance_km",
+            "distance_tolerance_km",
+            "history_login_count",
+            "check_impossible_travel",
+            "impossible_tolerance_km",
         ]
 
 
diff --git a/authentik/policies/geoip/migrations/0002_geoippolicy_check_history_distance_and_more.py b/authentik/policies/geoip/migrations/0002_geoippolicy_check_history_distance_and_more.py
new file mode 100644
index 0000000000..9e44800c94
--- /dev/null
+++ b/authentik/policies/geoip/migrations/0002_geoippolicy_check_history_distance_and_more.py
@@ -0,0 +1,43 @@
+# Generated by Django 5.0.10 on 2025-01-02 20:40
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("authentik_policies_geoip", "0001_initial"),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name="geoippolicy",
+            name="check_history_distance",
+            field=models.BooleanField(default=False),
+        ),
+        migrations.AddField(
+            model_name="geoippolicy",
+            name="check_impossible_travel",
+            field=models.BooleanField(default=False),
+        ),
+        migrations.AddField(
+            model_name="geoippolicy",
+            name="distance_tolerance_km",
+            field=models.PositiveIntegerField(default=50),
+        ),
+        migrations.AddField(
+            model_name="geoippolicy",
+            name="history_login_count",
+            field=models.PositiveIntegerField(default=5),
+        ),
+        migrations.AddField(
+            model_name="geoippolicy",
+            name="history_max_distance_km",
+            field=models.PositiveBigIntegerField(default=100),
+        ),
+        migrations.AddField(
+            model_name="geoippolicy",
+            name="impossible_tolerance_km",
+            field=models.PositiveIntegerField(default=100),
+        ),
+    ]
diff --git a/authentik/policies/geoip/models.py b/authentik/policies/geoip/models.py
index bd83ad12f6..f94341afd9 100644
--- a/authentik/policies/geoip/models.py
+++ b/authentik/policies/geoip/models.py
@@ -4,15 +4,21 @@ from itertools import chain
 
 from django.contrib.postgres.fields import ArrayField
 from django.db import models
+from django.utils.timezone import now
 from django.utils.translation import gettext as _
 from django_countries.fields import CountryField
+from geopy import distance
 from rest_framework.serializers import BaseSerializer
 
+from authentik.events.context_processors.geoip import GeoIPDict
+from authentik.events.models import Event, EventAction
 from authentik.policies.exceptions import PolicyException
 from authentik.policies.geoip.exceptions import GeoIPNotFoundException
 from authentik.policies.models import Policy
 from authentik.policies.types import PolicyRequest, PolicyResult
 
+MAX_DISTANCE_HOUR_KM = 1000
+
 
 class GeoIPPolicy(Policy):
     """Ensure the user satisfies requirements of geography or network topology, based on IP
@@ -21,6 +27,15 @@ class GeoIPPolicy(Policy):
     asns = ArrayField(models.IntegerField(), blank=True, default=list)
     countries = CountryField(multiple=True, blank=True)
 
+    distance_tolerance_km = models.PositiveIntegerField(default=50)
+
+    check_history_distance = models.BooleanField(default=False)
+    history_max_distance_km = models.PositiveBigIntegerField(default=100)
+    history_login_count = models.PositiveIntegerField(default=5)
+
+    check_impossible_travel = models.BooleanField(default=False)
+    impossible_tolerance_km = models.PositiveIntegerField(default=100)
+
     @property
     def serializer(self) -> type[BaseSerializer]:
         from authentik.policies.geoip.api import GeoIPPolicySerializer
@@ -37,21 +52,27 @@ class GeoIPPolicy(Policy):
         - the client IP is advertised by an autonomous system with ASN in the `asns`
         - the client IP is geolocated in a country of `countries`
         """
-        results: list[PolicyResult] = []
+        static_results: list[PolicyResult] = []
+        dynamic_results: list[PolicyResult] = []
 
         if self.asns:
-            results.append(self.passes_asn(request))
+            static_results.append(self.passes_asn(request))
         if self.countries:
-            results.append(self.passes_country(request))
+            static_results.append(self.passes_country(request))
 
-        if not results:
+        if self.check_history_distance or self.check_impossible_travel:
+            dynamic_results.append(self.passes_distance(request))
+
+        if not static_results and not dynamic_results:
             return PolicyResult(True)
 
-        passing = any(r.passing for r in results)
-        messages = chain(*[r.messages for r in results])
+        passing = any(r.passing for r in static_results) and all(r.passing for r in dynamic_results)
+        messages = chain(
+            *[r.messages for r in static_results], *[r.messages for r in dynamic_results]
+        )
 
         result = PolicyResult(passing, *messages)
-        result.source_results = results
+        result.source_results = list(chain(static_results, dynamic_results))
 
         return result
 
@@ -73,7 +94,7 @@ class GeoIPPolicy(Policy):
 
     def passes_country(self, request: PolicyRequest) -> PolicyResult:
         # This is not a single get chain because `request.context` can contain `{ "geoip": None }`.
-        geoip_data = request.context.get("geoip")
+        geoip_data: GeoIPDict | None = request.context.get("geoip")
         country = geoip_data.get("country") if geoip_data else None
 
         if not country:
@@ -87,6 +108,42 @@ class GeoIPPolicy(Policy):
 
         return PolicyResult(True)
 
+    def passes_distance(self, request: PolicyRequest) -> PolicyResult:
+        """Check if current policy execution is out of distance range compared
+        to previous authentication requests"""
+        # Get previous login event and GeoIP data
+        previous_logins = Event.objects.filter(
+            action=EventAction.LOGIN, user__pk=request.user.pk, context__geo__isnull=False
+        ).order_by("-created")[: self.history_login_count]
+        _now = now()
+        geoip_data: GeoIPDict | None = request.context.get("geoip")
+        if not geoip_data:
+            return PolicyResult(False)
+        for previous_login in previous_logins:
+            previous_login_geoip: GeoIPDict = previous_login.context["geo"]
+
+            # Figure out distance
+            dist = distance.geodesic(
+                (previous_login_geoip["lat"], previous_login_geoip["long"]),
+                (geoip_data["lat"], geoip_data["long"]),
+            )
+            if self.check_history_distance and dist.km >= (
+                self.history_max_distance_km - self.distance_tolerance_km
+            ):
+                return PolicyResult(
+                    False, _("Distance from previous authentication is larger than threshold.")
+                )
+            # Check if distance between `previous_login` and now is more
+            # than max distance per hour times the amount of hours since the previous login
+            # (round down to the lowest closest time of hours)
+            # clamped to be at least 1 hour
+            rel_time_hours = max(int((_now - previous_login.created).total_seconds() / 3600), 1)
+            if self.check_impossible_travel and dist.km >= (
+                (MAX_DISTANCE_HOUR_KM * rel_time_hours) - self.distance_tolerance_km
+            ):
+                return PolicyResult(False, _("Distance is further than possible."))
+        return PolicyResult(True)
+
     class Meta(Policy.PolicyMeta):
         verbose_name = _("GeoIP Policy")
         verbose_name_plural = _("GeoIP Policies")
diff --git a/authentik/policies/geoip/tests.py b/authentik/policies/geoip/tests.py
index f84727d1df..a1178f35c4 100644
--- a/authentik/policies/geoip/tests.py
+++ b/authentik/policies/geoip/tests.py
@@ -1,8 +1,10 @@
 """geoip policy tests"""
 
 from django.test import TestCase
-from guardian.shortcuts import get_anonymous_user
 
+from authentik.core.tests.utils import create_test_user
+from authentik.events.models import Event, EventAction
+from authentik.events.utils import get_user
 from authentik.policies.engine import PolicyRequest, PolicyResult
 from authentik.policies.exceptions import PolicyException
 from authentik.policies.geoip.exceptions import GeoIPNotFoundException
@@ -14,8 +16,8 @@ class TestGeoIPPolicy(TestCase):
 
     def setUp(self):
         super().setUp()
-
-        self.request = PolicyRequest(get_anonymous_user())
+        self.user = create_test_user()
+        self.request = PolicyRequest(self.user)
 
         self.context_disabled_geoip = {}
         self.context_unknown_ip = {"asn": None, "geoip": None}
@@ -126,3 +128,70 @@ class TestGeoIPPolicy(TestCase):
         result: PolicyResult = policy.passes(self.request)
 
         self.assertTrue(result.passing)
+
+    def test_history(self):
+        """Test history checks"""
+        Event.objects.create(
+            action=EventAction.LOGIN,
+            user=get_user(self.user),
+            context={
+                # Random location in Canada
+                "geo": {"lat": 55.868351, "long": -104.441011},
+            },
+        )
+        # Random location in Poland
+        self.request.context["geoip"] = {"lat": 50.950613, "long": 20.363679}
+
+        policy = GeoIPPolicy.objects.create(check_history_distance=True)
+
+        result: PolicyResult = policy.passes(self.request)
+        self.assertFalse(result.passing)
+
+    def test_history_no_data(self):
+        """Test history checks (with no geoip data in context)"""
+        Event.objects.create(
+            action=EventAction.LOGIN,
+            user=get_user(self.user),
+            context={
+                # Random location in Canada
+                "geo": {"lat": 55.868351, "long": -104.441011},
+            },
+        )
+
+        policy = GeoIPPolicy.objects.create(check_history_distance=True)
+
+        result: PolicyResult = policy.passes(self.request)
+        self.assertFalse(result.passing)
+
+    def test_history_impossible_travel(self):
+        """Test history checks"""
+        Event.objects.create(
+            action=EventAction.LOGIN,
+            user=get_user(self.user),
+            context={
+                # Random location in Canada
+                "geo": {"lat": 55.868351, "long": -104.441011},
+            },
+        )
+        # Random location in Poland
+        self.request.context["geoip"] = {"lat": 50.950613, "long": 20.363679}
+
+        policy = GeoIPPolicy.objects.create(check_impossible_travel=True)
+
+        result: PolicyResult = policy.passes(self.request)
+        self.assertFalse(result.passing)
+
+    def test_history_no_geoip(self):
+        """Test history checks (previous login with no geoip data)"""
+        Event.objects.create(
+            action=EventAction.LOGIN,
+            user=get_user(self.user),
+            context={},
+        )
+        # Random location in Poland
+        self.request.context["geoip"] = {"lat": 50.950613, "long": 20.363679}
+
+        policy = GeoIPPolicy.objects.create(check_history_distance=True)
+
+        result: PolicyResult = policy.passes(self.request)
+        self.assertFalse(result.passing)
diff --git a/authentik/enterprise/providers/rac/__init__.py b/authentik/providers/rac/__init__.py
similarity index 100%
rename from authentik/enterprise/providers/rac/__init__.py
rename to authentik/providers/rac/__init__.py
diff --git a/authentik/enterprise/providers/rac/api/__init__.py b/authentik/providers/rac/api/__init__.py
similarity index 100%
rename from authentik/enterprise/providers/rac/api/__init__.py
rename to authentik/providers/rac/api/__init__.py
diff --git a/authentik/enterprise/providers/rac/api/connection_tokens.py b/authentik/providers/rac/api/connection_tokens.py
similarity index 78%
rename from authentik/enterprise/providers/rac/api/connection_tokens.py
rename to authentik/providers/rac/api/connection_tokens.py
index 18c1485d12..c6de12b1c2 100644
--- a/authentik/enterprise/providers/rac/api/connection_tokens.py
+++ b/authentik/providers/rac/api/connection_tokens.py
@@ -6,13 +6,12 @@ from rest_framework.viewsets import GenericViewSet
 from authentik.core.api.groups import GroupMemberSerializer
 from authentik.core.api.used_by import UsedByMixin
 from authentik.core.api.utils import ModelSerializer
-from authentik.enterprise.api import EnterpriseRequiredMixin
-from authentik.enterprise.providers.rac.api.endpoints import EndpointSerializer
-from authentik.enterprise.providers.rac.api.providers import RACProviderSerializer
-from authentik.enterprise.providers.rac.models import ConnectionToken
+from authentik.providers.rac.api.endpoints import EndpointSerializer
+from authentik.providers.rac.api.providers import RACProviderSerializer
+from authentik.providers.rac.models import ConnectionToken
 
 
-class ConnectionTokenSerializer(EnterpriseRequiredMixin, ModelSerializer):
+class ConnectionTokenSerializer(ModelSerializer):
     """ConnectionToken Serializer"""
 
     provider_obj = RACProviderSerializer(source="provider", read_only=True)
diff --git a/authentik/enterprise/providers/rac/api/endpoints.py b/authentik/providers/rac/api/endpoints.py
similarity index 94%
rename from authentik/enterprise/providers/rac/api/endpoints.py
rename to authentik/providers/rac/api/endpoints.py
index 6cb4aea8fa..4f63976158 100644
--- a/authentik/enterprise/providers/rac/api/endpoints.py
+++ b/authentik/providers/rac/api/endpoints.py
@@ -14,10 +14,9 @@ from structlog.stdlib import get_logger
 from authentik.core.api.used_by import UsedByMixin
 from authentik.core.api.utils import ModelSerializer
 from authentik.core.models import Provider
-from authentik.enterprise.api import EnterpriseRequiredMixin
-from authentik.enterprise.providers.rac.api.providers import RACProviderSerializer
-from authentik.enterprise.providers.rac.models import Endpoint
 from authentik.policies.engine import PolicyEngine
+from authentik.providers.rac.api.providers import RACProviderSerializer
+from authentik.providers.rac.models import Endpoint
 from authentik.rbac.filters import ObjectFilter
 
 LOGGER = get_logger()
@@ -28,7 +27,7 @@ def user_endpoint_cache_key(user_pk: str) -> str:
     return f"goauthentik.io/providers/rac/endpoint_access/{user_pk}"
 
 
-class EndpointSerializer(EnterpriseRequiredMixin, ModelSerializer):
+class EndpointSerializer(ModelSerializer):
     """Endpoint Serializer"""
 
     provider_obj = RACProviderSerializer(source="provider", read_only=True)
diff --git a/authentik/enterprise/providers/rac/api/property_mappings.py b/authentik/providers/rac/api/property_mappings.py
similarity index 95%
rename from authentik/enterprise/providers/rac/api/property_mappings.py
rename to authentik/providers/rac/api/property_mappings.py
index d41a4eb16c..4a5beafdb3 100644
--- a/authentik/enterprise/providers/rac/api/property_mappings.py
+++ b/authentik/providers/rac/api/property_mappings.py
@@ -10,7 +10,7 @@ from rest_framework.viewsets import ModelViewSet
 from authentik.core.api.property_mappings import PropertyMappingSerializer
 from authentik.core.api.used_by import UsedByMixin
 from authentik.core.api.utils import JSONDictField
-from authentik.enterprise.providers.rac.models import RACPropertyMapping
+from authentik.providers.rac.models import RACPropertyMapping
 
 
 class RACPropertyMappingSerializer(PropertyMappingSerializer):
diff --git a/authentik/enterprise/providers/rac/api/providers.py b/authentik/providers/rac/api/providers.py
similarity index 87%
rename from authentik/enterprise/providers/rac/api/providers.py
rename to authentik/providers/rac/api/providers.py
index 9d0439ee7e..35ae2b2410 100644
--- a/authentik/enterprise/providers/rac/api/providers.py
+++ b/authentik/providers/rac/api/providers.py
@@ -5,11 +5,10 @@ from rest_framework.viewsets import ModelViewSet
 
 from authentik.core.api.providers import ProviderSerializer
 from authentik.core.api.used_by import UsedByMixin
-from authentik.enterprise.api import EnterpriseRequiredMixin
-from authentik.enterprise.providers.rac.models import RACProvider
+from authentik.providers.rac.models import RACProvider
 
 
-class RACProviderSerializer(EnterpriseRequiredMixin, ProviderSerializer):
+class RACProviderSerializer(ProviderSerializer):
     """RACProvider Serializer"""
 
     outpost_set = ListField(child=CharField(), read_only=True, source="outpost_set.all")
diff --git a/authentik/providers/rac/apps.py b/authentik/providers/rac/apps.py
new file mode 100644
index 0000000000..7b11c1e540
--- /dev/null
+++ b/authentik/providers/rac/apps.py
@@ -0,0 +1,14 @@
+"""RAC app config"""
+
+from django.apps import AppConfig
+
+
+class AuthentikProviderRAC(AppConfig):
+    """authentik rac app config"""
+
+    name = "authentik.providers.rac"
+    label = "authentik_providers_rac"
+    verbose_name = "authentik Providers.RAC"
+    default = True
+    mountpoint = ""
+    ws_mountpoint = "authentik.providers.rac.urls"
diff --git a/authentik/enterprise/providers/rac/consumer_client.py b/authentik/providers/rac/consumer_client.py
similarity index 96%
rename from authentik/enterprise/providers/rac/consumer_client.py
rename to authentik/providers/rac/consumer_client.py
index b6331ca563..b55059ec20 100644
--- a/authentik/enterprise/providers/rac/consumer_client.py
+++ b/authentik/providers/rac/consumer_client.py
@@ -7,22 +7,22 @@ from channels.generic.websocket import AsyncWebsocketConsumer
 from django.http.request import QueryDict
 from structlog.stdlib import BoundLogger, get_logger
 
-from authentik.enterprise.providers.rac.models import ConnectionToken, RACProvider
 from authentik.outposts.consumer import OUTPOST_GROUP_INSTANCE
 from authentik.outposts.models import Outpost, OutpostState, OutpostType
+from authentik.providers.rac.models import ConnectionToken, RACProvider
 
 # Global broadcast group, which messages are sent to when the outpost connects back
 # to authentik for a specific connection
 # The `RACClientConsumer` consumer adds itself to this group on connection,
 # and removes itself once it has been assigned a specific outpost channel
-RAC_CLIENT_GROUP = "group_enterprise_rac_client"
+RAC_CLIENT_GROUP = "group_rac_client"
 # A group for all connections in a given authentik session ID
 # A disconnect message is sent to this group when the session expires/is deleted
-RAC_CLIENT_GROUP_SESSION = "group_enterprise_rac_client_%(session)s"
+RAC_CLIENT_GROUP_SESSION = "group_rac_client_%(session)s"
 # A group for all connections with a specific token, which in almost all cases
 # is just one connection, however this is used to disconnect the connection
 # when the token is deleted
-RAC_CLIENT_GROUP_TOKEN = "group_enterprise_rac_token_%(token)s"  # nosec
+RAC_CLIENT_GROUP_TOKEN = "group_rac_token_%(token)s"  # nosec
 
 # Step 1: Client connects to this websocket endpoint
 # Step 2: We prepare all the connection args for Guac
diff --git a/authentik/enterprise/providers/rac/consumer_outpost.py b/authentik/providers/rac/consumer_outpost.py
similarity index 95%
rename from authentik/enterprise/providers/rac/consumer_outpost.py
rename to authentik/providers/rac/consumer_outpost.py
index a1119d85a8..a6f8aea07f 100644
--- a/authentik/enterprise/providers/rac/consumer_outpost.py
+++ b/authentik/providers/rac/consumer_outpost.py
@@ -3,7 +3,7 @@
 from channels.exceptions import ChannelFull
 from channels.generic.websocket import AsyncWebsocketConsumer
 
-from authentik.enterprise.providers.rac.consumer_client import RAC_CLIENT_GROUP
+from authentik.providers.rac.consumer_client import RAC_CLIENT_GROUP
 
 
 class RACOutpostConsumer(AsyncWebsocketConsumer):
diff --git a/authentik/enterprise/providers/rac/controllers/__init__.py b/authentik/providers/rac/controllers/__init__.py
similarity index 100%
rename from authentik/enterprise/providers/rac/controllers/__init__.py
rename to authentik/providers/rac/controllers/__init__.py
diff --git a/authentik/enterprise/providers/rac/controllers/docker.py b/authentik/providers/rac/controllers/docker.py
similarity index 100%
rename from authentik/enterprise/providers/rac/controllers/docker.py
rename to authentik/providers/rac/controllers/docker.py
diff --git a/authentik/enterprise/providers/rac/controllers/kubernetes.py b/authentik/providers/rac/controllers/kubernetes.py
similarity index 100%
rename from authentik/enterprise/providers/rac/controllers/kubernetes.py
rename to authentik/providers/rac/controllers/kubernetes.py
diff --git a/authentik/enterprise/providers/rac/migrations/0001_initial.py b/authentik/providers/rac/migrations/0001_initial.py
similarity index 100%
rename from authentik/enterprise/providers/rac/migrations/0001_initial.py
rename to authentik/providers/rac/migrations/0001_initial.py
diff --git a/authentik/enterprise/providers/rac/migrations/0001_squashed_0003_alter_connectiontoken_options_and_more.py b/authentik/providers/rac/migrations/0001_squashed_0003_alter_connectiontoken_options_and_more.py
similarity index 100%
rename from authentik/enterprise/providers/rac/migrations/0001_squashed_0003_alter_connectiontoken_options_and_more.py
rename to authentik/providers/rac/migrations/0001_squashed_0003_alter_connectiontoken_options_and_more.py
diff --git a/authentik/enterprise/providers/rac/migrations/0002_endpoint_maximum_connections.py b/authentik/providers/rac/migrations/0002_endpoint_maximum_connections.py
similarity index 100%
rename from authentik/enterprise/providers/rac/migrations/0002_endpoint_maximum_connections.py
rename to authentik/providers/rac/migrations/0002_endpoint_maximum_connections.py
diff --git a/authentik/enterprise/providers/rac/migrations/0003_alter_connectiontoken_options_and_more.py b/authentik/providers/rac/migrations/0003_alter_connectiontoken_options_and_more.py
similarity index 100%
rename from authentik/enterprise/providers/rac/migrations/0003_alter_connectiontoken_options_and_more.py
rename to authentik/providers/rac/migrations/0003_alter_connectiontoken_options_and_more.py
diff --git a/authentik/enterprise/providers/rac/migrations/0004_alter_connectiontoken_expires.py b/authentik/providers/rac/migrations/0004_alter_connectiontoken_expires.py
similarity index 100%
rename from authentik/enterprise/providers/rac/migrations/0004_alter_connectiontoken_expires.py
rename to authentik/providers/rac/migrations/0004_alter_connectiontoken_expires.py
diff --git a/authentik/enterprise/providers/rac/migrations/0005_alter_racpropertymapping_options.py b/authentik/providers/rac/migrations/0005_alter_racpropertymapping_options.py
similarity index 100%
rename from authentik/enterprise/providers/rac/migrations/0005_alter_racpropertymapping_options.py
rename to authentik/providers/rac/migrations/0005_alter_racpropertymapping_options.py
diff --git a/authentik/enterprise/providers/rac/migrations/0006_connectiontoken_authentik_p_expires_91f148_idx_and_more.py b/authentik/providers/rac/migrations/0006_connectiontoken_authentik_p_expires_91f148_idx_and_more.py
similarity index 100%
rename from authentik/enterprise/providers/rac/migrations/0006_connectiontoken_authentik_p_expires_91f148_idx_and_more.py
rename to authentik/providers/rac/migrations/0006_connectiontoken_authentik_p_expires_91f148_idx_and_more.py
diff --git a/authentik/enterprise/providers/rac/migrations/__init__.py b/authentik/providers/rac/migrations/__init__.py
similarity index 100%
rename from authentik/enterprise/providers/rac/migrations/__init__.py
rename to authentik/providers/rac/migrations/__init__.py
diff --git a/authentik/enterprise/providers/rac/models.py b/authentik/providers/rac/models.py
similarity index 96%
rename from authentik/enterprise/providers/rac/models.py
rename to authentik/providers/rac/models.py
index 39b59553ce..26d7b60734 100644
--- a/authentik/enterprise/providers/rac/models.py
+++ b/authentik/providers/rac/models.py
@@ -74,7 +74,7 @@ class RACProvider(Provider):
 
     @property
     def serializer(self) -> type[Serializer]:
-        from authentik.enterprise.providers.rac.api.providers import RACProviderSerializer
+        from authentik.providers.rac.api.providers import RACProviderSerializer
 
         return RACProviderSerializer
 
@@ -100,7 +100,7 @@ class Endpoint(SerializerModel, PolicyBindingModel):
 
     @property
     def serializer(self) -> type[Serializer]:
-        from authentik.enterprise.providers.rac.api.endpoints import EndpointSerializer
+        from authentik.providers.rac.api.endpoints import EndpointSerializer
 
         return EndpointSerializer
 
@@ -129,7 +129,7 @@ class RACPropertyMapping(PropertyMapping):
 
     @property
     def serializer(self) -> type[Serializer]:
-        from authentik.enterprise.providers.rac.api.property_mappings import (
+        from authentik.providers.rac.api.property_mappings import (
             RACPropertyMappingSerializer,
         )
 
diff --git a/authentik/enterprise/providers/rac/signals.py b/authentik/providers/rac/signals.py
similarity index 88%
rename from authentik/enterprise/providers/rac/signals.py
rename to authentik/providers/rac/signals.py
index 2cf7b00bf9..f36cb19898 100644
--- a/authentik/enterprise/providers/rac/signals.py
+++ b/authentik/providers/rac/signals.py
@@ -10,12 +10,12 @@ from django.dispatch import receiver
 from django.http import HttpRequest
 
 from authentik.core.models import User
-from authentik.enterprise.providers.rac.api.endpoints import user_endpoint_cache_key
-from authentik.enterprise.providers.rac.consumer_client import (
+from authentik.providers.rac.api.endpoints import user_endpoint_cache_key
+from authentik.providers.rac.consumer_client import (
     RAC_CLIENT_GROUP_SESSION,
     RAC_CLIENT_GROUP_TOKEN,
 )
-from authentik.enterprise.providers.rac.models import ConnectionToken, Endpoint
+from authentik.providers.rac.models import ConnectionToken, Endpoint
 
 
 @receiver(user_logged_out)
diff --git a/authentik/enterprise/providers/rac/templates/if/rac.html b/authentik/providers/rac/templates/if/rac.html
similarity index 85%
rename from authentik/enterprise/providers/rac/templates/if/rac.html
rename to authentik/providers/rac/templates/if/rac.html
index 156d96085e..4f26fba880 100644
--- a/authentik/enterprise/providers/rac/templates/if/rac.html
+++ b/authentik/providers/rac/templates/if/rac.html
@@ -3,7 +3,7 @@
 {% load authentik_core %}
 
 {% block head %}
-
+
 
 
 
diff --git a/authentik/enterprise/providers/rac/tests/__init__.py b/authentik/providers/rac/tests/__init__.py
similarity index 100%
rename from authentik/enterprise/providers/rac/tests/__init__.py
rename to authentik/providers/rac/tests/__init__.py
diff --git a/authentik/enterprise/providers/rac/tests/test_api.py b/authentik/providers/rac/tests/test_api.py
similarity index 53%
rename from authentik/enterprise/providers/rac/tests/test_api.py
rename to authentik/providers/rac/tests/test_api.py
index da71133e80..c66bb11853 100644
--- a/authentik/enterprise/providers/rac/tests/test_api.py
+++ b/authentik/providers/rac/tests/test_api.py
@@ -1,16 +1,9 @@
 """Test RAC Provider"""
 
-from datetime import timedelta
-from time import mktime
-from unittest.mock import MagicMock, patch
-
 from django.urls import reverse
-from django.utils.timezone import now
 from rest_framework.test import APITestCase
 
 from authentik.core.tests.utils import create_test_admin_user, create_test_flow
-from authentik.enterprise.license import LicenseKey
-from authentik.enterprise.models import License
 from authentik.lib.generators import generate_id
 
 
@@ -20,21 +13,8 @@ class TestAPI(APITestCase):
     def setUp(self) -> None:
         self.user = create_test_admin_user()
 
-    @patch(
-        "authentik.enterprise.license.LicenseKey.validate",
-        MagicMock(
-            return_value=LicenseKey(
-                aud="",
-                exp=int(mktime((now() + timedelta(days=3000)).timetuple())),
-                name=generate_id(),
-                internal_users=100,
-                external_users=100,
-            )
-        ),
-    )
     def test_create(self):
         """Test creation of RAC Provider"""
-        License.objects.create(key=generate_id())
         self.client.force_login(self.user)
         response = self.client.post(
             reverse("authentik_api:racprovider-list"),
diff --git a/authentik/enterprise/providers/rac/tests/test_endpoints_api.py b/authentik/providers/rac/tests/test_endpoints_api.py
similarity index 98%
rename from authentik/enterprise/providers/rac/tests/test_endpoints_api.py
rename to authentik/providers/rac/tests/test_endpoints_api.py
index 1ad9b70daf..9a2469bbba 100644
--- a/authentik/enterprise/providers/rac/tests/test_endpoints_api.py
+++ b/authentik/providers/rac/tests/test_endpoints_api.py
@@ -5,10 +5,10 @@ from rest_framework.test import APITestCase
 
 from authentik.core.models import Application
 from authentik.core.tests.utils import create_test_admin_user
-from authentik.enterprise.providers.rac.models import Endpoint, Protocols, RACProvider
 from authentik.lib.generators import generate_id
 from authentik.policies.dummy.models import DummyPolicy
 from authentik.policies.models import PolicyBinding
+from authentik.providers.rac.models import Endpoint, Protocols, RACProvider
 
 
 class TestEndpointsAPI(APITestCase):
diff --git a/authentik/enterprise/providers/rac/tests/test_models.py b/authentik/providers/rac/tests/test_models.py
similarity index 98%
rename from authentik/enterprise/providers/rac/tests/test_models.py
rename to authentik/providers/rac/tests/test_models.py
index b6e7258d83..4a9fad4e67 100644
--- a/authentik/enterprise/providers/rac/tests/test_models.py
+++ b/authentik/providers/rac/tests/test_models.py
@@ -4,14 +4,14 @@ from django.test import TransactionTestCase
 
 from authentik.core.models import Application, AuthenticatedSession
 from authentik.core.tests.utils import create_test_admin_user
-from authentik.enterprise.providers.rac.models import (
+from authentik.lib.generators import generate_id
+from authentik.providers.rac.models import (
     ConnectionToken,
     Endpoint,
     Protocols,
     RACPropertyMapping,
     RACProvider,
 )
-from authentik.lib.generators import generate_id
 
 
 class TestModels(TransactionTestCase):
diff --git a/authentik/enterprise/providers/rac/tests/test_views.py b/authentik/providers/rac/tests/test_views.py
similarity index 67%
rename from authentik/enterprise/providers/rac/tests/test_views.py
rename to authentik/providers/rac/tests/test_views.py
index a63f27fba0..80778d2ebc 100644
--- a/authentik/enterprise/providers/rac/tests/test_views.py
+++ b/authentik/providers/rac/tests/test_views.py
@@ -1,23 +1,17 @@
 """RAC Views tests"""
 
-from datetime import timedelta
 from json import loads
-from time import mktime
-from unittest.mock import MagicMock, patch
 
 from django.urls import reverse
-from django.utils.timezone import now
 from rest_framework.test import APITestCase
 
 from authentik.core.models import Application
 from authentik.core.tests.utils import create_test_admin_user, create_test_flow
-from authentik.enterprise.license import LicenseKey
-from authentik.enterprise.models import License
-from authentik.enterprise.providers.rac.models import Endpoint, Protocols, RACProvider
 from authentik.lib.generators import generate_id
 from authentik.policies.denied import AccessDeniedResponse
 from authentik.policies.dummy.models import DummyPolicy
 from authentik.policies.models import PolicyBinding
+from authentik.providers.rac.models import Endpoint, Protocols, RACProvider
 
 
 class TestRACViews(APITestCase):
@@ -39,21 +33,8 @@ class TestRACViews(APITestCase):
             provider=self.provider,
         )
 
-    @patch(
-        "authentik.enterprise.license.LicenseKey.validate",
-        MagicMock(
-            return_value=LicenseKey(
-                aud="",
-                exp=int(mktime((now() + timedelta(days=3000)).timetuple())),
-                name=generate_id(),
-                internal_users=100,
-                external_users=100,
-            )
-        ),
-    )
     def test_no_policy(self):
         """Test request"""
-        License.objects.create(key=generate_id())
         self.client.force_login(self.user)
         response = self.client.get(
             reverse(
@@ -70,18 +51,6 @@ class TestRACViews(APITestCase):
         final_response = self.client.get(next_url)
         self.assertEqual(final_response.status_code, 200)
 
-    @patch(
-        "authentik.enterprise.license.LicenseKey.validate",
-        MagicMock(
-            return_value=LicenseKey(
-                aud="",
-                exp=int(mktime((now() + timedelta(days=3000)).timetuple())),
-                name=generate_id(),
-                internal_users=100,
-                external_users=100,
-            )
-        ),
-    )
     def test_app_deny(self):
         """Test request (deny on app level)"""
         PolicyBinding.objects.create(
@@ -89,7 +58,6 @@ class TestRACViews(APITestCase):
             policy=DummyPolicy.objects.create(name="deny", result=False, wait_min=1, wait_max=2),
             order=0,
         )
-        License.objects.create(key=generate_id())
         self.client.force_login(self.user)
         response = self.client.get(
             reverse(
@@ -99,18 +67,6 @@ class TestRACViews(APITestCase):
         )
         self.assertIsInstance(response, AccessDeniedResponse)
 
-    @patch(
-        "authentik.enterprise.license.LicenseKey.validate",
-        MagicMock(
-            return_value=LicenseKey(
-                aud="",
-                exp=int(mktime((now() + timedelta(days=3000)).timetuple())),
-                name=generate_id(),
-                internal_users=100,
-                external_users=100,
-            )
-        ),
-    )
     def test_endpoint_deny(self):
         """Test request (deny on endpoint level)"""
         PolicyBinding.objects.create(
@@ -118,7 +74,6 @@ class TestRACViews(APITestCase):
             policy=DummyPolicy.objects.create(name="deny", result=False, wait_min=1, wait_max=2),
             order=0,
         )
-        License.objects.create(key=generate_id())
         self.client.force_login(self.user)
         response = self.client.get(
             reverse(
diff --git a/authentik/enterprise/providers/rac/urls.py b/authentik/providers/rac/urls.py
similarity index 66%
rename from authentik/enterprise/providers/rac/urls.py
rename to authentik/providers/rac/urls.py
index 88b3e2e828..07e6f661cc 100644
--- a/authentik/enterprise/providers/rac/urls.py
+++ b/authentik/providers/rac/urls.py
@@ -4,14 +4,14 @@ from channels.auth import AuthMiddleware
 from channels.sessions import CookieMiddleware
 from django.urls import path
 
-from authentik.enterprise.providers.rac.api.connection_tokens import ConnectionTokenViewSet
-from authentik.enterprise.providers.rac.api.endpoints import EndpointViewSet
-from authentik.enterprise.providers.rac.api.property_mappings import RACPropertyMappingViewSet
-from authentik.enterprise.providers.rac.api.providers import RACProviderViewSet
-from authentik.enterprise.providers.rac.consumer_client import RACClientConsumer
-from authentik.enterprise.providers.rac.consumer_outpost import RACOutpostConsumer
-from authentik.enterprise.providers.rac.views import RACInterface, RACStartView
 from authentik.outposts.channels import TokenOutpostMiddleware
+from authentik.providers.rac.api.connection_tokens import ConnectionTokenViewSet
+from authentik.providers.rac.api.endpoints import EndpointViewSet
+from authentik.providers.rac.api.property_mappings import RACPropertyMappingViewSet
+from authentik.providers.rac.api.providers import RACProviderViewSet
+from authentik.providers.rac.consumer_client import RACClientConsumer
+from authentik.providers.rac.consumer_outpost import RACOutpostConsumer
+from authentik.providers.rac.views import RACInterface, RACStartView
 from authentik.root.asgi_middleware import SessionMiddleware
 from authentik.root.middleware import ChannelsLoggingMiddleware
 
diff --git a/authentik/enterprise/providers/rac/views.py b/authentik/providers/rac/views.py
similarity index 96%
rename from authentik/enterprise/providers/rac/views.py
rename to authentik/providers/rac/views.py
index 36785766a3..bac8e21b90 100644
--- a/authentik/enterprise/providers/rac/views.py
+++ b/authentik/providers/rac/views.py
@@ -10,8 +10,6 @@ from django.utils.translation import gettext as _
 
 from authentik.core.models import Application, AuthenticatedSession
 from authentik.core.views.interface import InterfaceView
-from authentik.enterprise.policy import EnterprisePolicyAccessView
-from authentik.enterprise.providers.rac.models import ConnectionToken, Endpoint, RACProvider
 from authentik.events.models import Event, EventAction
 from authentik.flows.challenge import RedirectChallenge
 from authentik.flows.exceptions import FlowNonApplicableException
@@ -20,9 +18,11 @@ from authentik.flows.planner import PLAN_CONTEXT_APPLICATION, FlowPlanner
 from authentik.flows.stage import RedirectStage
 from authentik.lib.utils.time import timedelta_from_string
 from authentik.policies.engine import PolicyEngine
+from authentik.policies.views import PolicyAccessView
+from authentik.providers.rac.models import ConnectionToken, Endpoint, RACProvider
 
 
-class RACStartView(EnterprisePolicyAccessView):
+class RACStartView(PolicyAccessView):
     """Start a RAC connection by checking access and creating a connection token"""
 
     endpoint: Endpoint
diff --git a/authentik/root/settings.py b/authentik/root/settings.py
index 6eddf6c98d..a9568c64ba 100644
--- a/authentik/root/settings.py
+++ b/authentik/root/settings.py
@@ -87,6 +87,7 @@ TENANT_APPS = [
     "authentik.providers.ldap",
     "authentik.providers.oauth2",
     "authentik.providers.proxy",
+    "authentik.providers.rac",
     "authentik.providers.radius",
     "authentik.providers.saml",
     "authentik.providers.scim",
diff --git a/blueprints/schema.json b/blueprints/schema.json
index d43da273e2..bca4395e32 100644
--- a/blueprints/schema.json
+++ b/blueprints/schema.json
@@ -801,6 +801,126 @@
                             }
                         }
                     },
+                    {
+                        "type": "object",
+                        "required": [
+                            "model",
+                            "identifiers"
+                        ],
+                        "properties": {
+                            "model": {
+                                "const": "authentik_providers_rac.racprovider"
+                            },
+                            "id": {
+                                "type": "string"
+                            },
+                            "state": {
+                                "type": "string",
+                                "enum": [
+                                    "absent",
+                                    "present",
+                                    "created",
+                                    "must_created"
+                                ],
+                                "default": "present"
+                            },
+                            "conditions": {
+                                "type": "array",
+                                "items": {
+                                    "type": "boolean"
+                                }
+                            },
+                            "permissions": {
+                                "$ref": "#/$defs/model_authentik_providers_rac.racprovider_permissions"
+                            },
+                            "attrs": {
+                                "$ref": "#/$defs/model_authentik_providers_rac.racprovider"
+                            },
+                            "identifiers": {
+                                "$ref": "#/$defs/model_authentik_providers_rac.racprovider"
+                            }
+                        }
+                    },
+                    {
+                        "type": "object",
+                        "required": [
+                            "model",
+                            "identifiers"
+                        ],
+                        "properties": {
+                            "model": {
+                                "const": "authentik_providers_rac.endpoint"
+                            },
+                            "id": {
+                                "type": "string"
+                            },
+                            "state": {
+                                "type": "string",
+                                "enum": [
+                                    "absent",
+                                    "present",
+                                    "created",
+                                    "must_created"
+                                ],
+                                "default": "present"
+                            },
+                            "conditions": {
+                                "type": "array",
+                                "items": {
+                                    "type": "boolean"
+                                }
+                            },
+                            "permissions": {
+                                "$ref": "#/$defs/model_authentik_providers_rac.endpoint_permissions"
+                            },
+                            "attrs": {
+                                "$ref": "#/$defs/model_authentik_providers_rac.endpoint"
+                            },
+                            "identifiers": {
+                                "$ref": "#/$defs/model_authentik_providers_rac.endpoint"
+                            }
+                        }
+                    },
+                    {
+                        "type": "object",
+                        "required": [
+                            "model",
+                            "identifiers"
+                        ],
+                        "properties": {
+                            "model": {
+                                "const": "authentik_providers_rac.racpropertymapping"
+                            },
+                            "id": {
+                                "type": "string"
+                            },
+                            "state": {
+                                "type": "string",
+                                "enum": [
+                                    "absent",
+                                    "present",
+                                    "created",
+                                    "must_created"
+                                ],
+                                "default": "present"
+                            },
+                            "conditions": {
+                                "type": "array",
+                                "items": {
+                                    "type": "boolean"
+                                }
+                            },
+                            "permissions": {
+                                "$ref": "#/$defs/model_authentik_providers_rac.racpropertymapping_permissions"
+                            },
+                            "attrs": {
+                                "$ref": "#/$defs/model_authentik_providers_rac.racpropertymapping"
+                            },
+                            "identifiers": {
+                                "$ref": "#/$defs/model_authentik_providers_rac.racpropertymapping"
+                            }
+                        }
+                    },
                     {
                         "type": "object",
                         "required": [
@@ -3561,126 +3681,6 @@
                             }
                         }
                     },
-                    {
-                        "type": "object",
-                        "required": [
-                            "model",
-                            "identifiers"
-                        ],
-                        "properties": {
-                            "model": {
-                                "const": "authentik_providers_rac.racprovider"
-                            },
-                            "id": {
-                                "type": "string"
-                            },
-                            "state": {
-                                "type": "string",
-                                "enum": [
-                                    "absent",
-                                    "present",
-                                    "created",
-                                    "must_created"
-                                ],
-                                "default": "present"
-                            },
-                            "conditions": {
-                                "type": "array",
-                                "items": {
-                                    "type": "boolean"
-                                }
-                            },
-                            "permissions": {
-                                "$ref": "#/$defs/model_authentik_providers_rac.racprovider_permissions"
-                            },
-                            "attrs": {
-                                "$ref": "#/$defs/model_authentik_providers_rac.racprovider"
-                            },
-                            "identifiers": {
-                                "$ref": "#/$defs/model_authentik_providers_rac.racprovider"
-                            }
-                        }
-                    },
-                    {
-                        "type": "object",
-                        "required": [
-                            "model",
-                            "identifiers"
-                        ],
-                        "properties": {
-                            "model": {
-                                "const": "authentik_providers_rac.endpoint"
-                            },
-                            "id": {
-                                "type": "string"
-                            },
-                            "state": {
-                                "type": "string",
-                                "enum": [
-                                    "absent",
-                                    "present",
-                                    "created",
-                                    "must_created"
-                                ],
-                                "default": "present"
-                            },
-                            "conditions": {
-                                "type": "array",
-                                "items": {
-                                    "type": "boolean"
-                                }
-                            },
-                            "permissions": {
-                                "$ref": "#/$defs/model_authentik_providers_rac.endpoint_permissions"
-                            },
-                            "attrs": {
-                                "$ref": "#/$defs/model_authentik_providers_rac.endpoint"
-                            },
-                            "identifiers": {
-                                "$ref": "#/$defs/model_authentik_providers_rac.endpoint"
-                            }
-                        }
-                    },
-                    {
-                        "type": "object",
-                        "required": [
-                            "model",
-                            "identifiers"
-                        ],
-                        "properties": {
-                            "model": {
-                                "const": "authentik_providers_rac.racpropertymapping"
-                            },
-                            "id": {
-                                "type": "string"
-                            },
-                            "state": {
-                                "type": "string",
-                                "enum": [
-                                    "absent",
-                                    "present",
-                                    "created",
-                                    "must_created"
-                                ],
-                                "default": "present"
-                            },
-                            "conditions": {
-                                "type": "array",
-                                "items": {
-                                    "type": "boolean"
-                                }
-                            },
-                            "permissions": {
-                                "$ref": "#/$defs/model_authentik_providers_rac.racpropertymapping_permissions"
-                            },
-                            "attrs": {
-                                "$ref": "#/$defs/model_authentik_providers_rac.racpropertymapping"
-                            },
-                            "identifiers": {
-                                "$ref": "#/$defs/model_authentik_providers_rac.racpropertymapping"
-                            }
-                        }
-                    },
                     {
                         "type": "object",
                         "required": [
@@ -4663,6 +4663,7 @@
                         "authentik.providers.ldap",
                         "authentik.providers.oauth2",
                         "authentik.providers.proxy",
+                        "authentik.providers.rac",
                         "authentik.providers.radius",
                         "authentik.providers.saml",
                         "authentik.providers.scim",
@@ -4703,7 +4704,6 @@
                         "authentik.enterprise.audit",
                         "authentik.enterprise.providers.google_workspace",
                         "authentik.enterprise.providers.microsoft_entra",
-                        "authentik.enterprise.providers.rac",
                         "authentik.enterprise.providers.ssf",
                         "authentik.enterprise.stages.authenticator_endpoint_gdtc",
                         "authentik.enterprise.stages.source",
@@ -4738,6 +4738,9 @@
                         "authentik_providers_oauth2.scopemapping",
                         "authentik_providers_oauth2.oauth2provider",
                         "authentik_providers_proxy.proxyprovider",
+                        "authentik_providers_rac.racprovider",
+                        "authentik_providers_rac.endpoint",
+                        "authentik_providers_rac.racpropertymapping",
                         "authentik_providers_radius.radiusprovider",
                         "authentik_providers_radius.radiusproviderpropertymapping",
                         "authentik_providers_saml.samlprovider",
@@ -4807,9 +4810,6 @@
                         "authentik_providers_google_workspace.googleworkspaceprovidermapping",
                         "authentik_providers_microsoft_entra.microsoftentraprovider",
                         "authentik_providers_microsoft_entra.microsoftentraprovidermapping",
-                        "authentik_providers_rac.racprovider",
-                        "authentik_providers_rac.endpoint",
-                        "authentik_providers_rac.racpropertymapping",
                         "authentik_providers_ssf.ssfprovider",
                         "authentik_stages_authenticator_endpoint_gdtc.authenticatorendpointgdtcstage",
                         "authentik_stages_source.sourcestage",
@@ -5232,6 +5232,38 @@
                     },
                     "maxItems": 249,
                     "title": "Countries"
+                },
+                "check_history_distance": {
+                    "type": "boolean",
+                    "title": "Check history distance"
+                },
+                "history_max_distance_km": {
+                    "type": "integer",
+                    "minimum": 0,
+                    "maximum": 9223372036854775807,
+                    "title": "History max distance km"
+                },
+                "distance_tolerance_km": {
+                    "type": "integer",
+                    "minimum": 0,
+                    "maximum": 2147483647,
+                    "title": "Distance tolerance km"
+                },
+                "history_login_count": {
+                    "type": "integer",
+                    "minimum": 0,
+                    "maximum": 2147483647,
+                    "title": "History login count"
+                },
+                "check_impossible_travel": {
+                    "type": "boolean",
+                    "title": "Check impossible travel"
+                },
+                "impossible_tolerance_km": {
+                    "type": "integer",
+                    "minimum": 0,
+                    "maximum": 2147483647,
+                    "title": "Impossible tolerance km"
                 }
             },
             "required": []
@@ -6014,6 +6046,216 @@
                 }
             }
         },
+        "model_authentik_providers_rac.racprovider": {
+            "type": "object",
+            "properties": {
+                "name": {
+                    "type": "string",
+                    "minLength": 1,
+                    "title": "Name"
+                },
+                "authentication_flow": {
+                    "type": "string",
+                    "format": "uuid",
+                    "title": "Authentication flow",
+                    "description": "Flow used for authentication when the associated application is accessed by an un-authenticated user."
+                },
+                "authorization_flow": {
+                    "type": "string",
+                    "format": "uuid",
+                    "title": "Authorization flow",
+                    "description": "Flow used when authorizing this provider."
+                },
+                "property_mappings": {
+                    "type": "array",
+                    "items": {
+                        "type": "string",
+                        "format": "uuid"
+                    },
+                    "title": "Property mappings"
+                },
+                "settings": {
+                    "type": "object",
+                    "additionalProperties": true,
+                    "title": "Settings"
+                },
+                "connection_expiry": {
+                    "type": "string",
+                    "minLength": 1,
+                    "title": "Connection expiry",
+                    "description": "Determines how long a session lasts. Default of 0 means that the sessions lasts until the browser is closed. (Format: hours=-1;minutes=-2;seconds=-3)"
+                },
+                "delete_token_on_disconnect": {
+                    "type": "boolean",
+                    "title": "Delete token on disconnect",
+                    "description": "When set to true, connection tokens will be deleted upon disconnect."
+                }
+            },
+            "required": []
+        },
+        "model_authentik_providers_rac.racprovider_permissions": {
+            "type": "array",
+            "items": {
+                "type": "object",
+                "required": [
+                    "permission"
+                ],
+                "properties": {
+                    "permission": {
+                        "type": "string",
+                        "enum": [
+                            "add_racprovider",
+                            "change_racprovider",
+                            "delete_racprovider",
+                            "view_racprovider"
+                        ]
+                    },
+                    "user": {
+                        "type": "integer"
+                    },
+                    "role": {
+                        "type": "string"
+                    }
+                }
+            }
+        },
+        "model_authentik_providers_rac.endpoint": {
+            "type": "object",
+            "properties": {
+                "name": {
+                    "type": "string",
+                    "minLength": 1,
+                    "title": "Name"
+                },
+                "provider": {
+                    "type": "integer",
+                    "title": "Provider"
+                },
+                "protocol": {
+                    "type": "string",
+                    "enum": [
+                        "rdp",
+                        "vnc",
+                        "ssh"
+                    ],
+                    "title": "Protocol"
+                },
+                "host": {
+                    "type": "string",
+                    "minLength": 1,
+                    "title": "Host"
+                },
+                "settings": {
+                    "type": "object",
+                    "additionalProperties": true,
+                    "title": "Settings"
+                },
+                "property_mappings": {
+                    "type": "array",
+                    "items": {
+                        "type": "string",
+                        "format": "uuid"
+                    },
+                    "title": "Property mappings"
+                },
+                "auth_mode": {
+                    "type": "string",
+                    "enum": [
+                        "static",
+                        "prompt"
+                    ],
+                    "title": "Auth mode"
+                },
+                "maximum_connections": {
+                    "type": "integer",
+                    "minimum": -2147483648,
+                    "maximum": 2147483647,
+                    "title": "Maximum connections"
+                }
+            },
+            "required": []
+        },
+        "model_authentik_providers_rac.endpoint_permissions": {
+            "type": "array",
+            "items": {
+                "type": "object",
+                "required": [
+                    "permission"
+                ],
+                "properties": {
+                    "permission": {
+                        "type": "string",
+                        "enum": [
+                            "add_endpoint",
+                            "change_endpoint",
+                            "delete_endpoint",
+                            "view_endpoint"
+                        ]
+                    },
+                    "user": {
+                        "type": "integer"
+                    },
+                    "role": {
+                        "type": "string"
+                    }
+                }
+            }
+        },
+        "model_authentik_providers_rac.racpropertymapping": {
+            "type": "object",
+            "properties": {
+                "managed": {
+                    "type": [
+                        "string",
+                        "null"
+                    ],
+                    "minLength": 1,
+                    "title": "Managed by authentik",
+                    "description": "Objects that are managed by authentik. These objects are created and updated automatically. This flag only indicates that an object can be overwritten by migrations. You can still modify the objects via the API, but expect changes to be overwritten in a later update."
+                },
+                "name": {
+                    "type": "string",
+                    "minLength": 1,
+                    "title": "Name"
+                },
+                "expression": {
+                    "type": "string",
+                    "title": "Expression"
+                },
+                "static_settings": {
+                    "type": "object",
+                    "additionalProperties": true,
+                    "title": "Static settings"
+                }
+            },
+            "required": []
+        },
+        "model_authentik_providers_rac.racpropertymapping_permissions": {
+            "type": "array",
+            "items": {
+                "type": "object",
+                "required": [
+                    "permission"
+                ],
+                "properties": {
+                    "permission": {
+                        "type": "string",
+                        "enum": [
+                            "add_racpropertymapping",
+                            "change_racpropertymapping",
+                            "delete_racpropertymapping",
+                            "view_racpropertymapping"
+                        ]
+                    },
+                    "user": {
+                        "type": "integer"
+                    },
+                    "role": {
+                        "type": "string"
+                    }
+                }
+            }
+        },
         "model_authentik_providers_radius.radiusprovider": {
             "type": "object",
             "properties": {
@@ -14183,216 +14425,6 @@
                 }
             }
         },
-        "model_authentik_providers_rac.racprovider": {
-            "type": "object",
-            "properties": {
-                "name": {
-                    "type": "string",
-                    "minLength": 1,
-                    "title": "Name"
-                },
-                "authentication_flow": {
-                    "type": "string",
-                    "format": "uuid",
-                    "title": "Authentication flow",
-                    "description": "Flow used for authentication when the associated application is accessed by an un-authenticated user."
-                },
-                "authorization_flow": {
-                    "type": "string",
-                    "format": "uuid",
-                    "title": "Authorization flow",
-                    "description": "Flow used when authorizing this provider."
-                },
-                "property_mappings": {
-                    "type": "array",
-                    "items": {
-                        "type": "string",
-                        "format": "uuid"
-                    },
-                    "title": "Property mappings"
-                },
-                "settings": {
-                    "type": "object",
-                    "additionalProperties": true,
-                    "title": "Settings"
-                },
-                "connection_expiry": {
-                    "type": "string",
-                    "minLength": 1,
-                    "title": "Connection expiry",
-                    "description": "Determines how long a session lasts. Default of 0 means that the sessions lasts until the browser is closed. (Format: hours=-1;minutes=-2;seconds=-3)"
-                },
-                "delete_token_on_disconnect": {
-                    "type": "boolean",
-                    "title": "Delete token on disconnect",
-                    "description": "When set to true, connection tokens will be deleted upon disconnect."
-                }
-            },
-            "required": []
-        },
-        "model_authentik_providers_rac.racprovider_permissions": {
-            "type": "array",
-            "items": {
-                "type": "object",
-                "required": [
-                    "permission"
-                ],
-                "properties": {
-                    "permission": {
-                        "type": "string",
-                        "enum": [
-                            "add_racprovider",
-                            "change_racprovider",
-                            "delete_racprovider",
-                            "view_racprovider"
-                        ]
-                    },
-                    "user": {
-                        "type": "integer"
-                    },
-                    "role": {
-                        "type": "string"
-                    }
-                }
-            }
-        },
-        "model_authentik_providers_rac.endpoint": {
-            "type": "object",
-            "properties": {
-                "name": {
-                    "type": "string",
-                    "minLength": 1,
-                    "title": "Name"
-                },
-                "provider": {
-                    "type": "integer",
-                    "title": "Provider"
-                },
-                "protocol": {
-                    "type": "string",
-                    "enum": [
-                        "rdp",
-                        "vnc",
-                        "ssh"
-                    ],
-                    "title": "Protocol"
-                },
-                "host": {
-                    "type": "string",
-                    "minLength": 1,
-                    "title": "Host"
-                },
-                "settings": {
-                    "type": "object",
-                    "additionalProperties": true,
-                    "title": "Settings"
-                },
-                "property_mappings": {
-                    "type": "array",
-                    "items": {
-                        "type": "string",
-                        "format": "uuid"
-                    },
-                    "title": "Property mappings"
-                },
-                "auth_mode": {
-                    "type": "string",
-                    "enum": [
-                        "static",
-                        "prompt"
-                    ],
-                    "title": "Auth mode"
-                },
-                "maximum_connections": {
-                    "type": "integer",
-                    "minimum": -2147483648,
-                    "maximum": 2147483647,
-                    "title": "Maximum connections"
-                }
-            },
-            "required": []
-        },
-        "model_authentik_providers_rac.endpoint_permissions": {
-            "type": "array",
-            "items": {
-                "type": "object",
-                "required": [
-                    "permission"
-                ],
-                "properties": {
-                    "permission": {
-                        "type": "string",
-                        "enum": [
-                            "add_endpoint",
-                            "change_endpoint",
-                            "delete_endpoint",
-                            "view_endpoint"
-                        ]
-                    },
-                    "user": {
-                        "type": "integer"
-                    },
-                    "role": {
-                        "type": "string"
-                    }
-                }
-            }
-        },
-        "model_authentik_providers_rac.racpropertymapping": {
-            "type": "object",
-            "properties": {
-                "managed": {
-                    "type": [
-                        "string",
-                        "null"
-                    ],
-                    "minLength": 1,
-                    "title": "Managed by authentik",
-                    "description": "Objects that are managed by authentik. These objects are created and updated automatically. This flag only indicates that an object can be overwritten by migrations. You can still modify the objects via the API, but expect changes to be overwritten in a later update."
-                },
-                "name": {
-                    "type": "string",
-                    "minLength": 1,
-                    "title": "Name"
-                },
-                "expression": {
-                    "type": "string",
-                    "title": "Expression"
-                },
-                "static_settings": {
-                    "type": "object",
-                    "additionalProperties": true,
-                    "title": "Static settings"
-                }
-            },
-            "required": []
-        },
-        "model_authentik_providers_rac.racpropertymapping_permissions": {
-            "type": "array",
-            "items": {
-                "type": "object",
-                "required": [
-                    "permission"
-                ],
-                "properties": {
-                    "permission": {
-                        "type": "string",
-                        "enum": [
-                            "add_racpropertymapping",
-                            "change_racpropertymapping",
-                            "delete_racpropertymapping",
-                            "view_racpropertymapping"
-                        ]
-                    },
-                    "user": {
-                        "type": "integer"
-                    },
-                    "role": {
-                        "type": "string"
-                    }
-                }
-            }
-        },
         "model_authentik_providers_ssf.ssfprovider": {
             "type": "object",
             "properties": {
diff --git a/go.mod b/go.mod
index 274837c657..3966daef7a 100644
--- a/go.mod
+++ b/go.mod
@@ -29,7 +29,7 @@ require (
 	github.com/spf13/cobra v1.9.1
 	github.com/stretchr/testify v1.10.0
 	github.com/wwt/guac v1.3.2
-	goauthentik.io/api/v3 v3.2024123.4
+	goauthentik.io/api/v3 v3.2024123.6
 	golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
 	golang.org/x/oauth2 v0.26.0
 	golang.org/x/sync v0.11.0
diff --git a/go.sum b/go.sum
index 949be28e57..bf3f192e33 100644
--- a/go.sum
+++ b/go.sum
@@ -299,8 +299,8 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y
 go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
 go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
 go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
-goauthentik.io/api/v3 v3.2024123.4 h1:JYLsUjkJ7kT+jHO72DyFTXFwKEGAcOOlLh36SRG9BDw=
-goauthentik.io/api/v3 v3.2024123.4/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
+goauthentik.io/api/v3 v3.2024123.6 h1:AGOCa7Fc/9eONCPEW4sEhTiyEBvxN57Lfqz1zm6Gy98=
+goauthentik.io/api/v3 v3.2024123.6/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
diff --git a/lifecycle/aws/package-lock.json b/lifecycle/aws/package-lock.json
index 7f7058b327..98dd6b7c86 100644
--- a/lifecycle/aws/package-lock.json
+++ b/lifecycle/aws/package-lock.json
@@ -9,7 +9,7 @@
             "version": "0.0.0",
             "license": "MIT",
             "devDependencies": {
-                "aws-cdk": "^2.178.2",
+                "aws-cdk": "^2.179.0",
                 "cross-env": "^7.0.3"
             },
             "engines": {
@@ -17,9 +17,9 @@
             }
         },
         "node_modules/aws-cdk": {
-            "version": "2.178.2",
-            "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.178.2.tgz",
-            "integrity": "sha512-ojMCMnBGinvDUD6+BOOlUOB9pjsYXoQdFVbf4bvi3dy3nwn557r0j6qDUcJMeikzPJ6YWzfAdL0fYxBZg4xcOg==",
+            "version": "2.179.0",
+            "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.179.0.tgz",
+            "integrity": "sha512-aA2+8S2g4UBQHkUEt0mYd16VLt/ucR+QfyUJi34LDKRAhOCNDjPCZ4z9z/JEDyuni0BdzsYA55pnpDN9tMULpA==",
             "dev": true,
             "license": "Apache-2.0",
             "bin": {
diff --git a/lifecycle/aws/package.json b/lifecycle/aws/package.json
index 8d091ee737..4521357683 100644
--- a/lifecycle/aws/package.json
+++ b/lifecycle/aws/package.json
@@ -10,7 +10,7 @@
         "node": ">=20"
     },
     "devDependencies": {
-        "aws-cdk": "^2.178.2",
+        "aws-cdk": "^2.179.0",
         "cross-env": "^7.0.3"
     }
 }
diff --git a/poetry.lock b/poetry.lock
index a772a7c1c2..81c451ddf3 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -358,22 +358,6 @@ jsii = ">=1.105.0,<2.0.0"
 publication = ">=0.0.3"
 typeguard = ">=2.13.3,<4.3.0"
 
-[[package]]
-name = "aws-cdk-asset-kubectl-v20"
-version = "2.1.3"
-description = "A Lambda Layer that contains kubectl v1.20"
-optional = false
-python-versions = "~=3.8"
-files = [
-    {file = "aws_cdk.asset_kubectl_v20-2.1.3-py3-none-any.whl", hash = "sha256:d5612e5bd03c215a28ce53193b1144ecf4e93b3b6779563c046a8a74d83a3979"},
-    {file = "aws_cdk_asset_kubectl_v20-2.1.3.tar.gz", hash = "sha256:237cd8530d9e8be0bbc7159af927dbb6b7f91bf3f4099c8ef4d9a213b34264be"},
-]
-
-[package.dependencies]
-jsii = ">=1.103.1,<2.0.0"
-publication = ">=0.0.3"
-typeguard = ">=2.13.3,<5.0.0"
-
 [[package]]
 name = "aws-cdk-asset-node-proxy-agent-v6"
 version = "2.1.0"
@@ -408,18 +392,17 @@ typeguard = ">=2.13.3,<4.3.0"
 
 [[package]]
 name = "aws-cdk-lib"
-version = "2.178.2"
+version = "2.179.0"
 description = "Version 2 of the AWS Cloud Development Kit library"
 optional = false
 python-versions = "~=3.8"
 files = [
-    {file = "aws_cdk_lib-2.178.2-py3-none-any.whl", hash = "sha256:624383e57fe2b32f7d0fc098b78b4cd21d19ae3af3f24b01f32ec4795baaee25"},
-    {file = "aws_cdk_lib-2.178.2.tar.gz", hash = "sha256:c00757885b74023350bb34f388f6447155e802ecf827e595bda917098a4925fe"},
+    {file = "aws_cdk_lib-2.179.0-py3-none-any.whl", hash = "sha256:1d7b88ee69067b8d58dac9eeb6697bbaf5d5c032a3070898389c41e7c4f3e3d7"},
+    {file = "aws_cdk_lib-2.179.0.tar.gz", hash = "sha256:b653a55754f4020a4b36e4ae183d213e76e27b18b842cbf9e430e9eccb700550"},
 ]
 
 [package.dependencies]
 "aws-cdk.asset-awscli-v1" = ">=2.2.208,<3.0.0"
-"aws-cdk.asset-kubectl-v20" = ">=2.1.3,<3.0.0"
 "aws-cdk.asset-node-proxy-agent-v6" = ">=2.1.0,<3.0.0"
 "aws-cdk.cloud-assembly-schema" = ">=39.2.0,<40.0.0"
 constructs = ">=10.0.0,<11.0.0"
@@ -466,13 +449,13 @@ typing-extensions = ">=4.0.0"
 
 [[package]]
 name = "bandit"
-version = "1.8.2"
+version = "1.8.3"
 description = "Security oriented static analyser for python code."
 optional = false
 python-versions = ">=3.9"
 files = [
-    {file = "bandit-1.8.2-py3-none-any.whl", hash = "sha256:df6146ad73dd30e8cbda4e29689ddda48364e36ff655dbfc86998401fcf1721f"},
-    {file = "bandit-1.8.2.tar.gz", hash = "sha256:e00ad5a6bc676c0954669fe13818024d66b70e42cf5adb971480cf3b671e835f"},
+    {file = "bandit-1.8.3-py3-none-any.whl", hash = "sha256:28f04dc0d258e1dd0f99dee8eefa13d1cb5e3fde1a5ab0c523971f97b289bcd8"},
+    {file = "bandit-1.8.3.tar.gz", hash = "sha256:f5847beb654d309422985c36644649924e0ea4425c76dec2e89110b87506193a"},
 ]
 
 [package.dependencies]
@@ -1884,6 +1867,17 @@ files = [
     {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"},
 ]
 
+[[package]]
+name = "geographiclib"
+version = "2.0"
+description = "The geodesic routines from GeographicLib"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "geographiclib-2.0-py3-none-any.whl", hash = "sha256:6b7225248e45ff7edcee32becc4e0a1504c606ac5ee163a5656d482e0cd38734"},
+    {file = "geographiclib-2.0.tar.gz", hash = "sha256:f7f41c85dc3e1c2d3d935ec86660dc3b2c848c83e17f9a9e51ba9d5146a15859"},
+]
+
 [[package]]
 name = "geoip2"
 version = "5.0.1"
@@ -1903,6 +1897,29 @@ requests = ">=2.24.0,<3.0.0"
 [package.extras]
 test = ["pytest-httpserver (>=1.0.10)"]
 
+[[package]]
+name = "geopy"
+version = "2.4.1"
+description = "Python Geocoding Toolbox"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "geopy-2.4.1-py3-none-any.whl", hash = "sha256:ae8b4bc5c1131820f4d75fce9d4aaaca0c85189b3aa5d64c3dcaf5e3b7b882a7"},
+    {file = "geopy-2.4.1.tar.gz", hash = "sha256:50283d8e7ad07d89be5cb027338c6365a32044df3ae2556ad3f52f4840b3d0d1"},
+]
+
+[package.dependencies]
+geographiclib = ">=1.52,<3"
+
+[package.extras]
+aiohttp = ["aiohttp"]
+dev = ["coverage", "flake8 (>=5.0,<5.1)", "isort (>=5.10.0,<5.11.0)", "pytest (>=3.10)", "pytest-asyncio (>=0.17)", "readme-renderer", "sphinx (<=4.3.2)", "sphinx-issues", "sphinx-rtd-theme (>=0.5.0)"]
+dev-docs = ["readme-renderer", "sphinx (<=4.3.2)", "sphinx-issues", "sphinx-rtd-theme (>=0.5.0)"]
+dev-lint = ["flake8 (>=5.0,<5.1)", "isort (>=5.10.0,<5.11.0)"]
+dev-test = ["coverage", "pytest (>=3.10)", "pytest-asyncio (>=0.17)", "sphinx (<=4.3.2)"]
+requests = ["requests (>=2.16.2)", "urllib3 (>=1.24.2)"]
+timezone = ["pytz"]
+
 [[package]]
 name = "google-api-core"
 version = "2.19.1"
@@ -4611,13 +4628,13 @@ websocket-client = ">=1.8,<2.0"
 
 [[package]]
 name = "sentry-sdk"
-version = "2.21.0"
+version = "2.22.0"
 description = "Python client for Sentry (https://sentry.io)"
 optional = false
 python-versions = ">=3.6"
 files = [
-    {file = "sentry_sdk-2.21.0-py2.py3-none-any.whl", hash = "sha256:7623cfa9e2c8150948a81ca253b8e2bfe4ce0b96ab12f8cd78e3ac9c490fd92f"},
-    {file = "sentry_sdk-2.21.0.tar.gz", hash = "sha256:a6d38e0fb35edda191acf80b188ec713c863aaa5ad8d5798decb8671d02077b6"},
+    {file = "sentry_sdk-2.22.0-py2.py3-none-any.whl", hash = "sha256:3d791d631a6c97aad4da7074081a57073126c69487560c6f8bffcf586461de66"},
+    {file = "sentry_sdk-2.22.0.tar.gz", hash = "sha256:b4bf43bb38f547c84b2eadcefbe389b36ef75f3f38253d7a74d6b928c07ae944"},
 ]
 
 [package.dependencies]
@@ -4661,6 +4678,7 @@ sanic = ["sanic (>=0.8)"]
 sqlalchemy = ["sqlalchemy (>=1.2)"]
 starlette = ["starlette (>=0.19.1)"]
 starlite = ["starlite (>=1.48)"]
+statsig = ["statsig (>=0.55.3)"]
 tornado = ["tornado (>=6)"]
 unleash = ["UnleashClient (>=6.0.1)"]
 
@@ -5847,4 +5865,4 @@ files = [
 [metadata]
 lock-version = "2.0"
 python-versions = "~3.12"
-content-hash = "a3915ac2ef2bb53f7cd67070912cdaf717c3bf73ed972fa337a9b07fce162451"
+content-hash = "8a6bfd4833e415a9f4f613ab4f33e60c8332b9f5743583222cdb7190f6286216"
diff --git a/pyproject.toml b/pyproject.toml
index 2fb4649d4b..e4312479f9 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -113,6 +113,7 @@ duo-client = "*"
 fido2 = "*"
 flower = "*"
 geoip2 = "*"
+geopy = "*"
 google-api-python-client = "*"
 gunicorn = "*"
 gssapi = "*"
diff --git a/schema.yml b/schema.yml
index ebb6732b40..9896329197 100644
--- a/schema.yml
+++ b/schema.yml
@@ -39482,6 +39482,7 @@ components:
       - authentik.providers.ldap
       - authentik.providers.oauth2
       - authentik.providers.proxy
+      - authentik.providers.rac
       - authentik.providers.radius
       - authentik.providers.saml
       - authentik.providers.scim
@@ -39522,7 +39523,6 @@ components:
       - authentik.enterprise.audit
       - authentik.enterprise.providers.google_workspace
       - authentik.enterprise.providers.microsoft_entra
-      - authentik.enterprise.providers.rac
       - authentik.enterprise.providers.ssf
       - authentik.enterprise.stages.authenticator_endpoint_gdtc
       - authentik.enterprise.stages.source
@@ -44006,6 +44006,27 @@ components:
           items:
             $ref: '#/components/schemas/DetailedCountryField'
           readOnly: true
+        check_history_distance:
+          type: boolean
+        history_max_distance_km:
+          type: integer
+          maximum: 9223372036854775807
+          minimum: 0
+          format: int64
+        distance_tolerance_km:
+          type: integer
+          maximum: 2147483647
+          minimum: 0
+        history_login_count:
+          type: integer
+          maximum: 2147483647
+          minimum: 0
+        check_impossible_travel:
+          type: boolean
+        impossible_tolerance_km:
+          type: integer
+          maximum: 2147483647
+          minimum: 0
       required:
       - bound_to
       - component
@@ -44038,6 +44059,27 @@ components:
           items:
             $ref: '#/components/schemas/CountryCodeEnum'
           maxItems: 249
+        check_history_distance:
+          type: boolean
+        history_max_distance_km:
+          type: integer
+          maximum: 9223372036854775807
+          minimum: 0
+          format: int64
+        distance_tolerance_km:
+          type: integer
+          maximum: 2147483647
+          minimum: 0
+        history_login_count:
+          type: integer
+          maximum: 2147483647
+          minimum: 0
+        check_impossible_travel:
+          type: boolean
+        impossible_tolerance_km:
+          type: integer
+          maximum: 2147483647
+          minimum: 0
       required:
       - countries
       - name
@@ -46583,6 +46625,9 @@ components:
       - authentik_providers_oauth2.scopemapping
       - authentik_providers_oauth2.oauth2provider
       - authentik_providers_proxy.proxyprovider
+      - authentik_providers_rac.racprovider
+      - authentik_providers_rac.endpoint
+      - authentik_providers_rac.racpropertymapping
       - authentik_providers_radius.radiusprovider
       - authentik_providers_radius.radiusproviderpropertymapping
       - authentik_providers_saml.samlprovider
@@ -46652,9 +46697,6 @@ components:
       - authentik_providers_google_workspace.googleworkspaceprovidermapping
       - authentik_providers_microsoft_entra.microsoftentraprovider
       - authentik_providers_microsoft_entra.microsoftentraprovidermapping
-      - authentik_providers_rac.racprovider
-      - authentik_providers_rac.endpoint
-      - authentik_providers_rac.racpropertymapping
       - authentik_providers_ssf.ssfprovider
       - authentik_stages_authenticator_endpoint_gdtc.authenticatorendpointgdtcstage
       - authentik_stages_source.sourcestage
@@ -50557,6 +50599,27 @@ components:
           items:
             $ref: '#/components/schemas/CountryCodeEnum'
           maxItems: 249
+        check_history_distance:
+          type: boolean
+        history_max_distance_km:
+          type: integer
+          maximum: 9223372036854775807
+          minimum: 0
+          format: int64
+        distance_tolerance_km:
+          type: integer
+          maximum: 2147483647
+          minimum: 0
+        history_login_count:
+          type: integer
+          maximum: 2147483647
+          minimum: 0
+        check_impossible_travel:
+          type: boolean
+        impossible_tolerance_km:
+          type: integer
+          maximum: 2147483647
+          minimum: 0
     PatchedGoogleWorkspaceProviderMappingRequest:
       type: object
       description: GoogleWorkspaceProviderMapping Serializer
diff --git a/web/build.mjs b/web/build.mjs
index 65d36a7d80..f9ca7b346c 100644
--- a/web/build.mjs
+++ b/web/build.mjs
@@ -74,7 +74,7 @@ const interfaces = [
     ["user/UserInterface.ts", "user"],
     ["flow/FlowInterface.ts", "flow"],
     ["standalone/api-browser/index.ts", "standalone/api-browser"],
-    ["enterprise/rac/index.ts", "enterprise/rac"],
+    ["rac/index.ts", "rac"],
     ["standalone/loading/index.ts", "standalone/loading"],
     ["polyfill/poly.ts", "."],
 ];
diff --git a/web/package-lock.json b/web/package-lock.json
index 5f0c10b660..967432ec77 100644
--- a/web/package-lock.json
+++ b/web/package-lock.json
@@ -23,7 +23,7 @@
                 "@floating-ui/dom": "^1.6.11",
                 "@formatjs/intl-listformat": "^7.5.7",
                 "@fortawesome/fontawesome-free": "^6.6.0",
-                "@goauthentik/api": "^2024.12.3-1739801838",
+                "@goauthentik/api": "^2024.12.3-1739965710",
                 "@lit-labs/ssr": "^3.2.2",
                 "@lit/context": "^1.1.2",
                 "@lit/localize": "^0.12.2",
@@ -1814,9 +1814,9 @@
             }
         },
         "node_modules/@goauthentik/api": {
-            "version": "2024.12.3-1739801838",
-            "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2024.12.3-1739801838.tgz",
-            "integrity": "sha512-gK+chjueX2MbHyjeYczx+plapSRmzaTkZDH6PFwulcvxIFb3awfMkw4cWDjwHZunfDgu8EoP50cPlF3AA/PNoQ=="
+            "version": "2024.12.3-1739965710",
+            "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2024.12.3-1739965710.tgz",
+            "integrity": "sha512-16zoQWeJhAFSwttvqLRoXoQA43tMW1ZXDEihW6r8rtWtlxqPh7n36RtcWYraYiLcjmJskI90zdgz6k1kmY5AXw=="
         },
         "node_modules/@goauthentik/web": {
             "resolved": "",
diff --git a/web/package.json b/web/package.json
index 801479e3ec..864a8bfaa2 100644
--- a/web/package.json
+++ b/web/package.json
@@ -11,7 +11,7 @@
         "@floating-ui/dom": "^1.6.11",
         "@formatjs/intl-listformat": "^7.5.7",
         "@fortawesome/fontawesome-free": "^6.6.0",
-        "@goauthentik/api": "^2024.12.3-1739801838",
+        "@goauthentik/api": "^2024.12.3-1739965710",
         "@lit-labs/ssr": "^3.2.2",
         "@lit/context": "^1.1.2",
         "@lit/localize": "^0.12.2",
diff --git a/web/scripts/knip.config.ts b/web/scripts/knip.config.ts
index a923bd63ae..b2a1ac3f11 100644
--- a/web/scripts/knip.config.ts
+++ b/web/scripts/knip.config.ts
@@ -6,7 +6,7 @@ const config: KnipConfig = {
         "./src/user/UserInterface.ts",
         "./src/flow/FlowInterface.ts",
         "./src/standalone/api-browser/index.ts",
-        "./src/enterprise/rac/index.ts",
+        "./src/rac/index.ts",
         "./src/standalone/loading/index.ts",
         "./src/polyfill/poly.ts",
     ],
diff --git a/web/src/admin/policies/geoip/GeoIPPolicyForm.ts b/web/src/admin/policies/geoip/GeoIPPolicyForm.ts
index 440323a430..1b5119ae2b 100644
--- a/web/src/admin/policies/geoip/GeoIPPolicyForm.ts
+++ b/web/src/admin/policies/geoip/GeoIPPolicyForm.ts
@@ -1,5 +1,6 @@
 import { BasePolicyForm } from "@goauthentik/admin/policies/BasePolicyForm";
 import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
+import { first } from "@goauthentik/common/utils";
 import "@goauthentik/elements/ak-dual-select";
 import { DataProvision, DualSelectPair } from "@goauthentik/elements/ak-dual-select/types";
 import "@goauthentik/elements/forms/FormGroup";
@@ -46,7 +47,7 @@ export class GeoIPPolicyForm extends BasePolicyForm
+ ${msg( + "When this option enabled, the GeoIP data of the policy request is compared to the specified number of historical logins.", + )} +
++ ${msg("Tolerance in checking for distances in kilometers.")} +
++ ${msg("Amount of previous login events to check against.")} +
++ ${msg( + "Maximum distance a login attempt is allowed from in kilometers.", + )} +
++ ${msg( + "When this option enabled, the GeoIP data of the policy request is compared to the specified number of historical logins and if the travel would have been possible in the amount of time since the previous event.", + )} +
++ ${msg("Tolerance in checking for distances in kilometers.")} +
+