# How to Use the GeoIP Policy for Location-Based Access Control in authentik

> Learn how to use authentik's GeoIP policy for location-based access control. Secure your applications by matching IPs against GeoLite2 databases and enforcing location continuity.

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

---

**The GeoIP Policy in authentik enables geographic access control by matching client IP addresses against MaxMind GeoLite2 databases for country, ASN, and travel-based checks, with optional session binding to enforce location continuity.**

The **GeoIP Policy** is a core authentik policy type that leverages MaxMind GeoLite2 databases to make authorization decisions based on where requests originate. Whether you need to block specific countries, restrict access to certain network providers, or detect anomalous login patterns like impossible travel, this policy provides granular location-based controls without writing custom code.

## What the GeoIP Policy Evaluates

The policy evaluates five distinct criteria that you can mix and match:

| Criterion | Description |
|-----------|-------------|
| **Country match** | Compares the client's ISO-3166 country code against an allowlist or blocklist |
| **ASN match** | Validates the client's Autonomous System Number against configured values |
| **Historical distance check** | Computes geographic distance between the current login and recent successful logins |
| **Impossible-travel check** | Rejects logins that would require physically impossible travel speeds based on time elapsed |
| **Session binding** | Binds authenticated sessions to continent, country, or city, terminating sessions that violate the binding |

These checks operate against GeoIP data loaded from `/geoip/GeoLite2-City.mmdb` and `/geoip/GeoLite2-ASN.mmdb` at startup. Authentik automatically detects and reloads updated database files without restart.

## Core Implementation Files

The GeoIP Policy implementation spans several key files in the `authentik/policies/geoip/` directory:

