How to Configure OIDC Authentication with frp for Single Sign-On

To configure OIDC authentication with frp, set auth.method = oidc in both the client (frpc) and server (frps) configurations, populate the [auth.oidc] section with your identity provider endpoints and credentials, and ensure the audience values match between both sides.

The frp (Fast Reverse Proxy) project supports OpenID Connect (OIDC) to enable single sign-on (SSO) for secure tunnel authentication. When you configure OIDC authentication with frp, you replace static privilege tokens with short-lived JWTs issued by any OIDC-compliant identity provider, centralizing access control and improving security posture over long-lived credentials.

How OIDC Authentication Works in frp

The implementation in pkg/auth/oidc.go establishes a token-based flow where the client obtains a JWT from your IdP and the server validates it on every connection.

The Authentication Flow

  1. Token Generation: The frpc client reads AuthOIDCClientConfig from its configuration and creates an oauth2/clientcredentials.Config. The NewOidcAuthSetter function in pkg/auth/oidc.go (lines 84-100) calls generateAccessToken to fetch a JWT from the IdP's token endpoint.

  2. Token Attachment: The client attaches the JWT to the PrivilegeKey field of Login, Ping, and NewWorkConn messages via SetLogin, SetPing, and SetNewWorkConn methods in the same file.

  3. Token Verification: The frps server uses AuthOIDCServerConfig to create a TokenVerifier via NewTokenVerifier (lines 211-222 in pkg/auth/oidc.go). This uses the go-oidc library to validate the issuer, audience, and signature against the IdP's JWKS endpoint.

  4. Session Management: Upon successful verification, the token's subject is stored and reused for subsequent Ping and NewWorkConn verification via verifyPostLoginToken, ensuring continuous authentication without re-fetching tokens.

Server Configuration (frps)

Configure the frps server to validate OIDC tokens by setting auth.method = oidc and defining the [auth.oidc] section.


# frps.ini

[common]
bindPort = 7000

[auth]
method = "oidc"
additionalScopes = ["HeartBeats", "NewWorkConns"]

[auth.oidc]
issuer = "https://accounts.google.com"
audience = "my-frp-client-id"
skipExpiryCheck = false
skipIssuerCheck = false

The server unmarshals this into AuthOIDCServerConfig defined in pkg/config/v1/server.go (lines 28-45). Validation logic in pkg/config/v1/validation/server.go ensures that OIDC parameters are mutually exclusive with other authentication methods.

Client Configuration (frpc)

The frpc client must obtain tokens from your IdP using the client credentials flow.


# frpc.ini

[common]
serverAddr = "my-frp.example.com"
serverPort = 7000

[auth]
method = "oidc"
additionalScopes = ["HeartBeats"]

[auth.oidc]
clientID = "my-frp-client-id"
clientSecret = "MY_CLIENT_SECRET"
audience = "my-frp-client-id"
scope = "openid profile email"
tokenEndpointURL = "https://oauth2.googleapis.com/token"

# Optional: TLS and proxy settings for token requests

trustedCaFile = "/etc/ssl/certs/ca-certificates.crt"
insecureSkipVerify = false
proxyURL = "http://proxy:3128"

This configuration maps to AuthOIDCClientConfig in pkg/config/v1/client.go (lines 196-236). The createOIDCHTTPClient function in pkg/auth/oidc.go (lines 35-73) handles custom TLS and proxy settings for the token endpoint connection. Validation in pkg/config/v1/validation/client.go (lines 88-104) checks for configuration conflicts.

Programmatic Implementation

If embedding frp as a library, you can instantiate the OIDC authenticator directly:

import (
    "github.com/fatedier/frp/pkg/auth"
    v1 "github.com/fatedier/frp/pkg/config/v1"
    "github.com/fatedier/frp/pkg/msg"
)

