Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Connecting Jira Align to Jira Data Center with Apigee as a Reverse Proxy

Purpose

This document will explain how to connect Jira Align SaaS to a Jira Data Center via Apigee with Basic Authentication (API Key) .

Given 1: The customer has selected Jira Align SaaS in either multi-tenant or dedicated VPC configuration. This does not directly apply for an on premise implementation of Jira Align.

Given 2: The customer hosts Jira Data Center behind a firewall, without currently exposing the Jira Data Center API ports externally

Given 3: The customer uses Apigee as an API Gateway for network edge security and REST API ingress.

Please review the following example and adjust for your organization's security policies, security posture, and security practices.

How It Works

Apigee.png

All REST API traffic will initiate from the Jira Connector for Jira Align.

The Jira Connector for Jira Align currently supports two authentication methods:

  • Basic Authentication

  • OAuth 1.0a.

The preferred authentication policy configuration for Apigee is the API Key, instead of Basic Authentication. This policy configuration allows Jira Align to send the API Key in the Basic Authentication header.

  • In the Jira Align administrator interface, the administrator would select Basic Auth and input the supported Apigee API key.

  • Using a custom Apigee integration, the Apigee tool would extract the API key from the Basic Auth header and validate it.

  • The next step in the custom Apigee integration would modify the inbound request to replace the Basic Authentication header with the Jira Service Account username and password, which is stored in an encrypted KVM and forward the request onto Jira Server/Data Center.

    • Note: At this point the Apigee solution would also perform the public to private DNS mapping.

    • Note 2: The Apigee service can also restrict the requests to the Jira endpoint.

We also highly recommend configuring Mutual TLS and/or IP Allow listing at the Apigee policy level to establish multi-factor authentication policy. A sample IP allow list policy is covered in this article. As always, please review and validate these policies with your Head of IT Security before configuring in your environment.

  • You’ll want one proxy for each Jira Align connector (Ex: Test and Prod).

Additional Notes

  • The following configurations are not supported between Apigee and Jira Align:

    • OAuth 1.0a

    • OAuth 2.0

    • Bearer token

  • Mutual TLS between Jira Align and Apigee is not covered in this article but enabling MFA is part of the User Compensating Control requirements of the Jira Align SOC 2 compliance.

Prerequisites

Configuration Steps

1.) Sign in to Apigee Edge and click on API Proxies.

apigee_1.png

2.) Click +Proxy to create a new Proxy.

apigee_2.png

3. Select Reverse proxy.

apigee_3.png

4.) Fill in the Proxy name, the base path, and Target API (Jira site).

You’ll need 2 base paths (one for prod, one for test) to connect Jira Align to your Production Jira DataCenter and Test Jira DataCenter.

apigee_4.png

5.) Select API Key in the Security: Authorization options.

  • Do not enable CORS

  • Quota configuration and design is not in scope for this document. For the purposes of establishing connections, please do not enable at this time.

apigee_5.png

6.) Select secure in the Virtual hosts options.

apigee_6.png

7.) Click Create.

apigee_7.png

Create Key Value Map Store

8.) In the Apigee Edge tool, go to Admin > Environments > Key Value Maps.

Make sure to select the correct environment.

We recommend to use the test environment first.

9.) Create Key Value Map.

Example:

kvm_store_1 (encrypted)

key: name, value: <jira-service-acct-username>

key: pass, value: <jira-service-acct-password>

apigee_9a.pngapigee_9b.pngapigee_9c.png

 

Policies

10) Navigate to Develop > API Proxies > Select your Proxy > Develop Tab.

11) Create these policies. You can paste the Verify API Key policy below over the existing one.

Type: AccessControl

This policy permits certain IPs (or IP ranges) to connect to the proxy.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AccessControl async="false" continueOnError="false" enabled="true" name="IP-Allow-List">
    <DisplayName>IP Allow List</DisplayName>
    <Properties/>
    <IPRules noRuleMatchAction="DENY">
        <MatchRule action="ALLOW">
            <SourceAddress mask="32"><Example-IP></SourceAddress>
</MatchRule> </IPRules> </AccessControl>

Type: BasicAuthentication

This policy decodes the inbound (to Apigee) Basic Auth Header and stores the decoded username and password in variables.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<BasicAuthentication name="Decode-Basic-Auth-Headers">
    <DisplayName>Decode Basic Auth Headers</DisplayName>
    <Operation>Decode</Operation>
    <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
    <User ref="request.header.username"/>
    <Password ref="request.header.password"/>
    <Source>request.header.Authorization</Source>
    <Set/>
</BasicAuthentication>

Type: BasicAuthentication

This policy encodes the outbound (to Jira Data Center) Basic Auth Header using the variables created in the KeyValueMapOperations policy (Get-KVM).

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<BasicAuthentication async="false" continueOnError="false" enabled="true" name="Encode-Basic-Auth-Headers">
    <DisplayName>Encode Basic Auth Headers</DisplayName>
    <Operation>Encode</Operation>
    <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
    <User ref="private.service.name"/>
    <Password ref="private.service.pass"/>
    <AssignTo createNew="true">request.header.Authorization</AssignTo>
    <Source>request.header.Authorization</Source>
</BasicAuthentication>

Type: KeyValueMapOperations