- **[`authentik/policies/geoip/models.py`](https://github.com/goauthentik/authentik/blob/main/authentik/policies/geoip/models.py)** — Defines the `GeoIPPolicy` model with fields for `countries`, `asns`, `check_history_distance`, `check_impossible_travel`, `history_login_count`, and `bind_to`
- **[`authentik/policies/geoip/api.py`](https://github.com/goauthentik/authentik/blob/main/authentik/policies/geoip/api.py)** — Contains `GeoIPPolicySerializer` and `GeoIPPolicyViewSet` for REST API access
- **[`authentik/policies/geoip/urls.py`](https://github.com/goauthentik/authentik/blob/main/authentik/policies/geoip/urls.py)** — Routes API endpoints to `/policies/geoip/`
- **[`authentik/policies/geoip/tests.py`](https://github.com/goauthentik/authentik/blob/main/authentik/policies/geoip/tests.py)** — Comprehensive test coverage for all evaluation modes

## Creating a GeoIP Policy via API

Use the REST API to programmatically create policies for automated infrastructure deployment:

```bash
curl -X POST https://authentik.example.com/api/v3/policies/geoip/ \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${AUTHENTIK_TOKEN}" \
  -d '{
    "name": "Restrict to North America ISPs",
    "executionLogging": true,
    "countries": ["US", "CA", "MX"],
    "asns": [7922, 7018, 8075],
    "check_history_distance": false,
    "check_impossible_travel": true,
    "history_login_count": 5,
    "bind_to": "country"
  }'

```

Key parameters explained:

- **`countries`** — Array of two-letter ISO-3166 country codes
- **`asns`** — Array of ASN numbers as integers
- **`check_impossible_travel`** — Enables velocity-based anomaly detection
- **`history_login_count`** — How many recent logins to compare against (default: 5)
- **`bind_to`** — One of `continent`, `country`, `city`, or empty string for no binding

## Creating a GeoIP Policy via UI

For single policy creation, use the authentik admin interface:

1. Navigate to **Customization → Policies**
2. Click **Create** and select **GeoIP Policy**
3. Configure the **Countries** field with comma-separated ISO codes (e.g., `DE, FR, NL, SE`)
4. Optionally add **ASNs** for provider-level restrictions
5. Enable **Check impossible travel** to detect credential sharing
6. Set **Bind sessions to** → **Country** to enforce location continuity
7. Attach the policy to a flow stage or application binding

## Session Binding and Security

Session binding is implemented in the user login stage configuration. When enabled, the resolved GeoIP attribute is stored with the session; subsequent requests with differing attributes terminate the session and require re-authentication.

Example flow stage configuration:

```yaml
- name: default-authentication-user-login
  type: authentik.stages.user_login.UserLoginStage
  bind_sessions: true
  geo_ip_binding: country

```

Binding granularity options:

- **`continent`** — Most permissive, allows movement within continents
- **`country`** — Balanced security for most organizations
- **`city`** — Most restrictive, suitable for high-security environments

## Detecting Anomalous Login Patterns

The **impossible travel** check uses both geographic distance and time delta between logins. The calculation considers Earth's circumference and realistic maximum travel speeds, flagging logins that exceed plausible human movement.

Enable with caution for users who legitimately use VPNs or travel frequently—these scenarios generate false positives. Combine with **history distance checking** for layered detection:

- **Distance check only** — Rejects distant logins regardless of timing
- **Impossible travel** — Rejects only physically unachievable movements
- **Both enabled** — Maximum protection, higher false-positive rate

## GeoIP Database Management

Operational maintenance of GeoIP data is critical for accurate enforcement. The database files must be mounted to `/geoip` in your authentik deployment:

```docker-compose
volumes:
  - ./geoip:/geoip:ro

```

Update procedure:

1. Download updated GeoLite2 databases from MaxMind
2. Replace files in the mounted volume
3. Authentik detects file changes and reloads within 60 seconds

For automated updates, use the MaxMind GeoIP Update tool or a scheduled job that pulls the latest databases before replacement.

## Integrating with Expression Policies

While the GeoIP Policy covers common use cases, raw GeoIP data is also available in **Expression Policies** through the context object:

```python

# Example expression policy accessing raw GeoIP context

if context.get("geo", {}).get("country", {}).get("iso_code") == "CN":
    return False

asn = context.get("asn", {}).get("autonomous_system_number")
if asn and asn > 64496:  # Private ASN range

    return False

return True

```

Prefer dedicated GeoIP Policies for simple country/ASN checks—these are optimized and provide clearer audit logging than custom expressions.

## Summary

- The **GeoIP Policy** provides built-in location-based access control using MaxMind GeoLite2 databases
- Core model in [`authentik/policies/geoip/models.py`](https://github.com/goauthentik/authentik/blob/main/authentik/policies/geoip/models.py) supports country matching, ASN filtering, distance checks, impossible-travel detection, and session binding
- REST API and UI both support full policy lifecycle management
- Session binding enforces geographic continuity for authenticated sessions
- Database updates require volume mounts to `/geoip` with automatic detection of file changes

## Frequently Asked Questions

### How do I obtain and update the MaxMind GeoIP databases?

MaxMind requires a free account to download GeoLite2 databases. After registration, download `GeoLite2-City.mmdb` and `GeoLite2-ASN.mmdb`, then mount them to `/geoip` in your authentik containers. The [authentik geoip operations documentation](https://github.com/goauthentik/authentik/blob/main/website/docs/sys-mgmt/ops/geoip.mdx) provides automation patterns using the `geoipupdate` tool.

### Why is my GeoIP Policy not blocking traffic as expected?

Most failures stem from missing or outdated database files, reverse proxy configurations that obscure client IPs, or private IP ranges that cannot be geolocated. Verify your proxy passes `X-Forwarded-For` headers and that authentik's `LISTEN_TRUSTED_PROXY` setting includes your proxy's IP. Check the **Event Log** for GeoIP resolution results.

### Can I use GeoIP Policies with IPv6 addresses?

Yes—MaxMind GeoLite2 databases include IPv6 coverage. Ensure your authentik deployment receives IPv6 client addresses (not NAT64) for accurate lookups. The policy evaluation code handles both address families transparently.