// Client-side token generation
clientCfg := v1.AuthOIDCClientConfig{
    ClientID:         "my-frp-client-id",
    ClientSecret:     "MY_CLIENT_SECRET",
    TokenEndpointURL: "https://oauth2.googleapis.com/token",
    Scope:            "openid profile email",
    Audience:         "my-frp-client-id",
}

setter, err := auth.NewOidcAuthSetter([]v1.AuthScope{v1.AuthScopeHeartBeats}, clientCfg)
if err != nil {
    panic(err)
}

login := &msg.Login{}
if err := setter.SetLogin(login); err != nil {
    panic(err)
}
// login.PrivilegeKey now contains the JWT

// Server-side token verification
serverCfg := v1.AuthOIDCServerConfig{
    Issuer:   "https://accounts.google.com",
    Audience: "my-frp-client-id",
}

verifier := auth.NewTokenVerifier(serverCfg)
consumer := auth.NewOidcAuthVerifier(nil, verifier)

if err := consumer.VerifyLogin(login); err != nil {
    // Reject connection: invalid token
}

This mirrors the internal implementation used by cmd/frpc/main.go and cmd/frps/main.go.

Key Source Files

File Purpose
pkg/auth/oidc.go Core OIDC logic: NewOidcAuthSetter, generateAccessToken, NewTokenVerifier, and OidcAuthConsumer
pkg/config/v1/server.go AuthOIDCServerConfig struct definition (lines 28-45)
pkg/config/v1/client.go AuthOIDCClientConfig struct definition (lines 196-236)
pkg/config/v1/validation/server.go Server-side OIDC configuration validation
pkg/config/v1/validation/client.go Client-side OIDC validation (lines 88-104)
cmd/frps/main.go Server entry point
cmd/frpc/main.go Client entry point

Summary

  • Configure OIDC authentication with frp by setting auth.method = oidc in both frpc and frps configurations.
  • The client (frpc) uses AuthOIDCClientConfig to fetch JWTs from your IdP via the token endpoint defined in pkg/auth/oidc.go.
  • The server (frps) uses AuthOIDCServerConfig to validate tokens against the issuer and audience using NewTokenVerifier.
  • Ensure audience values match between client and server, or omit the audience check on the server for testing.
  • Configure optional TLS or proxy settings in the client for corporate environments using trustedCaFile or proxyURL.
  • Validation logic in pkg/config/v1/validation/ prevents configuration conflicts before startup.

Frequently Asked Questions

What identity providers work with frp OIDC authentication?

Any OIDC-compliant identity provider works with frp, including Google Workspace, Azure Active Directory, Keycloak, Okta, Auth0, and AWS Cognito. The issuer URL in frps.ini must match the IdP's discovery document endpoint, and the tokenEndpointURL in frpc.ini must point to the provider's OAuth2 token endpoint.

How do I troubleshoot OIDC token validation failures in frps?

Check the frps logs for verification errors from NewTokenVerifier in pkg/auth/oidc.go. Common issues include clock skew between the server and IdP (enable skipExpiryCheck temporarily to test), mismatched audience values between client and server, or incorrect issuer URLs. Ensure the IdP's JWKS endpoint is reachable from the frps host for signature verification.

Can I use OIDC authentication with frp's built-in dashboard?

Yes, OIDC authentication applies to the control plane connection between frpc and frps, which secures the tunnel establishment. However, the frp dashboard (if enabled) uses separate authentication mechanisms. You should run the dashboard behind a reverse proxy that handles OIDC authentication for web access, while using the native OIDC support for client-server tunnel authentication.

Is OIDC more secure than static token authentication in frp?

Yes, OIDC is significantly more secure than static token authentication because tokens are short-lived and automatically rotated. The generateAccessToken function in pkg/auth/oidc.go obtains tokens with limited lifetime from your IdP, whereas static tokens remain valid until manually revoked. Additionally, OIDC enables centralized authentication policy enforcement through your identity provider, supporting multi-factor authentication and conditional access policies.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →