Skip to content

feat(plugins): add auth0 plugin commands - #1730

Open
developerkunal wants to merge 1 commit into
DXCDT-2607/consent-approvalsfrom
DXCDT-2604/plugin-commands
Open

developerkunal wants to merge 1 commit into
DXCDT-2607/consent-approvalsfrom
DXCDT-2604/plugin-commands

Conversation

@developerkunal

@developerkunal developerkunal commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

🔧 Changes

Adds the auth0 plugin command group (alias plugins) with search, list, info, install, update, uninstall (alias remove) and approve, wired to the registry client, plugin store and approvals from the PRs below. The group is experimental and only registered in dev and prerelease builds, so a stable build is unchanged, and a new skipDocs annotation keeps it out of the generated docs. Running a plugin comes in a later PR.

Commands

  • search [query] matches plugin IDs and descriptions. list shows installed plugins with version, pin and disk size. Both support --json, --json-compact and --csv.
  • info <plugin> shows the owner, permissions, versions and the tenants where it is approved.
  • install <plugin> installs from the signed registry, and an exact version pins it. In a terminal it shows the permissions and approves them for the tenant if the person agrees. Without a terminal, with --no-input, or in agent mode, it installs without an approval and prints the auth0 plugin approve command.
  • update [plugin] or update --all skips pinned plugins. When the new version asks for other permissions and nobody can approve them, the installed version stays active and the command says why.
  • uninstall <plugin> removes every version and the approvals, and asks for confirmation unless --force is set. It refuses to run unconfirmed in agent mode.
  • approve <plugin> approves the installed copy's permissions for a tenant. It needs a terminal and refuses in agent mode and with --no-input.

Behaviour a reviewer should know

  • Only a person approves. CI can pin approvals with AUTH0_CLI_PLUGIN_APPROVALS.
  • AUTH0_CLI_PLUGINS_DISABLED turns off install, update and approve. Plugin commands do not require a login.
  • install and update fail if the registry index could not be refreshed. install refuses a plugin name that would shadow an existing command or alias.
  • The approval tenant comes from --tenant, then AUTH0_DOMAIN in env auth mode, then the default tenant. A --tenant that contradicts AUTH0_DOMAIN is an error.

📚 References

DXCDT-2604. Part of the plugin framework stack of 11 PRs, and it builds on the one below it (DXCDT-2607).

🔬 Testing

The new code is covered by unit tests.

📝 Checklist

  • All new/changed/fixed functionality is covered by tests (or N/A)
  • I have added documentation for all new/changed functionality (or N/A)

@developerkunal
developerkunal requested a review from a team as a code owner October 24, 2026 14:47
@developerkunal
developerkunal force-pushed the DXCDT-2604/plugin-commands branch from 16481a3 to a70abd8 Compare October 24, 2026 15:30
@developerkunal
developerkunal force-pushed the DXCDT-2604/plugin-commands branch from a70abd8 to e56cdaf Compare November 2, 2026 11:12
@developerkunal
developerkunal force-pushed the DXCDT-2604/plugin-commands branch from e56cdaf to 28a2e06 Compare November 2, 2026 14:31
Add search, list, info, install, update, uninstall and approve behind a
version gate (dev and prerelease builds only). Consent is asked per
tenant at a terminal; non-interactive installs print the approve
command. Docs are not generated while the feature is gated.
@developerkunal
developerkunal force-pushed the DXCDT-2604/plugin-commands branch from 28a2e06 to c3d8061 Compare November 2, 2026 19:35
_, _ = w.Write(answer.body[:len(answer.body)/2])
panic(http.ErrAbortHandler)
default:
_, _ = w.Write(answer.body)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 High severity blocking issue identified in your code:
Untrusted input could be used to tamper with a web page rendering, which can lead to a Cross-site scripting (XSS) vulnerability. XSS vulnerabilities occur when untrusted input executes malicious JavaScript code, leading to issues such as account compromise and sensitive information leakage. To prevent this vulnerability, validate the user input, perform contextual output encoding or sanitize the input. For more information, see: [Go XSS prevention] (https://semgrep.dev/docs/cheat-sheets/go-xss/).

Why this might be safe to ignore:

The URL path is used only as a lookup key to retrieve a pre-configured route response body; the answer.body written to the response is server-controlled data, not user-supplied content derived from the request path. Additionally, this is a test helper file, making exploitation even less likely.

Dataflow graph
flowchart LR
    classDef invis fill:white, stroke: none
    classDef default fill:#e7f5ff, color:#1c7fd6, stroke: none

    subgraph File0["<b>internal/plugins/registry/registrytest/server.go</b>"]
        direction LR
        %% Source

        subgraph Source
            direction LR

            v0["<a href=https://github.com/auth0/auth0-cli/blob/c3d80617c43dfe7d435d8840333a57f2051ef9c2/internal/plugins/registry/registrytest/server.go#L166 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 166] r.URL</a>"]
        end
        %% Intermediate

        subgraph Traces0[Traces]
            direction TB

            v2["<a href=https://github.com/auth0/auth0-cli/blob/c3d80617c43dfe7d435d8840333a57f2051ef9c2/internal/plugins/registry/registrytest/server.go#L166 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 166] path</a>"]

            v3["<a href=https://github.com/auth0/auth0-cli/blob/c3d80617c43dfe7d435d8840333a57f2051ef9c2/internal/plugins/registry/registrytest/server.go#L181 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 181] answer</a>"]
        end
            v2 --> v3
        %% Sink

        subgraph Sink
            direction LR

            v1["<a href=https://github.com/auth0/auth0-cli/blob/c3d80617c43dfe7d435d8840333a57f2051ef9c2/internal/plugins/registry/registrytest/server.go#L196 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 196] w.Write(answer.body)</a>"]
        end
    end
    %% Class Assignment
    Source:::invis
    Sink:::invis

    Traces0:::invis
    File0:::invis

    %% Connections

    Source --> Traces0
    Traces0 --> Sink


Loading

To resolve this comment:

🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.

💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by no-direct-write-to-responsewriter-taint.

You can view more details about this finding in the Semgrep AppSec Platform.

}

