Skip to content
Open
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
17 changes: 10 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,17 @@ Apply these on every task in this repo — they keep changes correct, small, and

## Project Overview

**auth0-cli** is the official command-line interface for Auth0 build, manage, and test Auth0 integrations from the terminal.
**auth0-cli** is the official command-line interface for Auth0, used to build, manage, and test Auth0 integrations from the terminal.

- **Language:** Go 1.25.8
- **Tech Stack:** Cobra (commands) + pflag, go-auth0 Management SDK (v1 `management` and v2), Sentry crash reporting, zalando/go-keyring for secret storage, terraform-exec (Terraform export), charmbracelet/glamour (markdown rendering)
- **Package Manager:** Go modules — **vendored** (`vendor/` is committed; run `go mod tidy && go mod vendor` after dependency changes)
- **Minimum Platform Version:** Go 1.25.8 (from `go.mod`)
- **Dependencies:** go-auth0 v1.44.0 + v2.14.0, spf13/cobra 1.10.2, getsentry/sentry-go 0.47.0, zalando/go-keyring 0.2.8 · test: stretchr/testify 1.11.1, golang/mock (gomock) 1.6.0

- **Package Manager:** Go modules (vendored). Run `go mod tidy && go mod vendor` after dependency changes.
- **Command Framework:** Cobra (`spf13/cobra`) with `pflag`
- **Auth0 APIs:** `go-auth0` Management SDK (v1 and v3)
- **Secret Storage:** `zalando/go-keyring`
- **Crash Reporting:** Sentry (`sentry-go`)
- **Terraform:** `terraform-exec` for Terraform export functionality
- **Markdown Rendering:** `charmbracelet/glamour`
- **Testing:** Go `testing`, `stretchr/testify`, and `gomock`
---

## Project Structure
Expand Down Expand Up @@ -136,7 +139,7 @@ See [references/git-workflow.md](references/git-workflow.md) for branch, commit,

## Common Pitfalls

The top one: forgetting `make docs` after a command/flag change fails CI (`make check-docs`). Others involve vendoring, mock regeneration, and the v1/v2 go-auth0 split.
The top one: forgetting `make docs` after a command/flag change fails CI (`make check-docs`). Others involve vendoring, mock regeneration, and the v1/3 go-auth0 split.

See [references/pitfalls.md](references/pitfalls.md) for the full list. Read it when a build/CI step fails unexpectedly.

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/PuerkitoBio/rehttp v1.4.0
github.com/atotto/clipboard v0.1.4
github.com/auth0/go-auth0 v1.45.0
github.com/auth0/go-auth0/v2 v2.14.0
github.com/auth0/go-auth0/v3 v3.2.0
github.com/briandowns/spinner v1.23.2
github.com/charmbracelet/glamour v1.0.0
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/auth0/go-auth0 v1.45.0 h1:fQaNSWpoMneYsutOr+3fTOXIsFAQThSf2A0ShL3oaZg=
github.com/auth0/go-auth0 v1.45.0/go.mod h1:32sQB1uAn+99fJo6N819EniKq8h785p0ag0lMWhiTaE=
github.com/auth0/go-auth0/v2 v2.14.0 h1:zDxwRHGAt6gLK/OG6wAkB5ScQEJ8WW/ex1EnJig8fFc=
github.com/auth0/go-auth0/v2 v2.14.0/go.mod h1:Q/Y3VZVoI3sw87VyTPhx2TQL6Sq4Q/iCP67rW2gcn+M=
github.com/auth0/go-auth0/v3 v3.2.0 h1:/6kg5IXrsJcrWxOtfk8H2FHESeBbYvlFsHFwfLV65/E=
github.com/auth0/go-auth0/v3 v3.2.0/go.mod h1:0a8Yg46Et2wJICZZt5ihpnN/Q53GGiV8fSWkIhEK5x4=
github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0 h1:0NmehRCgyk5rljDQLKUO+cRJCnduDyn11+zGZIc9Z48=
github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0/go.mod h1:6L7zgvqo0idzI7IO8de6ZC051AfXb5ipkIJ7bIA2tGA=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
Expand Down
10 changes: 5 additions & 5 deletions internal/auth0/attack_protection.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import (
"context"

"github.com/auth0/go-auth0/management"
managementv2 "github.com/auth0/go-auth0/v2/management"
"github.com/auth0/go-auth0/v2/management/option"
managementv3 "github.com/auth0/go-auth0/v3/management"
"github.com/auth0/go-auth0/v3/management/option"
)

type AttackProtectionAPI interface {
Expand Down Expand Up @@ -67,18 +67,18 @@ type AttackProtectionAPI interface {
) (err error)
}

type AttackProtectionBotDetectionAPIV2 interface {
type AttackProtectionBotDetectionAPIV3 interface {
// Get the Bot Detection configuration of tenant.
//
// Required scope: `read:attack_protection`
//
// See: https://auth0.com/docs/api/management/v2#!/attack-protection/get-bot-detection
Get(ctx context.Context, opts ...option.RequestOption) (*managementv2.GetBotDetectionSettingsResponseContent, error)
Get(ctx context.Context, opts ...option.RequestOption) (*managementv3.GetBotDetectionSettingsResponseContent, error)

// Update the Bot Detection configuration of tenant.
//
// Required scope: `update:attack_protection`
//
// See: https://auth0.com/docs/api/management/v2#!/attack-protection/patch-bot-detection
Update(ctx context.Context, request *managementv2.UpdateBotDetectionSettingsRequestContent, opts ...option.RequestOption) (*managementv2.UpdateBotDetectionSettingsResponseContent, error)
Update(ctx context.Context, request *managementv3.UpdateBotDetectionSettingsRequestContent, opts ...option.RequestOption) (*managementv3.UpdateBotDetectionSettingsResponseContent, error)
}
12 changes: 6 additions & 6 deletions internal/auth0/auth0.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package auth0
import (
"github.com/auth0/go-auth0"
"github.com/auth0/go-auth0/management"
managementv2 "github.com/auth0/go-auth0/v2/management/client"
managementv3 "github.com/auth0/go-auth0/v3/management/client"
)

// API mimics `management.Management`s general interface, except it refers to
Expand Down Expand Up @@ -77,14 +77,14 @@ func NewAPI(m *management.Management) *API {
}
}

