Skip to content
This repository has been archived by the owner on Jan 8, 2024. It is now read-only.

Client-side CLI changes for OIDC Auth with HCP #4871

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/4871.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:feature
cli: `login -with-hcp` enables users to login to HCP Waypoint via HCP SSO using the CLI
```
73 changes: 73 additions & 0 deletions internal/cli/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type LoginCommand struct {
flagK8SService string
flagK8STokenSecret string
flagK8SNamespace string
flagHCP bool
}

func (c *LoginCommand) Run(args []string) int {
Expand Down Expand Up @@ -127,6 +128,10 @@ func (c *LoginCommand) Run(args []string) int {
log.Info("login method", "method", "token")
authFunc = c.loginToken

case c.flagHCP:
log.Info("login method", "method", "HCP")
authFunc = c.loginHCP

default:
log.Info("login method", "method", "OIDC")
authFunc = c.loginOIDC
Expand Down Expand Up @@ -229,6 +234,66 @@ func (c *LoginCommand) loginToken(ctx context.Context) (string, int) {
return convertResp.Token, 0
}

func (c *LoginCommand) loginHCP(ctx context.Context) (string, int) {
// Start our callback server
callbackSrv, err := wpoidc.NewCallbackServer()
if err != nil {
c.ui.Output(clierrors.Humanize(err), terminal.WithErrorStyle())
return "", 1
}

// Get the auth URL
authURL, err := c.project.Client().GetOIDCAuthURL(ctx, &pb.GetOIDCAuthURLRequest{
AuthMethod: &pb.Ref_AuthMethod{Name: "HCP"},
RedirectUri: callbackSrv.RedirectUri(),
Nonce: callbackSrv.Nonce(),
})
if err != nil {
c.ui.Output(clierrors.Humanize(err), terminal.WithErrorStyle())
return "", 1
}

// Open the auth URL in the user browser or ask them to visit it.
// We purposely use fmt here and NOT c.ui because the ui will truncate
// our URL (a known bug).
fmt.Printf(strings.TrimSpace(outVisitURL)+"\n\n", authURL.Url)
if err := util.OpenURL(authURL.Url); err != nil {
c.Log.Warn("error opening auth url", "err", err)
}

// Wait
var req *pb.CompleteOIDCAuthRequest
select {
case <-ctx.Done():
// User cancelled
return "", 1

case err := <-callbackSrv.ErrorCh():
c.ui.Output(clierrors.Humanize(err), terminal.WithErrorStyle())
return "", 1

case req = <-callbackSrv.SuccessCh():
// We got our data!
}

// Complete the auth
respToken, err := c.project.Client().CompleteOIDCAuth(ctx, req)
if err != nil {
c.ui.Output(clierrors.Humanize(err), terminal.WithErrorStyle())
return "", 1
}

// Output the claims in the debug log
c.Log.Warn("OIDC authentication complete",
"user_id", respToken.User.Id,
"username", respToken.User.Username,
"id_claims", respToken.IdClaimsJson,
"user_claims", respToken.UserClaimsJson,
)

return respToken.Token, 0
}

func (c *LoginCommand) loginOIDC(ctx context.Context) (string, int) {
// Get our OIDC auth methods
respList, err := c.project.Client().ListOIDCAuthMethods(ctx, &empty.Empty{})
Expand Down Expand Up @@ -467,6 +532,14 @@ func (c *LoginCommand) Flags() *flag.Sets {
Usage: "The name of the Kubernetes namespace that has the Waypoint token " +
"when using the -from-kubernetes flag.",
})

f.BoolVar(&flag.BoolVar{
Name: "from-hcp",
Target: &c.flagHCP,
Usage: "Perform the initial authentication after Waypoint is installed. " +
"This will enable to user to SSO via HCP." +
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
"This will enable to user to SSO via HCP." +
"This will enable to user to SSO via HCP. " +

"This returns a token that lasts for the duration of the SSO session.",
})
})
}

Expand Down
Loading