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
-
Token Generation: The
frpcclient readsAuthOIDCClientConfigfrom its configuration and creates anoauth2/clientcredentials.Config. TheNewOidcAuthSetterfunction inpkg/auth/oidc.go(lines 84-100) callsgenerateAccessTokento fetch a JWT from the IdP's token endpoint. -
Token Attachment: The client attaches the JWT to the
PrivilegeKeyfield ofLogin,Ping, andNewWorkConnmessages viaSetLogin,SetPing, andSetNewWorkConnmethods in the same file. -
Token Verification: The
frpsserver usesAuthOIDCServerConfigto create aTokenVerifierviaNewTokenVerifier(lines 211-222 inpkg/auth/oidc.go). This uses thego-oidclibrary to validate the issuer, audience, and signature against the IdP's JWKS endpoint. -
Session Management: Upon successful verification, the token's subject is stored and reused for subsequent
PingandNewWorkConnverification viaverifyPostLoginToken, 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 = oidcin bothfrpcandfrpsconfigurations. - The client (
frpc) usesAuthOIDCClientConfigto fetch JWTs from your IdP via the token endpoint defined inpkg/auth/oidc.go. - The server (
frps) usesAuthOIDCServerConfigto validate tokens against the issuer and audience usingNewTokenVerifier. - 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
trustedCaFileorproxyURL. - 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →