Skip to main content

Exchange an Authorization Code for an ID Token


When OIDC is enabled, the server will return an additional ID Token alongside the Access Token. Some IMS services require this ID Token instead of the Access Token due to downstream dependencies (for example GKE only supports OIDC and ID Token access to kubernetes clusters). To enable OIDC you should specify the Scopes field as openid when exchanging tokens and generating Authorization Codes.

package main

import (


const (
ClientID = "client-id"
ClientSecret = "client-secret"
RedirectUrl = "http://localhost:8080/redirect"

// The Authorization Code should have already been retrieved from the IMS
// Platform Auth service. See the "Generating an Authorization Code" code
// sample on how to get an AuthorizationCode.
AuthorizationCode = "authorization-code"

func main() {
// First we set up our OAuth2 configuration.
// We include the ClientID and ClientSecret from our OAuth Client, we
// specify the Authorize and Token URLs, and we set up the redirect URL.
// The values for these fields are set up when you create the OAuth Client
// or are provided in the documentation.
// Finally, we specify the Scopes we want to return. The Scopes specified
// here mean we operate in OIDC mode and return an ID Token. For more
// information on what this means please view the IMS Permissions and Scopes
// guide.
config := oauth2.Config{
ClientID: ClientID,
ClientSecret: ClientSecret,
Endpoint: oauth2.Endpoint{
AuthURL: "",
TokenURL: "",
RedirectURL: RedirectUrl,
Scopes: []string{"openid"},

token, err := config.Exchange(context.Background(), AuthorizationCode)
if err != nil {
log.Fatalf("could not exchange Authorization Code: %v", err)

log.Printf("Access Token: %s", token.AccessToken)
log.Printf("Expires: %s", token.Expiry.String())

idToken := token.Extra("id_token").(string)
log.Printf("ID Token: %s", idToken)