# How to Set Up a RADIUS Provider in authentik: Complete Configuration Guide

> Learn to set up a RADIUS provider in authentik. This guide covers configuring authentik to authenticate users with RADIUS via an outpost for centralized policy enforcement.

- Repository: [Authentik Security/authentik](https://github.com/goauthentik/authentik)
- Tags: how-to-guide
- Published: 2026-08-14

---

**RADIUS providers in authentik enable external applications to authenticate users via the RADIUS protocol through a containerized outpost that enforces centralized policies.**

Setting up a RADIUS provider involves three interconnected layers: defining the provider model in authentik's database, exposing it through REST APIs, and deploying a dedicated outpost container. This guide walks through each layer using actual source paths and working code examples from the goauthentik/authentik repository.

## Understanding the RADIUS Provider Architecture

The authentik RADIUS implementation follows a clean separation between configuration, policy evaluation, and protocol handling. All three layers work together to ensure user authentication requests are validated against your existing authentik policies before a RADIUS response is generated.

### Data Model Layer

The `RadiusProvider` model in [`authentik/providers/radius/models.py`](https://github.com/goauthentik/authentik/blob/main/authentik/providers/radius/models.py) extends both `Provider` and `OutpostModel` to inherit core provider functionality while enabling outpost deployment capabilities.

Key fields stored by the model include:

- **Shared secret** — the pre-shared key used to authenticate RADIUS clients
- **Client networks** — CIDR-notation allowed source IP ranges
- **TLS certificate** — optional certificate for secure communication
- **MFA support flag** — enables multi-factor authentication flows

The model also defines its UI component (`component = "ak-provider-radius-form"`) and icon for the authentik admin interface.

### REST API Layer

Two viewsets in [`authentik/providers/radius/api/providers.py`](https://github.com/goauthentik/authentik/blob/main/authentik/providers/radius/api/providers.py) expose RADIUS functionality:

**`RadiusProviderViewSet`** — handles CRUD operations using `RadiusProviderSerializer`. This serializer reads and writes all provider fields including the sensitive shared secret.

**`RadiusOutpostConfigViewSet`** — supplies minimal configuration for outpost initialization: provider name, application slug, shared secret, and network bindings.

The critical `check_access` action on the viewset performs policy evaluation. When called with an `app_slug` parameter, it:

1. Builds a policy engine for the target application
2. Runs all configured policies against the requesting user
3. On success, returns a Base64-encoded RADIUS packet containing attribute mappings

This centralizes all access decisions in authentik rather than distributing logic to outposts.

### Outpost Deployment Layer

Radius outposts run as containerized services that bridge RADIUS UDP traffic to authentik's HTTP API. The deployment is managed through:

- **`RadiusDockerController`** ([`authentik/providers/radius/controllers/docker.py`](https://github.com/goauthentik/authentik/blob/main/authentik/providers/radius/controllers/docker.py))
- **`RadiusKubernetesController`** ([`authentik/providers/radius/controllers/kubernetes.py`](https://github.com/goauthentik/authentik/blob/main/authentik/providers/radius/controllers/kubernetes.py))

These controllers create containers exposing **UDP port 1812**, mount the shared secret as configuration, and bind any configured TLS certificates. The outpost image is built from `lifecycle/container/radius.Dockerfile`.

## Creating a RADIUS Provider via API

Use authentik's Python client to programmatically create a provider with MFA support and restricted client networks:

```python
from goauthentik.client import AuthentikClient
from goauthentik.models import RadiusProvider

client = AuthentikClient(
    base_url="https://auth.example.com",
    token="YOUR_API_TOKEN"
)

provider = RadiusProvider(
    name="Corporate VPN RADIUS",
    client_networks="10.0.0.0/8, 192.168.0.0/16",
    shared_secret="super-secret-key-min-16-chars",
    mfa_support=True,
)

created = client.providers.radius.create(provider)
print(f"Provider created with ID: {created.pk}")

```

### Linking to an Application

After creating the provider, associate it with an application to enable policy evaluation:

```python
app = client.applications.create(
    name="Corporate VPN",
    slug="corp-vpn"
)

# Link the RADIUS provider

app.provider = created.pk
client.applications.update(app)

# Now policies applied to "corp-vpn" will evaluate during RADIUS authentication

```

## Testing Policy Evaluation Directly

The `check_access` endpoint can be called independently to verify configuration before deploying an outpost. This is useful for debugging attribute mappings:

```python
import requests
import base64

BASE = "https://auth.example.com/api"
TOKEN = "YOUR_API_TOKEN"
PROVIDER_ID = 42
APP_SLUG = "corp-vpn"

url = (
    f"{BASE}/outposts/radius/{PROVIDER_ID}/"
    f"check_access/?app_slug={APP_SLUG}"
)

resp = requests.get(
    url,
    headers={"Authorization": f"Bearer {TOKEN}"}
)
data = resp.json()

if data["access"]["passing"]:
    # Decode the RADIUS packet with injected attributes

    packet = base64.b64decode(data["attributes"])
    print(f"Access granted, packet size: {len(packet)} bytes")
else:
    print("Access denied by policy evaluation")
    print(f"Messages: {data['access']['messages']}")

```

The response includes the full policy evaluation result and pre-built RADIUS packet, eliminating guesswork about what attributes will be sent to clients.

## Deploying the RADIUS Outpost

### Docker Deployment

Run the official outpost container with environment-based configuration:

```bash
docker run -d \
  --name authentik-radius \
  -e AUTHENTIK_URL=https://auth.example.com \
  -e AUTHENTIK_TOKEN=YOUR_API_TOKEN \
  -e AUTHENTIK_INSECURE=false \
  -p 1812:1812/udp \
  ghcr.io/goauthentik/dev-radius:latest

```

The container automatically discovers all RADIUS providers your token can access and begins listening on UDP 1812.

### Kubernetes Deployment

For production Kubernetes environments, the `RadiusKubernetesController` generates a Deployment with the correct pod specification:

1. UDP port 1812 exposed on the pod
2. Token mounted via Secret
3. Resource limits configured for network throughput

The controller watches for provider changes and rolls out updates automatically.

## Authentication Flow Deep Dive

When a RADIUS client sends an Access-Request packet, this sequence executes:

1. **Outpost receives UDP packet** on port 1812
2. **Packet forwarded** to authentik's `check_access` endpoint with the target application slug
3. **Policy engine evaluates** all policies attached to the application
4. **Attribute mappings execute** if policies pass, injecting custom RADIUS attributes
5. **Encoded response returned** to outpost as Base64 RADIUS packet
6. **Outpost transmits response** back to the original client

This flow guarantees that **all policy decisions remain centralized** — the outpost acts only as a protocol converter, not an authorization authority.

## Property Mappings for Custom Attributes

RADIUS attribute injection uses dedicated property mappings defined in [`authentik/providers/radius/api/property_mappings.py`](https://github.com/goauthentik/authentik/blob/main/authentik/providers/radius/api/property_mappings.py). These mappings let you transform authentik user data into vendor-specific RADIUS attributes.

Example mapping that injects group membership:

```python
from goauthentik.models import RadiusProviderPropertyMapping

group_mapping = RadiusProviderPropertyMapping(
    name="RADIUS Groups",
    expression="""
    return {
        "Class": user.ak_groups.all().values_list("name", flat=True)
    }
    """
)

```

The `expression` field accepts Python code that returns a dictionary of RADIUS attribute names to values. All standard RADIUS attribute types are supported.

## Key Source Files Reference

| Component | Source File |
|-----------|-------------|
| Provider model definition | [`authentik/providers/radius/models.py`](https://github.com/goauthentik/authentik/blob/main/authentik/providers/radius/models.py) |
| REST API viewsets and serializers | [`authentik/providers/radius/api/providers.py`](https://github.com/goauthentik/authentik/blob/main/authentik/providers/radius/api/providers.py) |
| Property mapping API | [`authentik/providers/radius/api/property_mappings.py`](https://github.com/goauthentik/authentik/blob/main/authentik/providers/radius/api/property_mappings.py) |
| Docker deployment controller | [`authentik/providers/radius/controllers/docker.py`](https://github.com/goauthentik/authentik/blob/main/authentik/providers/radius/controllers/docker.py) |
| Kubernetes deployment controller | [`authentik/providers/radius/controllers/kubernetes.py`](https://github.com/goauthentik/authentik/blob/main/authentik/providers/radius/controllers/kubernetes.py) |
| Outpost image build | `lifecycle/container/radius.Dockerfile` |
| Outpost task orchestration | [`authentik/outposts/tasks.py`](https://github.com/goauthentik/authentik/blob/main/authentik/outposts/tasks.py) |

## Summary

- **RADIUS providers in authentik** combine a database model, REST API, and containerized outpost to deliver centralized authentication
- **The `RadiusProvider` model** stores shared secrets, client networks, and MFA configuration in [`authentik/providers/radius/models.py`](https://github.com/goauthentik/authentik/blob/main/authentik/providers/radius/models.py)
- **Policy enforcement happens centrally** through the `check_access` endpoint in [`authentik/providers/radius/api/providers.py`](https://github.com/goauthentik/authentik/blob/main/authentik/providers/radius/api/providers.py)
- **Outposts operate as stateless containers** that convert UDP RADIUS traffic to HTTP API calls, keeping secrets and decisions server-side
- **Property mappings enable custom attributes** by transforming authentik user data into RADIUS response fields

## Frequently Asked Questions

### What UDP port does the RADIUS outpost use?

The RADIUS outpost listens on **UDP port 1812** by default. This is configured in both the Docker controller (`RadiusDockerController`) and the outpost container specification. The port mapping is defined as `1812:1812/udp` in generated deployments.

### Can I restrict which IP addresses can send RADIUS requests?

Yes. The `client_networks` field on `RadiusProvider` accepts comma-separated CIDR notation. For example, `"10.0.0.0/8, 192.168.1.0/24"` limits requests to those networks. Invalid source IPs are rejected at the outpost level before reaching the authentik API.

### How does MFA work with RADIUS authentication?

When `mfa_support=True` is set on the provider, authentik's policy engine evaluates MFA requirements during the `check_access` call. If MFA is required but incomplete, the RADIUS Access-Reject response includes appropriate error attributes. The actual MFA challenge/response happens through authentik's standard flows, not within the RADIUS protocol itself.

### Can I run multiple RADIUS outposts for high availability?

Yes. Each outpost independently polls the authentik API for configuration and can serve identical provider definitions. Deploy multiple containers or pods behind a load balancer distributing UDP 1812 traffic. No session state is stored in the outpost — all authentication state lives in authentik's database.