go-oidc

repository·v3·Indexed 25 days ago

https://github.com/coreos/go-oidc

A provider-agnostic OpenID Connect client for Go that extends the golang.org/x/oauth2 package. It supports identity verification for providers such as Google, Microsoft, Okta, and workload identity providers like GitHub Actions and Kubernetes. The library provides functionality for provider discovery via oidc.NewProvider, ID Token verification and parsing, and implementation of RP-Initiated Logout.

Tokens
2.4K
Snippets
7
Records
8
Agent score
82%

What's inside go-oidc

  1. Run the ID Token example application

    v3

    After configuring your Google OAuth2 credentials, you can run the ID Token example application using the Go tool. Once running, access the application by navigating to http://127.0.0.1:5556 in your browser.

    go run ./example/idtoken/app.go
  2. Run the Logout example app with Auth0

    v3

    The logout example app demonstrates how to implement RP-Initiated Logout using an Auth0 provider. To run this example, you must have an Auth0 developer instance and an internet-accessible endpoint (using tools like Tailscale Funnel or Cloudflare Tunnel) to receive the logout callback.

    1. Configure Auth0 Application

    In your Auth0 application settings, you must configure the following:

    • Allowed Callback URLs: ${BASE_URL}/callback
    • Back-Channel Logout URI: ${BASE_URL}/logout

    Note: ${BASE_URL} is the public DNS name used to advertise your local endpoint.

    2. Set Environment Variables and Run

    Set your Auth0 credentials as environment variables and execute the application using the --base-url and --issuer-url flags.

    export CLIENT_ID="{AUTH0_CLIENT_ID}"
    export CLIENT_SECRET="{AUTH0_CLIENT_SECRET}"
    go run ./example/logout/app.go \
        --base-url="${BASE_URL}" \
        --issuer-url="${AUTH0_ISSUER_URL}"
  3. Set up Google OAuth2 credentials for examples

    v3

    To run the provided examples, you must register an OAuth2 application in the Google Developer Console and configure your environment.

    1. Visit the Google Developer Console.
    2. Navigate to Credentials in the left column.
    3. Click Create credentials and select OAuth client ID.
    4. Choose Web application as the application type.
    5. Add http://127.0.0.1:5556/auth/google/callback to the Authorized redirect URIs list.
    6. Once created, set the following environment variables with your new Client ID and Client Secret:
  4. Verify and parse ID Tokens

    v3

    After exchanging an authorization code for a token, you must extract the id_token from the OAuth2 token's extra fields. Use the idTokenVerifier (created via provider.Verifier) to validate the token's signature and claims. Finally, use the Claims method to unmarshal the JWT payload into a custom struct.

    ```go
    // Create an ID Token verifier.
    idTokenVerifier := provider.Verifier(&oidc.Config{ClientID: clientID})
    
    // ... inside callback handler ...
    
    // Extract the ID Token from OAuth2 token.
    rawIDToken, ok := oauth2Token.Extra("id_token").(string)
    if !ok {
        // handle missing token
    }
    
    // Parse and verify ID Token payload.
    idToken, err := idTokenVerifier.Verify(ctx, rawIDToken)
    if err != nil {
        // handle error
    }
    
    // Extract custom claims
    var claims struct {
        Email         string `json:
  5. Verify RP-Initiated Logout via Logout Token

    v3

    When performing RP-Initiated Logout, the application receives a logout token via a POST request to the configured logout endpoint. The application validates this token and logs its contents. A successful validation will output a JSON structure containing the following fields:

    • Issuer: The OIDC provider's issuer URL.
    • Subject: The unique identifier for the user.
    • Audience: An array containing the client ID.
    • IssuedAt: The timestamp when the token was issued.
    • Expiry: The expiration timestamp of the token.
    • SessionID: The unique identifier for the session.
    2026/06/17 13:06:39 Logout token: {
      "Issuer": "${AUTH0_ISSUER_URL}",
      "Subject": "1234",
      "Audience": [
        "${CLIENT_ID}"
      ],
      "IssuedAt": "2026-06-17T13:06:39-07:00",
      "Expiry": "2026-06-17T13:08:39-07:00",
      "SessionID": "Kaeo_qJ9zFDcWI9g_fNVa24rv7uu1gpV"
    }
  6. Complete OpenID Connect authentication flow example

    v3

    This example demonstrates the full lifecycle: initializing the provider, configuring the OAuth2 client, handling the initial redirect, and processing the callback to verify the ID Token and extract claims.

    provider, err := oidc.NewProvider(ctx, "https://accounts.google.com")
    if err != nil {
        // handle error
    }
    
    // Configure an OpenID Connect aware OAuth2 client.
    oauth2Config := oauth2.Config{
        ClientID:     clientID,
        ClientSecret: clientSecret,
        RedirectURL:  redirectURL,
    
        // Discovery returns the OAuth2 endpoints.
        Endpoint: provider.Endpoint(),
    
        // "openid" is a required scope for OpenID Connect flows.
        Scopes: []string{oidc.ScopeOpenID, oidc.ScopeProfile, oidc.ScopeEmail},
    }
    
    // Create an ID Token verifier.
    idTokenVerifier := provider.Verifier(&oidc.Config{ClientID: clientID})
    
    func handleRedirect(w http.ResponseWriter, r *http.Request) {
        http.Redirect(w, r, oauth2Config.AuthCodeURL(state), http.StatusFound)
    }
    
    func handleOAuth2Callback(w http.ResponseWriter, r *http.Request) {
        // Verify state and errors.
    
        oauth2Token, err := oauth2Config.Exchange(ctx, r.URL.Query().Get("code"))
        if err != nil {
            // handle error
        }
    
        // Extract the ID Token from OAuth2 token.
        rawIDToken, ok := oauth2Token.Extra("id_token").(string)
        if !ok {
            // handle missing token
        }
    
        // Parse and verify ID Token payload.
        idToken, err := idTokenVerifier.Verify(ctx, rawIDToken)
        if err != nil {
            // handle error
        }
    
        // Extract custom claims
        var claims struct {
            Email         string `json:"email"`
            EmailVerified bool   `json:"email_verified"`
            Name          string `json:"name"`
            Picture       string `json:"picture"`
        }
        if err := idToken.Claims(&claims); err != nil {
            // handle error
        }
    }
  7. Configure an OpenID Connect aware OAuth2 client

    v3

    Once you have a provider, you can configure a standard golang.org/x/oauth2.Config. Use provider.Endpoint() to populate the Endpoint field and ensure you include oidc.ScopeOpenID in your Scopes to enable OpenID Connect flows.

    // Configure an OpenID Connect aware OAuth2 client.
    oauth2Config := oauth2.Config{
        ClientID:     clientID,
        ClientSecret: clientSecret,
        RedirectURL:  redirectURL,
    
        // Discovery returns the OAuth2 endpoints.
        Endpoint: provider.Endpoint(),
    
        // "openid" is a required scope for OpenID Connect flows.
        Scopes: []string{oidc.ScopeOpenID, oidc.ScopeProfile, oidc.ScopeEmail},
    }
  8. Initialize an OpenID Connect provider with discovery

    v3

    To use go-oidc, you first initialize a provider using oidc.NewProvider. This uses OpenID Connect discovery to automatically retrieve the necessary OAuth2 endpoints from the issuer URL (e.g., https://accounts.google.com).

    provider, err := oidc.NewProvider(ctx, "https://accounts.google.com")
    if err != nil {
        // handle error
    }