Compass GraphQL Access From OAuth Application
Asked by Dan Walker:

I am looking to automate the creation and updating of our Compass components through GraphQL from an external application. From what I can tell there is no way to provide access to the right OAuth scopes to a traditional OAuth application and it must happen through a Forge app. Is that correct?

The workaround I can come up with is create a Forge app with a web hook that accepts the payload I have created and then turns it into the right GraphQL queries, but that seems like an extra step that shouldn't have to exist.


Answers:
author: Moinul
body: Hi Dan, You should be able to make requests to the compass GraphQL API from anywhere using Basic HTTP authentication with an API token. Compass API doesn't support OAuth yet.

You basically need to send an **Authorization** header that looks like **Basic \<value\>** where **value** is a **base64 encoded** string of **\<your-email\>:\<your-api-token\>**

You can generate an API token at <https://id.atlassian.com/manage-profile/security/api-tokens>

comments: author: Dan Walker
body: I have tried that, but I get a 403 back when using Basic HTTP auth.

"message": "The underlying service call failed. The underlying service compass status code is : 403",  
I am able to use the same header to query Jira, so I don't think I've made any typos, and I can run the same query successfully through the web explorer. Is there something I'm missing?


author: Moinul
body: Hi Dan, Could you share the code snippet you are trying to execute?

We may be missing something somewhere. Here is an example node.js (v12) snippet I was able to run and get result from compass GraphQL API

```
import fetch from "node-fetch";

const getComponentQuery = `
query getComponent($componentId: ID!) {
    compass {
        component(id: $componentId) {
            __typename
            ... on CompassComponent {
                id
                name
            }
            ... on QueryError {
                message
            }
        }
    }
}
`;


const makeRequest = async (query, variables) => {
    let token = Buffer.from(
        `my-email:my-token`
    ).toString("base64"); // replace my-email and my-token with your email and token

    const response = await fetch("https://api.atlassian.com/graphql", {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            "X-ExperimentalApi": "compass-beta, compass-prototype",
            Authorization: `Basic ${token}`,
        },
        body: JSON.stringify({
            query,
            variables,
        }),
    });
    return response.json();
};

// this should be a component ARI which you can get by clicking the ... on a component overview page and clicking Copy Component ID
makeRequest(getComponentQuery, {componentId: '<a-component-ari>'}).then((response) => {
    console.log(response.data.compass.component);
});
```

![620f08f553c3d399575226b47b8ec64d.png](https://community.atlassian.com/t5/image/serverpage/image-id/238220i27829AA149D4F69F/image-size/large?v=v2&px=999 "620f08f553c3d399575226b47b8ec64d.png")


author: Dan Walker
body: I am not in code yet. I'm just building my queries with Banana Cake Pop. I made sure to set the auth header and the experimental API header.

I've been running the following queries:

This one returns a 403:  

```
query listComponents($cloudId: String!) {
  compass {
    searchComponents(cloudId: $cloudId)
    {
      ... on CompassSearchComponentConnection {
        nodes {
          component {
            name
            id
          }
        }
      }
    }
  }
}
```

This one works:  

```
query jiraExample ($cloudId: ID!) {
  jira {
    allJiraProjects(cloudId: $cloudId, filter: {types: [SOFTWARE]}) {
      pageInfo {
        hasNextPage
      }
      edges {
        node {
          key
          name
        }
      }
    }
  }
}
```


author: Dan Walker
body: Update: I copied my same headers and queries into Postman, and it works in there...I'm not sure why Banana Cake Pop is getting a 403, but it seems likely that my tool is just sending up something that the GraphQL Endpoint doesn't like.


author: Moinul
body: Not really super familiar with Banana Cake Pop, so can't tell whats up there but glad it worked finally!


Tags: graphql