Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support oidc federated authentication #166

Merged
merged 2 commits into from
Jun 20, 2022

Conversation

ekristen
Copy link
Contributor

@ekristen ekristen commented May 31, 2022

Overview

This implements federated authentication via OIDC. This works for Kubernetes Federation along with Generic OIDC issuer.

The client credentials as pointed out by another individual who's name I cannot find (sorry!)

This basically allows for any OIDC issuer that is configured with a service principal to work. Simple pass the JWT token from the OIDC issuer to the auth config instead and enable client federated auth.

Testing

I did not provide tests as I have no way of setting up federated authentication for those test to pass properly for you but I can walk you through the process if interested, there are a couple ways to do this.

Example Code

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/manicminer/hamilton/auth"
	"github.com/manicminer/hamilton/environments"
	"github.com/manicminer/hamilton/msgraph"
	"github.com/manicminer/hamilton/odata"
)

var (
	tenantId = os.Getenv("AZURE_TENANT_ID")
	clientId = os.Getenv("AZURE_CLIENT_ID")
	jwtToken = os.Getenv("AZURE_FEDERATED_TOKEN")
)

func main() {
	ctx := context.Background()

	environment := environments.Global

	authConfig := &auth.Config{
		Environment:               environment,
		TenantID:                  tenantId,
		ClientID:                  clientId,
		FederatedAssertion:        jwtToken,
		EnableClientFederatedAuth: true,
	}

	authorizer, err := authConfig.NewAuthorizer(ctx, environment.MsGraph)
	if err != nil {
		log.Fatal(err)
	}

	client := msgraph.NewUsersClient(tenantId)
	client.BaseClient.Authorizer = authorizer

	users, _, err := client.List(ctx, odata.Query{})
	if err != nil {
		log.Println(err)
		return
	}
	if users == nil {
		log.Println("bad API response, nil result received")
		return
	}
	for _, user := range *users {
		fmt.Printf("%s: %s <%s>\n", *user.ID, *user.DisplayName, *user.UserPrincipalName)
	}
}

@ekristen
Copy link
Contributor Author

ekristen commented Jun 2, 2022

I don't believe the azure-cli-tests failed because of my changes, I suspect since its a fork, it can't use the GitHub Action secrets properly. Let me know if there's anything else I can do.

@ekristen
Copy link
Contributor Author

@manicminer any chance of getting eyes on this? Thanks!

Copy link
Owner

@manicminer manicminer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @ekristen, thanks for proposing this and apologies for the delay in reviewing as I've been periodically out of office.

This looks good, we'll omit the tests for now as it's nontrivial to supply a valid ID token programmatically. We'll lean on the GHA based test for now since it's doing the same thing.

@manicminer manicminer added enhancement New feature or request package/auth labels Jun 20, 2022
@manicminer manicminer added this to the v0.47.0 milestone Jun 20, 2022
@manicminer manicminer merged commit 5b862c1 into manicminer:main Jun 20, 2022
manicminer added a commit that referenced this pull request Jun 20, 2022
@ekristen
Copy link
Contributor Author

Nice! Thanks @manicminer -- going to look at Terraform inclusion next.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request package/auth
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants