Skip to main content

Protecting Routes

Labs Feature

Route protection is a labs feature and is disabled by default. Enable it with --labs routeoidc or MIREN_LABS=routeoidc when starting the server.

Looking for CI/CD OIDC?

If you want to deploy from GitHub Actions or other CI systems using OIDC tokens (no stored secrets), see CI/CD Deployment with OIDC. This page covers a different feature — protecting your app's HTTP routes with single sign-on.

Route protection lets you put single sign-on in front of an application at the routing layer. Unauthenticated requests are redirected to an OIDC identity provider for login, and after authentication, JWT claims are injected as HTTP headers before the request reaches your app.

Your app receives identity information as plain HTTP headers (e.g., X-User-Email) — no in-app auth code required. OIDC is the underlying mechanism, so any standards-compliant identity provider works.

Quick Start

Step 1: Add an identity provider

miren auth provider add my-google \
--provider-url https://accounts.google.com \
--client-id $GOOGLE_CLIENT_ID \
--client-secret $GOOGLE_CLIENT_SECRET \
--scope email --scope profile

Step 2: Protect a route

miren route protect myapp.example.com \
--provider my-google \
--claim-header email:X-User-Email \
--claim-header name:X-User-Name

That's it. Unauthenticated requests to myapp.example.com are now redirected to Google for login. After authentication, your app receives X-User-Email and X-User-Name headers.

Authentication vs Authorization

This feature handles authentication — verifying who a user is — not authorization — deciding what they can access.

After authentication, your app receives claims as headers and decides what to do with them. For example, if you configure Google as your identity provider, your app receives the user's email address and can check the domain for basic access control.

Trust Model

Your app trusts the claim headers (e.g., X-User-Email) because Miren is the only network path into the sandbox — external clients cannot reach your app directly. Miren validates the JWT from the identity provider and sets the headers before proxying the request.

This "trust the proxy" model is the standard approach used by tools like OAuth2 Proxy, Traefik ForwardAuth, and nginx auth_request. It's simple and works well when the platform controls the network topology, which Miren does via sandbox isolation.

Your app does not need to verify signatures or validate tokens — it can treat the claim headers as trusted input from the platform.

How Claim Mappings Work

The --claim-header option maps JWT claims from the identity provider to HTTP headers that your app receives:

miren route protect myapp.example.com \
--provider my-google \
--claim-header email:X-User-Email \
--claim-header sub:X-User-ID \
--claim-header name:X-User-Name
  • Each --claim-header takes the form CLAIM:HEADER
  • Multiple mappings can be specified
  • Claims not present in the JWT are silently skipped
  • Your app receives these as regular request headers

Example Provider Setups

Google

Google's identity provider works well when you want to restrict access by email domain.

miren auth provider add my-google \
--provider-url https://accounts.google.com \
--client-id $GOOGLE_CLIENT_ID \
--client-secret $GOOGLE_CLIENT_SECRET \
--scope email --scope profile

Your app can then check the X-User-Email header's domain for basic authorization (e.g., only allow @yourcompany.com).

GitHub (via federation)

GitHub doesn't expose a native OIDC provider endpoint. To use GitHub for authentication, you'll need a federated OIDC provider like Dex that can use GitHub as an upstream identity source and encode org and team membership as JWT claims.

GitLab

GitLab has a built-in OIDC provider — no federation layer needed. Register an application in your GitLab instance and point directly at it.

miren auth provider add my-gitlab \
--provider-url https://gitlab.com \
--client-id $GITLAB_CLIENT_ID \
--client-secret $GITLAB_CLIENT_SECRET \
--scope email --scope profile

Keycloak (self-hosted)

Keycloak is an open-source identity provider you can run yourself. It supports user federation, identity brokering, and fine-grained claim configuration.

miren auth provider add my-keycloak \
--provider-url https://keycloak.example.com/realms/myrealm \
--client-id $KEYCLOAK_CLIENT_ID \
--client-secret $KEYCLOAK_CLIENT_SECRET \
--scope email --scope profile

Reusing Providers Across Routes

Once you've added a provider, you can use it to protect any number of routes:

miren route protect app1.example.com --provider my-google --claim-header email:X-User-Email
miren route protect app2.example.com --provider my-google --claim-header email:X-User-Email

Default Route Support

route protect and route unprotect support the --default flag for the default route (which has no static hostname). When used with the default route, the OAuth2 redirect URL is derived from the request's Host header at runtime.

miren route protect --default \
--provider my-google \
--claim-header email:X-User-Email

Managing Identity Providers

# List all providers
miren auth provider list

# Show details of a provider
miren auth provider show my-google

# Remove a provider
miren auth provider remove my-google

Removing Route Protection

# Remove protection from a route (provider is preserved for reuse)
miren route unprotect myapp.example.com

# Check route status including protection info
miren route show myapp.example.com

See the CLI reference for the full list of options.