Skip to content

Add Confluence Data Center support with allow_local_address and beare…#6769

Open
srikanthpadakanti wants to merge 2 commits intoopensearch-project:mainfrom
srikanthpadakanti:confluence-data-center-6496-public
Open

Add Confluence Data Center support with allow_local_address and beare…#6769
srikanthpadakanti wants to merge 2 commits intoopensearch-project:mainfrom
srikanthpadakanti:confluence-data-center-6496-public

Conversation

@srikanthpadakanti
Copy link
Copy Markdown
Contributor

@srikanthpadakanti srikanthpadakanti commented Apr 20, 2026

Description

Two changes to support Confluence Data Center deployments:

1. Configurable address validation (allow_local_address)

The existing AddressValidation.validateInetAddress() rejects all local/private IPs, which blocks Confluence Data Center running on internal
networks. Added a boolean config allow_local_address (defaults to false) that skips site-local, loopback, and link-local checks when enabled.
Multicast and any-local addresses are still rejected regardless.

  source:
    confluence:                                                                                                                                     
      hosts:                                                                                                                                        
        - "https://confluence.internal.company.com"                                                                                                 
      allow_local_address: true                                                                                                                    

  1. Bearer token authentication

Confluence Data Center uses Personal Access Tokens (PAT) for authentication. Added bearer_token as a third auth option alongside basic and oauth2.
Only one auth method can be configured at a time.

  source:                                                   
    confluence:
      hosts:                                                                                                                                        
        - "https://confluence.internal.company.com"
      allow_local_address: true                                                                                                                     
      authentication:                                       
        bearer_token: "your-personal-access-token"           

Changes are in atlassian-commons so Jira Data Center also benefits from the same allow_local_address and bearer token support.

Issues Resolved

Resolves #6496
#6496

Check List

  • [ X ] New functionality includes testing.
  • New functionality has a documentation issue. Please link to it in this PR.
  • [ X ] New functionality has javadoc added
  • [ X ] Commits are signed with a real name per the DCO

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

…r token auth

Make address validation configurable via allow_local_address (default false)
so Confluence Data Center on internal networks is supported. Add bearer token
authentication for Personal Access Tokens used by Data Center deployments.

Resolves opensearch-project#6496

Signed-off-by: Srikanth Padakanti <srikanth_padakanti@apple.com>
@srikanthpadakanti srikanthpadakanti force-pushed the confluence-data-center-6496-public branch from 99de791 to f257f0f Compare April 20, 2026 22:10
@srikanthpadakanti
Copy link
Copy Markdown
Contributor Author

srikanthpadakanti commented Apr 21, 2026

Hi @dlvenable @kkondaka Please review this. Thanks.

Copy link
Copy Markdown
Member

@dlvenable dlvenable left a comment

Choose a reason for hiding this comment

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

Thanks @srikanthpadakanti for the contribution! I have a few comments and questions.


@AssertTrue(message = "Authentication config should have either basic or oauth2")
@JsonProperty("bearer_token")
private String bearerToken;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For OAuth2, we use PluginConfigVariable. This allows us to refresh the credentials from the Jira/Confluence source plugins themselves. Do you think this is relevant for bearer tokens?

Either way, this can support reading from secrets managers.

Copy link
Copy Markdown
Contributor Author

@srikanthpadakanti srikanthpadakanti May 7, 2026

Choose a reason for hiding this comment

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

Agreed on PluginConfigVariable, Will address in a follow-up since PATs don't need refresh, but secrets manager reads are valuable. Keeping scope tight for this PR.

Otherwise if you want me to implement it now, I can change String bearerToken to PluginConfigVariable bearerToken and update all usages. What do you prefer?


private ConfluenceRestClient(RestTemplate restTemplate, AtlassianAuthConfig authConfig,
PluginMetrics pluginMetrics, boolean allowLocalAddress) {
super(restTemplate, authConfig, pluginMetrics, allowLocalAddress);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we need similar changes in the JiraRestClient?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, since this lives in atlassian-commons the Jira client inherits it. Will wire through JiraRestClient as well

boolean hasBasic = basicConfig != null;
boolean hasOauth = oauth2Config != null;
return hasBasic ^ hasOauth;
boolean hasBearer = bearerToken != null && !bearerToken.isBlank();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I tend to think that isEmpty is the right approach here. This would ignore an explicit " ", which is an odd configuration to be sure.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed, switching to isEmpty

@JsonProperty("acknowledgments")
private boolean acknowledgments = false;

@JsonProperty("allow_local_address")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

To me, this implies that it will allow localhost names specifically. But it is localhost and private IP.

Should we have two configurations:

  • allow_private_network or allow_internal_address to denote private IP addresses, but not localhost
  • allow_local_address or allow_localhost_address to allow localhost addresses

Or maybe just update the one name?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Makes sense to separate the concerns

void testAllowLocalAddressStillRejectsAnyLocal() throws UnknownHostException {
InetAddress wildcardAddress = InetAddress.getByName("0.0.0.0");
assertThrows(BadRequestException.class, () -> AddressValidation.validateInetAddress(wildcardAddress, true));
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just to be sure, we should have some test cases that includes a public IP to be sure it is not exclusive to localhost addresses.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will add a positive case with a routable public IP to confirm it passes through cleanly

assertThrows(RuntimeException.class, () -> ConfluenceConfigHelper.validateConfig(confluenceSourceConfig));

when(authenticationConfig.getBearerToken()).thenReturn("");
assertThrows(RuntimeException.class, () -> ConfluenceConfigHelper.validateConfig(confluenceSourceConfig));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This has three different test cases. I think splitting them out into three different JUnit test cases/methods is ideal.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will break into three: null token, empty token, and blank token

when(sourceConfig.getAuthType()).thenReturn(BEARER_TOKEN);
when(sourceConfig.getAuthenticationConfig()).thenReturn(authenticationConfig);
when(authenticationConfig.getBearerToken()).thenReturn("test-token");
when(sourceConfig.getAccountUrl()).thenReturn("https://confluence.internal.com");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not sure what internal.com is. We should probably use example.com or opensearch.org (we know the latter).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

using opensearch.org


@Test
void testInterceptSetsBearerAuthHeader() throws IOException {
when(authConfig.getBearerToken()).thenReturn("my-token");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Generate a random value here instead of the static "my-token".

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will generate via UUID.randomUUID().toString() for better test isolation

…t values, wire JiraRestClient

Signed-off-by: Srikanth Padakanti <srikanth_padakanti@apple.com>
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.

Confluence Data Center

2 participants