feat: add proxy auth mode for Atlassian CLIs#411
Conversation
Automated PR ReviewReviewed commit: Summary
go:implementation-tests (1 finding)Minor -
|
| Field | Value |
|---|---|
| Model | claude-sonnet-4-6 |
| Reviewers | go:implementation-tests, policies:conventions, structure:repo-health, documentation:docs |
| Engine | claude_cli · claude-sonnet-4-6 |
| Reviewed by | cr · piekstra-dev |
| Duration | 8m 11s wall · 8m 10s compute |
| Cost | ~$1.04 (est.) |
| Tokens | 26 in / 10.7k out |
Per-workstream usage
| Workstream | Model | In | Out | Cache read | Cache create | Cost | Duration |
|---|---|---|---|---|---|---|---|
| orchestrator-selection | claude-sonnet-4-6 | 4 | 1.6k | 0 | 20.5k | ~$0.10 (est.) | 26s |
| go:implementation-tests | claude-sonnet-4-6 | 6 | 1.1k | 199.9k | 76.7k | ~$0.36 (est.) | 3m 02s |
| policies:conventions | claude-sonnet-4-6 | 4 | 2.8k | 7.2k | 24.2k | ~$0.14 (est.) | 53s |
| structure:repo-health | claude-sonnet-4-6 | 4 | 2.9k | 7.2k | 27.6k | ~$0.15 (est.) | 53s |
| documentation:docs | claude-sonnet-4-6 | 4 | 1.3k | 3.9k | 44.5k | ~$0.19 (est.) | 1m 54s |
| orchestrator-rollup | claude-sonnet-4-6 | 4 | 975 | 24.1k | 20.5k | ~$0.10 (est.) | 59s |
piekstra-dev
left a comment
There was a problem hiding this comment.
Automated PR review completed with outcome: comment.
33ea05b to
ad44044
Compare
|
Hi @piekstra! I've fixed the PR based on the review and rebased. Thanks for taking a look. |
piekstra-dev
left a comment
There was a problem hiding this comment.
Automated PR Review
Reviewed commit: ad44044b06b2
Profile: reviewer - Posting as: piekstra-dev
Summary
Requesting changes because trusted repo-local review guidance could not be loaded from .codereview/agents/ on the PR base branch.
Base branch .codereview/agents/ was not present for this review.
0 PR discussion threads considered. 0 summarized; 0 resolved.
ad44044 to
48422cb
Compare
piekstra-dev
left a comment
There was a problem hiding this comment.
Automated PR Review
Reviewed commit: 48422cba71a0
Profile: reviewer - Posting as: piekstra-dev
Summary
| Reviewer | Findings |
|---|---|
| go:implementation-tests | 0 |
| policies:conventions | 1 |
| structure:repo-health | 1 |
| documentation:docs | 1 |
policies:conventions (1 finding)
Minor - tools/cfl/internal/cmd/init/init.go:23
The bearer-auth (and basic-auth) form validators in
cfl initalways reject an empty API token regardless of--no-verify, while the equivalent jtk validators useif s == "" && !noVerify(initcmd.go:241, 298). jtk'sfinalizeInitalso has an explicitcfg.APIToken == ""branch (initcmd.go:409-410) that emits aset-credentialrecovery hint, acknowledging the deferred-token workflow. cfl has no such branch and its form blocks the workflow entirely.This asymmetry means
jtk init --auth-method bearer --url ... --no-verifyallows saving URL + Cloud ID now and adding the token later viaset-credential, butcfl init --auth-method bearer --url ... --no-verifyforces the user to supply a token at init time. Users who operate both tools will encounter inconsistent behavior for the same auth flow.Fix: add
&& !noVerifyto the bearer and basic token form validators incfl init(mirroring jtk), and add a matchingcfg.APIToken == ""branch incfl finalizeInitthat prints acfl set-credentialrecovery hint so the deferred-token path is documented and tested.
structure:repo-health (1 finding)
Minor - tools/cfl/internal/cmd/init/init.go:23
requireNonInteractiveFieldsis structurally duplicated betweentools/cfl/internal/cmd/init/init.goandtools/jtk/internal/cmd/initcmd/initcmd.go. Both functions encode the same auth-method branching policy (proxy → early return, bearer → require cloud-id, basic → require email + token) and differ only in the tool name embedded in the recovery hint. This is the same entropy pattern that produced thenormalizeAuthConfigduplication fixed in this PR (nowauth.NormalizeConfig). If a fourth auth method is added to one tool, the other silently keeps the old validation shape.Fix: add an exported
auth.RequireNonInteractiveFields(url, authMethod, email, apiToken, cloudID, toolHint string) errortoshared/auth/auth.goalongsideNormalizeConfig, taking the tool-specific credential command as atoolHintparameter for the recovery message. Bothcfl initandjtk initthen call it rather than maintaining parallel copies.
documentation:docs (1 finding)
Minor - tools/cfl/integration-tests.md:593
The Test Execution Checklist preamble (line 593) says "Run the full checklist with separate passes to ensure each auth path works," and the Auth Methods section at the top of the file enumerates three paths (Basic, Bearer, Proxy). However, only Pass 1 (Basic Auth) and Pass 2 (Bearer Auth) checklist blocks are present — there is no Pass 3 for Proxy Auth. A tester following this runbook would not know a proxy-auth pass is required.
The settled inline thread flagged this same gap in
jtk/integration-tests.md, and that file was fixed with a full Pass 3 section (lines 1581–1604).cfl/integration-tests.mdhas the same structural gap and was not updated to match.Fix: add a "Pass 3: Proxy Auth" block to the cfl Test Execution Checklist. At minimum it should mirror the jtk Pass 3 structure: setup steps (
cfl init --auth-method proxy --url <proxy-url> --no-verify,cfl config showto verify auth_method=proxy and email/token absent,cfl space listto confirm the proxy path works), then a full checklist pass over all cfl command sections (all cfl commands have no scope restrictions, so no sections need to be skipped, unlike the jtk bearer pass).
Reviewer Coverage
| Reviewer | Status | Inspected | Skipped | Constraints |
|---|---|---|---|---|
| go:implementation-tests | incomplete_skipped | shared/auth/auth.go, shared/auth/auth_test.go, shared/client/client.go, shared/client/client_test.go, shared/client/options.go, shared/url/url.go, shared/url/url_test.go, tools/cfl/api/client.go, tools/cfl/api/client_test.go, tools/cfl/internal/cmd/init/init.go, tools/cfl/internal/cmd/init/init_test.go, tools/cfl/internal/cmd/root/root.go, tools/cfl/internal/config/config.go, tools/jtk/api/client.go, tools/jtk/api/client_test.go, tools/jtk/internal/cmd/initcmd/initcmd.go, tools/jtk/internal/cmd/initcmd/initcmd_test.go, tools/jtk/internal/cmd/root/root.go | shared/credstore/conndivergence_test.go, shared/credstore/credstore.go, shared/credstore/credstore_test.go, tools/cfl/internal/cmd/root/root_test.go, tools/cfl/internal/config/config_test.go, tools/jtk/internal/cmd/root/root_test.go, tools/jtk/internal/config/config.go, tools/jtk/internal/config/config_test.go | unavailable |
| policies:conventions | complete_broad | shared/auth/auth.go, shared/client/client.go, shared/client/options.go, shared/credstore/credstore.go, tools/cfl/internal/cmd/init/init.go, tools/cfl/internal/cmd/root/root.go, tools/cfl/internal/config/config.go, tools/jtk/internal/cmd/initcmd/initcmd.go, tools/jtk/internal/cmd/root/root.go, tools/jtk/internal/config/config.go | unavailable | Shared CLI standards docs (cli-common/docs) and shared automation (.github) were not available locally; review is based solely on repo-local files and the visible diff context.; tools/cfl/api/client.go (the NewProxyClient implementation) is not in the assigned file list; the settled inline thread about missing loopback safety there could not be independently confirmed from assigned files. |
| structure:repo-health | complete_broad | shared/auth/auth.go, shared/client/client.go, shared/client/options.go, shared/credstore/credstore.go, shared/url/url.go, tools/cfl/api/client.go, tools/cfl/internal/cmd/init/init.go, tools/cfl/internal/cmd/root/root.go, tools/cfl/internal/config/config.go, tools/jtk/api/client.go, tools/jtk/internal/cmd/initcmd/initcmd.go, tools/jtk/internal/cmd/root/root.go, tools/jtk/internal/config/config.go | unavailable | Integration test runbook files (jtk/integration-tests.md, cfl/integration-tests.md) were not in the assigned file list and could not be verified for the proxy auth checklist parity finding raised in the settled thread. |
| documentation:docs | complete_broad | tools/cfl/README.md, tools/cfl/docs/development.md, tools/cfl/integration-tests.md, tools/jtk/README.md, tools/jtk/docs/development.md, tools/jtk/integration-tests.md | unavailable | Review limited to the six assigned changed files; code implementation files were not inspected. |
0 PR discussion threads considered. 0 summarized; 0 resolved.
Completed in 5m 13s | ~$2.37 (est.) | claude-sonnet-4-6 | cr 0.10.243
| Field | Value |
|---|---|
| Model | claude-sonnet-4-6 |
| Reviewers | go:implementation-tests, policies:conventions, structure:repo-health, documentation:docs |
| Engine | claude_cli · claude-sonnet-4-6 |
| Reviewed by | cr · piekstra-dev |
| Duration | 5m 13s wall · 12m 16s compute |
| Cost | ~$2.37 (est.) |
| Tokens | 51 in / 38.9k out |
Per-workstream usage
| Workstream | Model | In | Out | Cache read | Cache create | Cost | Duration |
|---|---|---|---|---|---|---|---|
| orchestrator-selection | claude-sonnet-4-6 | 4 | 2.3k | 28.7k | 29.9k | ~$0.15 (est.) | 50s |
| go:implementation-tests | claude-sonnet-4-6 | 22 | 13.6k | 903.6k | 73.5k | ~$0.75 (est.) | 4m 39s |
| policies:conventions | claude-sonnet-4-6 | 8 | 10.6k | 160.8k | 58.7k | ~$0.43 (est.) | 3m 05s |
| structure:repo-health | claude-sonnet-4-6 | 7 | 6.8k | 127.0k | 73.5k | ~$0.42 (est.) | 1m 52s |
| documentation:docs | claude-sonnet-4-6 | 6 | 4.9k | 131.2k | 90.9k | ~$0.45 (est.) | 1m 22s |
| orchestrator-rollup | claude-sonnet-4-6 | 4 | 688 | 39.3k | 37.6k | ~$0.16 (est.) | 25s |
48422cb to
2895893
Compare
|
@piekstra-dev Follow-up review requested. Feedback from review 4704315391 is addressed in 2895893; all three inline threads have replies and are resolved. Please review the current head. |
piekstra-dev
left a comment
There was a problem hiding this comment.
Automated PR Review
Reviewed commit: 2895893f83e5
Profile: reviewer - Posting as: piekstra-dev
Summary
| Reviewer | Findings |
|---|---|
| go:implementation-tests | 0 |
| structure:repo-health | 0 |
| policies:conventions | 0 |
| documentation:docs | 0 |
Reviewer Coverage
| Reviewer | Status | Inspected | Skipped | Constraints |
|---|---|---|---|---|
| go:implementation-tests | incomplete_skipped | shared/auth/auth.go, shared/auth/auth_test.go, shared/client/client.go, shared/client/client_test.go, shared/client/options.go, shared/credstore/credstore.go, shared/url/url.go, tools/cfl/api/client.go, tools/cfl/api/client_test.go, tools/cfl/internal/cmd/init/init.go, tools/cfl/internal/cmd/root/root.go, tools/cfl/internal/config/config.go, tools/jtk/api/client.go, tools/jtk/internal/cmd/initcmd/initcmd.go, tools/jtk/internal/config/config.go | shared/credstore/conndivergence_test.go, shared/credstore/credstore_test.go, shared/url/url_test.go, tools/cfl/internal/cmd/init/finalize_test.go, tools/cfl/internal/cmd/init/init_test.go, tools/cfl/internal/cmd/root/root_test.go, tools/cfl/internal/config/config_test.go, tools/jtk/api/client_test.go, tools/jtk/internal/cmd/initcmd/initcmd_test.go, tools/jtk/internal/cmd/root/root.go, tools/jtk/internal/cmd/root/root_test.go, tools/jtk/internal/config/config_test.go | Did not run go test ./...; correctness of proxy-auth behavior was verified by reading implementation and test source, not by executing the suite.; Reviewed against the checked-out repo snapshot in the workbench rather than a raw diff; git history/blame was not consulted, so severity judgments rely on reading final file contents plus the PR dossier's discussion thread rather than confirming exact line-level diff hunks. |
| structure:repo-health | complete_broad | shared/auth/auth.go, shared/client/client.go, shared/client/options.go, shared/credstore/credstore.go, shared/url/url.go, tools/cfl/api/client.go, tools/cfl/internal/cmd/init/init.go, tools/cfl/internal/cmd/root/root.go, tools/cfl/internal/config/config.go, tools/jtk/api/client.go, tools/jtk/internal/cmd/initcmd/initcmd.go, tools/jtk/internal/cmd/root/root.go, tools/jtk/internal/config/config.go | unavailable | unavailable |
| policies:conventions | complete_broad | tools/cfl/README.md, tools/cfl/internal/cmd/init/init.go, tools/cfl/internal/cmd/root/root.go, tools/cfl/internal/config/config.go, tools/jtk/README.md, tools/jtk/internal/cmd/initcmd/initcmd.go, tools/jtk/internal/cmd/root/root.go, tools/jtk/internal/config/config.go | unavailable | Shared cli-common conventions docs were not present in the provided review context, so this review relies on cross-tool (cfl vs jtk) consistency and the diff/dossier discussion rather than the canonical standards text.; tools/cfl/api/client.go and tools/jtk/api/client.go (where the loopback-HTTP proxy guard and gateway base URL override live) are not in the assigned file set and were not inspected; the previously-discussed NewProxyClient asymmetry lives there, not in the assigned config/root/init files. |
| documentation:docs | complete_broad | tools/cfl/README.md, tools/cfl/docs/development.md, tools/cfl/integration-tests.md, tools/jtk/README.md, tools/jtk/docs/development.md, tools/jtk/integration-tests.md | unavailable | unavailable |
0 PR discussion threads considered. 0 summarized; 0 resolved.
Completed in 4m 59s | unavailable | claude-sonnet-5 | cr 0.10.259
| Field | Value |
|---|---|
| Model | claude-sonnet-5 |
| Reviewers | go:implementation-tests, structure:repo-health, policies:conventions, documentation:docs |
| Engine | claude_cli · claude-sonnet-5 |
| Reviewed by | cr · piekstra-dev |
| Duration | 4m 59s wall · 8m 32s compute |
| Cost | unavailable |
| Tokens | unavailable |
Per-workstream usage
| Workstream | Model | In | Out | Cache read | Cache create | Cost | Duration |
|---|---|---|---|---|---|---|---|
| orchestrator-selection | claude-sonnet-5 | unavailable | unavailable | unavailable | unavailable | unavailable | 29s |
| go:implementation-tests | claude-sonnet-5 | unavailable | unavailable | unavailable | unavailable | unavailable | 2m 33s |
| structure:repo-health | claude-sonnet-5 | unavailable | unavailable | unavailable | unavailable | unavailable | 1m 34s |
| policies:conventions | claude-sonnet-5 | unavailable | unavailable | unavailable | unavailable | unavailable | 2m 03s |
| documentation:docs | claude-sonnet-5 | unavailable | unavailable | unavailable | unavailable | unavailable | 1m 39s |
| orchestrator-rollup | claude-sonnet-5 | unavailable | unavailable | unavailable | unavailable | unavailable | 11s |
Summary
proxyas a supported auth method forjtkandcflAuthorizationheader in proxy mode and require only a URLhttp://proxy URLs while continuing to reject arbitrary cleartext URLsWhy
Some users run Atlassian CLI tools through a trusted local or managed proxy that handles upstream authentication. The existing
basicandbearermodes require the CLI to own credentials and emit an auth header, which makes those proxy setups difficult or impossible to configure cleanly.Implementation Notes
Proxy auth is explicit via
ATLASSIAN_AUTH_METHOD=proxy,JIRA_AUTH_METHOD=proxy, orCFL_AUTH_METHOD=proxy. In this mode, the CLI constructs normal Jira or Confluence API URLs but deliberately omitsAuthorization. HTTPS proxy URLs are accepted, andhttp://is limited to loopback hosts for local proxy workflows.Bearer auth keeps existing behavior by default and adds
ATLASSIAN_GATEWAY_BASE_URL,JIRA_GATEWAY_BASE_URL, andCFL_GATEWAY_BASE_URLfor environments that need to override the Atlassian gateway base.Tests
go test ./...insharedgo test ./...intools/jtkgo test ./...intools/cfl