w.WriteHeader(response.status)
_, _ = w.Write(body)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 High severity blocking issue identified in your code:
Untrusted input could be used to tamper with a web page rendering, which can lead to a Cross-site scripting (XSS) vulnerability. XSS vulnerabilities occur when untrusted input executes malicious JavaScript code, leading to issues such as account compromise and sensitive information leakage. To prevent this vulnerability, validate the user input, perform contextual output encoding or sanitize the input. For more information, see: [Go XSS prevention] (https://semgrep.dev/docs/cheat-sheets/go-xss/).

Why this might be safe to ignore:

The data written to the response (cleaned) is the upstream API's JSON response body processed through stripSecrets, not a direct reflection of user-supplied input. The proxy reads the request body, forwards it to an upstream service, validates the response is JSON, strips secrets, and returns that - the taint tracking conflates the request body source with the upstream response data flowing to the sink.

Dataflow graph
flowchart LR
    classDef invis fill:white, stroke: none
    classDef default fill:#e7f5ff, color:#1c7fd6, stroke: none

    subgraph File0["<b>internal/plugins/proxy/proxy.go</b>"]
        direction LR
        %% Source

        subgraph Source
            direction LR

            v0["<a href=https://github.com/auth0/auth0-cli/blob/c3d80617c43dfe7d435d8840333a57f2051ef9c2/internal/plugins/proxy/proxy.go#L489 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 489] r.Body</a>"]
        end
        %% Intermediate

        subgraph Traces0[Traces]
            direction TB

            v2["<a href=https://github.com/auth0/auth0-cli/blob/c3d80617c43dfe7d435d8840333a57f2051ef9c2/internal/plugins/proxy/proxy.go#L489 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 489] body</a>"]

            v3["<a href=https://github.com/auth0/auth0-cli/blob/c3d80617c43dfe7d435d8840333a57f2051ef9c2/internal/plugins/proxy/proxy.go#L447 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 447] readRequestBody</a>"]

            v4["<a href=https://github.com/auth0/auth0-cli/blob/c3d80617c43dfe7d435d8840333a57f2051ef9c2/internal/plugins/proxy/proxy.go#L447 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 447] body</a>"]

            v5["<a href=https://github.com/auth0/auth0-cli/blob/c3d80617c43dfe7d435d8840333a57f2051ef9c2/internal/plugins/proxy/proxy.go#L454 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 454] {</a>"]

            v6["<a href=https://github.com/auth0/auth0-cli/blob/c3d80617c43dfe7d435d8840333a57f2051ef9c2/internal/plugins/proxy/proxy.go#L454 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 454] request</a>"]

            v7["<a href=https://github.com/auth0/auth0-cli/blob/c3d80617c43dfe7d435d8840333a57f2051ef9c2/internal/plugins/proxy/proxy.go#L462 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 462] response</a>"]

            v8["<a href=https://github.com/auth0/auth0-cli/blob/c3d80617c43dfe7d435d8840333a57f2051ef9c2/internal/plugins/proxy/proxy.go#L473 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 473] cleaned</a>"]

            v9["<a href=https://github.com/auth0/auth0-cli/blob/c3d80617c43dfe7d435d8840333a57f2051ef9c2/internal/plugins/proxy/proxy.go#L480 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 480] writeResponse</a>"]

            v10["<a href=https://github.com/auth0/auth0-cli/blob/c3d80617c43dfe7d435d8840333a57f2051ef9c2/internal/plugins/proxy/proxy.go#L663 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 663] body</a>"]
        end
            v2 --> v3
            v3 --> v4
            v4 --> v5
            v5 --> v6
            v6 --> v7
            v7 --> v8
            v8 --> v9
            v9 --> v10
        %% Sink

        subgraph Sink
            direction LR

            v1["<a href=https://github.com/auth0/auth0-cli/blob/c3d80617c43dfe7d435d8840333a57f2051ef9c2/internal/plugins/proxy/proxy.go#L684 target=_blank style='text-decoration:none; color:#1c7fd6'>[Line: 684] w.Write(body)</a>"]
        end
    end
    %% Class Assignment
    Source:::invis
    Sink:::invis

    Traces0:::invis
    File0:::invis

    %% Connections

    Source --> Traces0
    Traces0 --> Sink


Loading

To resolve this comment:

🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.

💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by no-direct-write-to-responsewriter-taint.

You can view more details about this finding in the Semgrep AppSec Platform.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant