How can a registered App create a new OAuthApp

I am looking for the GitHub API that will allow me to register a new OAuth App.

As a user, I can create a new OAuthApp through the web console[0].

However, for a CICD use case, we are creating short lived apps that use GitHub as an identity provider.

I want to:

  • Register a GitHub App that has privileges to create and delete GitHub OAuth Apps for a given organization.
  • Via the GitHub REST API, create an OAuthApp with a set Name, homepageURL, and oauthCallbackURL.
  • Retrieve the clientId and clientSecret for this new OAuthApp.
  • Use the clientId/clientSecret for a period of time.
  • Destroy the GitHubOAuthApp.

I have introspected the REST API used by the current “New GitHub OAuthApp” web form. I have tried to use a Personal Access Token to experiment with creating a new OAuth App. However, I get a 403.

I was using the go-github REST client, however it does not expose the relevant API.

Alternatively, if I can use the register app flow with a manifest[1] and still use GitHub as an identity provider, that may work for my use case. However, I can’t find a good example of that might work.

Here is a simple example that’s making an HTTP request. I used the personal access token for the authenticityToken but I don’t think that’s what the authentictyToken is really supposed to be.

func main() {
	tokenSource := oauth2.StaticTokenSource(
		&oauth2.Token{AccessToken: personalAccessToken},
	)
	oauthClient := oauth2.NewClient(oauth2.NoContext, tokenSource)

	oauthAPI := "https://github.com/organizations/%s/settings/applications/new?%s"
	queryString := "authenticity_token=%s&oauth_application[name]=%s&oauth_application[url]=%s&oauth_application[description]=%s&oauth_application[callback_url]=%s"

	org := "my-org"
	opts := OAuthAppOptions{AuthenticityToken: personalAccessToken, Name: "test-oauth-name", Description: "test-oauth-desc", HomepageURL: "https://github.com", OAuthCallbackURL: "https://github.com"}

	escapedAPIURL := fmt.Sprintf(oauthAPI, org, url.QueryEscape(fmt.Sprintf(queryString, opts.AuthenticityToken, opts.Name, opts.HomepageURL, opts.Description, opts.OAuthCallbackURL)))
	reqBuf := strings.NewReader(`{}`)
	fmt.Printf("Request: %s\n", escapedAPIURL)
	resp, err := oauthClient.Post(escapedAPIURL, "text/html", reqBuf)
	if err != nil {
		fmt.Errorf("Failed request: %w", err)
		panic(err)
	}
	fmt.Printf("response: %s\n", resp.Status)
}

[0] Creating an OAuth App - GitHub Docs
[1] Creating a GitHub App from a manifest - GitHub Docs

1 Like