Connecting to Confluence today requires minting an Atlassian API token by hand in account settings and pasting it into Connect-Confluence -Token. That works, but it is a manual, out-of-band step, the token is long-lived, and there is no guided interactive path — which raises the barrier to first use and encourages long-lived secrets on disk.
Atlassian's own CLI (acli) offers acli jira auth login --web: the browser opens, the user consents, and the session is established with no token handling. Atlassian's Rovo Dev CLI/MCP behaves the same way. Both can do this because they are first-party tools backed by an Atlassian-operated token-issuing service: the client never holds a client secret — a backend brokers the OAuth exchange and returns tokens, giving a device-grant-like experience. That backend service, not a raw public OAuth flow, is what makes the zero-config login possible, and it is a model to weigh here.
The module already stores multiple named connections in the encrypted Context vault and targets any of them per command via -Context, so several sites or accounts can be used at the same time. That is a real advantage worth preserving — acli keeps a single active account and requires acli jira auth switch to change it, and the Atlassian Remote MCP Server binds to one OAuth identity per connection with no per-call account selector.
Request
Desired capability
An interactive, browser-based sign-in for Connect-Confluence (for example Connect-Confluence -Web) that opens the consent screen, captures the result, and stores the credentials as a named context — with no manual token minting — while keeping the module's simultaneous multi-context model.
Acceptance criteria
- A single interactive command signs the user in through the browser, with no manual API-token creation.
- Multiple sites/accounts can be signed in and used simultaneously via
-Context, with no "switch active account" step.
- Credentials are stored encrypted (
SecureString) and access tokens refresh automatically on expiry; a failed/expired refresh surfaces a clear re-authentication message.
- The existing API-token path keeps working — no breaking change.
- Headless/CI usage remains supported.
Technical decisions
Findings that constrain the design (from the Atlassian docs)
- Flow: OAuth 2.0 (3LO) supports the authorization-code grant only. The implicit grant is explicitly unsupported and Atlassian's public OAuth does not expose an RFC 8628 device-authorization grant. A device-code experience is only possible if a backend service brokers it (see Option C below).
- Confidential client: both the code-for-token exchange and the refresh call mark
client_secret as required, and PKCE is not offered. Atlassian 3LO is a confidential-client model — there is no public-client/PKCE path a distributed CLI could use without a secret.
- How first-party tools sidestep this (
acli, Rovo Dev): since the secret cannot live in a distributed binary and there is no PKCE, acli and Rovo Dev rely on an Atlassian-operated token-issuing service. The CLI opens the browser (or shows a code) and a first-party backend performs the confidential-client exchange and returns tokens; the secret stays server-side. This is the "custom service that does the token issuing" pattern — the only way to get a truly secretless, zero-config CLI login on this platform. (acli and Rovo Dev are closed-source, so this is inferred from the platform constraints and observed behaviour, not an Atlassian-published internal design.)
- Callback: the redirect URI may be "any URL accessible by the app", so a short-lived localhost loopback listener is viable for capturing the
code.
- Refresh: rotating refresh tokens via the
offline_access scope (90-day inactivity expiry; each use returns a new refresh token that must replace the previous one).
- Gateway and multi-site: tokens call
https://api.atlassian.com/ex/confluence/{cloudId}/… (already how Invoke-ConfluenceRestMethod builds URLs), and GET /oauth/token/accessible-resources lists the sites a token can use (already wrapped by Get-ConfluenceAccessibleResource / Get-ConfluenceCloudId). A single account-level grant can span multiple sites for the same account.
Decisions
Three delivery models are viable. They are not mutually exclusive and can ship in order of increasing infrastructure.
- Option A — interactive API-token onboarding (no OAuth app, no infra).
Connect-Confluence (with -Token omitted) opens the API-token page and prompts for the token as a SecureString. A strict UX win over pasting -Token; needs no client secret; keeps working for headless/CI. Lowest effort.
- Option B — "bring your own" 3LO app + authorization code over a loopback redirect (no shared infra). The user registers a 3LO app once in the developer console and supplies
-ClientId / -ClientSecret (kept local, SecureString in Context). Connect-Confluence -Web opens consent, a transient localhost listener captures the code, exchanges it for access + refresh tokens, resolves the cloud ID via accessible-resources, and stores a named context. Real OAuth (short-lived + refresh) with the secret staying on the user's machine. Cost: a one-time, per-user app registration.
- Option C — distributable client + hosted token-broker service (the
acli / Rovo Dev model — "the infra"). Stand up a small first-party service that holds the single app's client_secret server-side and brokers the flow: the module starts a device-code-style login (open browser or show a code), the broker performs the confidential-client code/refresh exchange, and returns the tokens to the module (stored in Context). The module ships no secret and users need no app registration — the zero-config experience acli/Rovo Dev provide. Cost: someone must operate and secure the broker (it becomes trust-critical), and it must be built to Atlassian's distributable-app rules (see compliance note below).
Recommendation: ship A, then B; treat C as the longer-term "infra" investment if a zero-config, registration-free login is wanted for a broad audience. A and B need no service and serve power users immediately; C is what turns this into an acli-class experience but carries operational and compliance weight.
- Storage and refresh in Context. Persist access token, refresh token, expiry, client id/secret, cloud id, and granted scopes per named context (secrets as
SecureString). Invoke-ConfluenceRestMethod / Resolve-ConfluenceToken refresh the access token on expiry (and on a 401), rotating and re-storing the new refresh token. The existing per--Context selection is retained so multiple contexts stay simultaneously usable.
- Parameter sets.
Connect-Confluence gains a -Web (OAuth) parameter set alongside the existing -Token (API token) set; default behavior is unchanged.
- Reusability. The authorize-URL / loopback / token-exchange / refresh logic is generic to every PSModule Atlassian module (for example Jira). It is implemented behind small private helpers here but designed to be extractable into a shared module later (tracked as a follow-up). The
Context module is already the shared encrypted store.
- Atlassian compliance context (matters most for Option C). Atlassian's guidance for third-party apps says integrations should use a single, distributable 3LO app (or a Forge app) that identifies its source, and must not (a) instruct customers to generate/share API tokens that a third-party service stores, or (b) ask customers to create a 3LO app per tenant. Third-party apps are also prohibited from storing user credentials. Implications: Options A (a user's own token, stored locally by the user) and B (a user's own app, secret local) are personal-automation uses that sit outside the "third-party service storing others' credentials" concern — but they are the patterns Atlassian is steering away from for anything distributed. Option C is the pattern Atlassian actually endorses (one distributable app), but a broker that persisted users' refresh tokens server-side would itself be "storing user credentials" — so it must be designed to return tokens to the client for local storage and hold only the app secret, and comply with the security requirements for cloud apps. Atlassian's stated deadline for migrating to compliant connectors was Dec 31, 2025.
Sequencing
Option A (interactive API-token onboarding) lands first — small, low-risk, no app registration. Option B (-Web, bring-your-own app + loopback) next. Option C (hosted token-broker for zero-config, acli-style login) is a separate, larger infrastructure track, evaluated on its own once A and B are proven. Shared-helper extraction follows so other PSModule Atlassian modules can reuse whichever flows ship.
Connecting to Confluence today requires minting an Atlassian API token by hand in account settings and pasting it into
Connect-Confluence -Token. That works, but it is a manual, out-of-band step, the token is long-lived, and there is no guided interactive path — which raises the barrier to first use and encourages long-lived secrets on disk.Atlassian's own CLI (
acli) offersacli jira auth login --web: the browser opens, the user consents, and the session is established with no token handling. Atlassian's Rovo Dev CLI/MCP behaves the same way. Both can do this because they are first-party tools backed by an Atlassian-operated token-issuing service: the client never holds a client secret — a backend brokers the OAuth exchange and returns tokens, giving a device-grant-like experience. That backend service, not a raw public OAuth flow, is what makes the zero-config login possible, and it is a model to weigh here.The module already stores multiple named connections in the encrypted Context vault and targets any of them per command via
-Context, so several sites or accounts can be used at the same time. That is a real advantage worth preserving —aclikeeps a single active account and requiresacli jira auth switchto change it, and the Atlassian Remote MCP Server binds to one OAuth identity per connection with no per-call account selector.Request
Desired capability
An interactive, browser-based sign-in for
Connect-Confluence(for exampleConnect-Confluence -Web) that opens the consent screen, captures the result, and stores the credentials as a named context — with no manual token minting — while keeping the module's simultaneous multi-context model.Acceptance criteria
-Context, with no "switch active account" step.SecureString) and access tokens refresh automatically on expiry; a failed/expired refresh surfaces a clear re-authentication message.Technical decisions
Findings that constrain the design (from the Atlassian docs)
client_secretas required, and PKCE is not offered. Atlassian 3LO is a confidential-client model — there is no public-client/PKCE path a distributed CLI could use without a secret.acli, Rovo Dev): since the secret cannot live in a distributed binary and there is no PKCE,acliand Rovo Dev rely on an Atlassian-operated token-issuing service. The CLI opens the browser (or shows a code) and a first-party backend performs the confidential-client exchange and returns tokens; the secret stays server-side. This is the "custom service that does the token issuing" pattern — the only way to get a truly secretless, zero-config CLI login on this platform. (acliand Rovo Dev are closed-source, so this is inferred from the platform constraints and observed behaviour, not an Atlassian-published internal design.)code.offline_accessscope (90-day inactivity expiry; each use returns a new refresh token that must replace the previous one).https://api.atlassian.com/ex/confluence/{cloudId}/…(already howInvoke-ConfluenceRestMethodbuilds URLs), andGET /oauth/token/accessible-resourceslists the sites a token can use (already wrapped byGet-ConfluenceAccessibleResource/Get-ConfluenceCloudId). A single account-level grant can span multiple sites for the same account.Decisions
Three delivery models are viable. They are not mutually exclusive and can ship in order of increasing infrastructure.
Connect-Confluence(with-Tokenomitted) opens the API-token page and prompts for the token as aSecureString. A strict UX win over pasting-Token; needs no client secret; keeps working for headless/CI. Lowest effort.-ClientId/-ClientSecret(kept local,SecureStringin Context).Connect-Confluence -Webopens consent, a transient localhost listener captures thecode, exchanges it for access + refresh tokens, resolves the cloud ID viaaccessible-resources, and stores a named context. Real OAuth (short-lived + refresh) with the secret staying on the user's machine. Cost: a one-time, per-user app registration.acli/ Rovo Dev model — "the infra"). Stand up a small first-party service that holds the single app'sclient_secretserver-side and brokers the flow: the module starts a device-code-style login (open browser or show a code), the broker performs the confidential-client code/refresh exchange, and returns the tokens to the module (stored in Context). The module ships no secret and users need no app registration — the zero-config experienceacli/Rovo Dev provide. Cost: someone must operate and secure the broker (it becomes trust-critical), and it must be built to Atlassian's distributable-app rules (see compliance note below).Recommendation: ship A, then B; treat C as the longer-term "infra" investment if a zero-config, registration-free login is wanted for a broad audience. A and B need no service and serve power users immediately; C is what turns this into an
acli-class experience but carries operational and compliance weight.SecureString).Invoke-ConfluenceRestMethod/Resolve-ConfluenceTokenrefresh the access token on expiry (and on a401), rotating and re-storing the new refresh token. The existing per--Contextselection is retained so multiple contexts stay simultaneously usable.Connect-Confluencegains a-Web(OAuth) parameter set alongside the existing-Token(API token) set; default behavior is unchanged.Contextmodule is already the shared encrypted store.Sequencing
Option A (interactive API-token onboarding) lands first — small, low-risk, no app registration. Option B (
-Web, bring-your-own app + loopback) next. Option C (hosted token-broker for zero-config,acli-style login) is a separate, larger infrastructure track, evaluated on its own once A and B are proven. Shared-helper extraction follows so other PSModule Atlassian modules can reuse whichever flows ship.