This policy places the Jira service username and password defined in the Key Value Map Store into private variables.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<KeyValueMapOperations async="false" continueOnError="false" enabled="true" name="Get-KVM" mapIdentifier="kvm_store_1">
    <DisplayName>Get KVM</DisplayName>
    <Properties/>
    <Get assignTo="private.service.name">
        <Key>
            <Parameter>name</Parameter>
        </Key>
    </Get>
    <Get assignTo="private.service.pass">
        <Key>
            <Parameter>pass</Parameter>
        </Key>
    </Get>
    <Scope>environment</Scope>
</KeyValueMapOperations>

Type: AssignMessage

This policy cleans up Basic Auth Headers that are no longer needed after decoding and extraction has been completed.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="Remove-Basic-Auth-Headers">
    <DisplayName>Remove Basic Auth Headers</DisplayName>
    <Properties/>
    <Remove>
        <Headers>
            <Header name="request.header.Authorization"/>
        </Headers>
    </Remove>
    <Remove>
        <Headers>
            <Header name="request.header.username"/>
        </Headers>
    </Remove>
    <Remove>
        <Headers>
            <Header name="request.header.password"/>
        </Headers>
    </Remove>
    <Remove>
        <Headers>
            <Header name="username"/>
        </Headers>
    </Remove>
    <Remove>
        <Headers>
            <Header name="password"/>
        </Headers>
    </Remove>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>

Type: VerifyAPIKey

This policy takes the password decoded during "Decode-Basic-Auth-Headers" and validates it against the Apigee API Key.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<VerifyAPIKey async="false" continueOnError="false" enabled="true" name="Verify-API-Key">
    <DisplayName>Verify API Key</DisplayName>
    <APIKey ref="request.header.password"/>
</VerifyAPIKey>

 

12) Place this in your Proxy Endpoint PreFlow and PostFlow after making any adjustments (such as BasePath).

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Name>IP-Allow-List</Name>
            </Step>
            <Step>
                <Condition>(proxy.pathsuffix != "/rest/api/2/serverInfo")</Condition>
                <Name>Decode-Basic-Auth-Headers</Name>
            </Step>
            <Step>
                <Condition>(proxy.pathsuffix != "/rest/api/2/serverInfo")</Condition>
                <Name>Verify-API-Key</Name>
            </Step>
            <Step>
                <Name>Remove-Basic-Auth-Headers</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>
    <Flows/>
    <PostFlow name="PostFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix != "/rest/api/2/serverInfo")</Condition>
                <Name>Get-KVM</Name>
            </Step>
            <Step>
                <Condition>(proxy.pathsuffix != "/rest/api/2/serverInfo")</Condition>
                <Name>Encode-Basic-Auth-Headers</Name>
            </Step>
        </Request>
        <Response/>
    </PostFlow>
    <HTTPProxyConnection>
        <BasePath>/Jira-Align-Test</BasePath>
        <VirtualHost>secure</VirtualHost>
    </HTTPProxyConnection>
    <RouteRule name="default">
        <TargetEndpoint>default</TargetEndpoint>
    </RouteRule>
</ProxyEndpoint>

 

13) Validate that this in your Target Endpoint PreFlow and PostFlow. (Do not paste over the existing policy.)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TargetEndpoint name="default">
    <PreFlow name="PreFlow">
        <Request/>
        <Response/>
    </PreFlow>
    <Flows/>
    <PostFlow name="PostFlow">
        <Request/>
        <Response/>
    </PostFlow>
    <HTTPTargetConnection>
        <URL>https://<your Jira server></URL>
    </HTTPTargetConnection>
</TargetEndpoint>

 

14) Save and Deploy to Test (or Prod if you are skipping Test).

apigee_14.png

Note: Trace is a great way to test and troubleshoot.

 

Create API Product and App

15) Go to Publish > API Products. Create new API Product.

16.) Give the API Product a name, access, environment(s), and add the recently created API proxy.

17.) Click Save.

apigee_17.png

18.) Go to Publish > Apps. Create new App.

19.) Give the App a name and add the recently created API Product.

20.) Click Create.

21.) In the newly created app, you should see the Key. Note that key for later use.

apigee_21.png

 

Setup in Jira Align

22.) Sign in to Jira Align as a super administrator, and navigate to Admin > Jira Settings > Jira Connectors.

apigee_22.png

23.) Enter the Jira Base URL (+ /browse/{external} ) into Jira Link.

24.) Assign this connector a memorable name.

25.) Enter the Apigee API Endpoint and base path from step 6 and step 4 into Jira API URL. (ex: https://example.apigee.net/Jira-Align-Test )

26.) Select Basic with API token Authentication as Authentication Type and set the username to something random and password as Key from step 21.

27.) Click Save.

28.) Click Test Now. (Note: You’ll need to close and open this box to see the Test refresh.)

29.) Assuming the test was good, go ahead and press Activate and Save.

30.) Then you can proceed with Syncing a Project.

 

 

1 comment

Mark Cruth Atlassian Team Mar 18, 2021

Thanks for sharing this, @James McCulley ! I know lots of customers leverage Apigee and this will make it 1000% times easier for them to think about how they connect to Jira Align!

Like # people like this

Comment

Log in or Sign up to comment
TAGS
Community showcase
Published in Jira Align

Helpful hints if you're rolling Align out to your entire enterprise

(Or, What to expect when you’re expanding.) Once you've completed your Jumpstart, or your initial assessment of Jira Align, you'll start to think about how you can roll it out to the rest of your e...

2,451 views 9 36
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you