type APIV2 struct {
AttackProtectionBotDetection AttackProtectionBotDetectionAPIV2
Events EventsAPIV2
type APIV3 struct {
AttackProtectionBotDetection AttackProtectionBotDetectionAPIV3
Events EventsAPIV3
PhoneNotificationTemplate PhoneNotificationTemplateAPI
}

func NewAPIV2(m *managementv2.Management) *APIV2 {
return &APIV2{
func NewAPIV3(m *managementv3.Management) *APIV3 {
return &APIV3{
AttackProtectionBotDetection: m.AttackProtection.BotDetection,
Events: m.Events,
PhoneNotificationTemplate: m.Branding.Phone.Templates,
Expand Down
14 changes: 7 additions & 7 deletions internal/auth0/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@ package auth0
import (
"context"

managementv2 "github.com/auth0/go-auth0/v2/management"
"github.com/auth0/go-auth0/v2/management/core"
"github.com/auth0/go-auth0/v2/management/option"
managementv3 "github.com/auth0/go-auth0/v3/management"
"github.com/auth0/go-auth0/v3/management/core"
"github.com/auth0/go-auth0/v3/management/option"
)

// EventsAPIV2 is the V2 SDK interface for the /events endpoint
// EventsAPIV3 is the V3 SDK interface for the /events endpoint
// (Server-Sent Event subscription stream).
type EventsAPIV2 interface {
type EventsAPIV3 interface {
// Subscribe to events via Server-Sent Events (SSE).
//
// Required scope: `read:events`
//
// See: https://auth0.com/docs/api/management/v2/events/get-events
Subscribe(
ctx context.Context,
request *managementv2.SubscribeEventsRequestParameters,
request *managementv3.SubscribeEventsRequestParameters,
opts ...option.RequestOption,
) (*core.Stream[managementv2.EventStreamSubscribeEventsResponseContent], error)
) (*core.Stream[managementv3.EventStreamSubscribeEventsResponseContent], error)
}
4 changes: 2 additions & 2 deletions internal/auth0/mock/phone_notification_template_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions internal/auth0/phone_notification_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ package auth0
import (
"context"

managementv2 "github.com/auth0/go-auth0/v2/management"
"github.com/auth0/go-auth0/v2/management/option"
managementv3 "github.com/auth0/go-auth0/v3/management"
"github.com/auth0/go-auth0/v3/management/option"
)

type PhoneNotificationTemplateAPI interface {
List(ctx context.Context, request *managementv2.ListPhoneTemplatesRequestParameters, opts ...option.RequestOption) (*managementv2.ListPhoneTemplatesResponseContent, error)
List(ctx context.Context, request *managementv3.ListPhoneTemplatesRequestParameters, opts ...option.RequestOption) (*managementv3.ListPhoneTemplatesResponseContent, error)
}
2 changes: 1 addition & 1 deletion internal/cli/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"regexp"
"strings"

"github.com/auth0/go-auth0/v2/management/core"
"github.com/auth0/go-auth0/v3/management/core"
"github.com/spf13/cobra"

"github.com/auth0/auth0-cli/internal/ansi"
Expand Down
24 changes: 12 additions & 12 deletions internal/cli/attack_protection_bot_detection.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package cli
import (
"strings"

managementv2 "github.com/auth0/go-auth0/v2/management"
managementv3 "github.com/auth0/go-auth0/v3/management"
"github.com/spf13/cobra"

"github.com/auth0/auth0-cli/internal/ansi"
Expand Down Expand Up @@ -150,9 +150,9 @@ func updateBotDetectionCmd(cli *cli) *cobra.Command {

func showBotDetectionCmdRun(cli *cli) func(cmd *cobra.Command, args []string) error {
return func(cmd *cobra.Command, args []string) error {
var bd *managementv2.GetBotDetectionSettingsResponseContent
var bd *managementv3.GetBotDetectionSettingsResponseContent
err := ansi.Waiting(func() (err error) {
bd, err = cli.apiv2.AttackProtectionBotDetection.Get(cmd.Context())
bd, err = cli.apiv3.AttackProtectionBotDetection.Get(cmd.Context())
return err
})
if err != nil {
Expand All @@ -167,15 +167,15 @@ func showBotDetectionCmdRun(cli *cli) func(cmd *cobra.Command, args []string) er

func updateBotDetectionCmdRun(cli *cli, inputs *botDetectionInputs) func(cmd *cobra.Command, args []string) error {
return func(cmd *cobra.Command, args []string) error {
var current *managementv2.GetBotDetectionSettingsResponseContent
var current *managementv3.GetBotDetectionSettingsResponseContent
if err := ansi.Waiting(func() (err error) {
current, err = cli.apiv2.AttackProtectionBotDetection.Get(cmd.Context())
current, err = cli.apiv3.AttackProtectionBotDetection.Get(cmd.Context())
return err
}); err != nil {
return err
}

bdUpdate := &managementv2.UpdateBotDetectionSettingsRequestContent{}
bdUpdate := &managementv3.UpdateBotDetectionSettingsRequestContent{}
noLocalFlagSet := noLocalFlagSet(cmd)

// Set bot detection level.
Expand All @@ -186,7 +186,7 @@ func updateBotDetectionCmdRun(cli *cli, inputs *botDetectionInputs) func(cmd *co
if inputs.BotDetectionLevel == "" {
inputs.BotDetectionLevel = string(current.GetBotDetectionLevel())
}
botDetectionLevel, err := managementv2.NewBotDetectionLevelEnumFromString(inputs.BotDetectionLevel)
botDetectionLevel, err := managementv3.NewBotDetectionLevelEnumFromString(inputs.BotDetectionLevel)
if err != nil {
return err
}
Expand All @@ -201,7 +201,7 @@ func updateBotDetectionCmdRun(cli *cli, inputs *botDetectionInputs) func(cmd *co
if inputs.ChallengePasswordPolicy == "" {
inputs.ChallengePasswordPolicy = string(current.GetChallengePasswordPolicy())
}
challengePasswordPolicy, err := managementv2.NewBotDetectionChallengePolicyPasswordFlowEnumFromString(inputs.ChallengePasswordPolicy)
challengePasswordPolicy, err := managementv3.NewBotDetectionChallengePolicyPasswordFlowEnumFromString(inputs.ChallengePasswordPolicy)
if err != nil {
return err
}
Expand All @@ -216,7 +216,7 @@ func updateBotDetectionCmdRun(cli *cli, inputs *botDetectionInputs) func(cmd *co
if inputs.ChallengePasswordlessPolicy == "" {
inputs.ChallengePasswordlessPolicy = string(current.GetChallengePasswordlessPolicy())
}
challengePasswordlessPolicy, err := managementv2.NewBotDetectionChallengePolicyPasswordlessFlowEnumFromString(inputs.ChallengePasswordlessPolicy)
challengePasswordlessPolicy, err := managementv3.NewBotDetectionChallengePolicyPasswordlessFlowEnumFromString(inputs.ChallengePasswordlessPolicy)
if err != nil {
return err
}
Expand All @@ -231,7 +231,7 @@ func updateBotDetectionCmdRun(cli *cli, inputs *botDetectionInputs) func(cmd *co
if inputs.ChallengePasswordResetPolicy == "" {
inputs.ChallengePasswordResetPolicy = string(current.GetChallengePasswordResetPolicy())
}
challengePasswordResetPolicy, err := managementv2.NewBotDetectionChallengePolicyPasswordResetFlowEnumFromString(inputs.ChallengePasswordResetPolicy)
challengePasswordResetPolicy, err := managementv3.NewBotDetectionChallengePolicyPasswordResetFlowEnumFromString(inputs.ChallengePasswordResetPolicy)
if err != nil {
return err
}
Expand All @@ -258,10 +258,10 @@ func updateBotDetectionCmdRun(cli *cli, inputs *botDetectionInputs) func(cmd *co
bdUpdate.SetMonitoringModeEnabled(&inputs.MonitoringModeEnabled)
}

var updatedBD *managementv2.UpdateBotDetectionSettingsResponseContent
var updatedBD *managementv3.UpdateBotDetectionSettingsResponseContent
if err := ansi.Waiting(func() error {
var err error
updatedBD, err = cli.apiv2.AttackProtectionBotDetection.Update(cmd.Context(), bdUpdate)
updatedBD, err = cli.apiv3.AttackProtectionBotDetection.Update(cmd.Context(), bdUpdate)
return err
}); err != nil {
return err
Expand Down
6 changes: 3 additions & 3 deletions internal/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const userAgent = "Auth0 CLI"
type cli struct {
// Core primitives exposed to command builders.
api *auth0.API
apiv2 *auth0.APIV2
apiv3 *auth0.APIV3
renderer *display.Renderer
tracker *analytics.Tracker

Expand Down Expand Up @@ -139,13 +139,13 @@ func (c *cli) setupWithAuthentication(ctx context.Context) error {
return err
}

apiv2, err := initializeManagementClientV2(tenant.Domain, tenant.GetAccessToken())
apiv3, err := initializeManagementClientV3(tenant.Domain, tenant.GetAccessToken())
if err != nil {
return err
}

c.api = auth0.NewAPI(api)
c.apiv2 = auth0.NewAPIV2(apiv2)
c.apiv3 = auth0.NewAPIV3(apiv3)
return nil
}

Expand Down
Loading
Loading