# Authentication

# Introduction

SalesCloud Apps can authenticate and perform queries and mutations with the SalesCloud Graph on behalf of organizations.

Users must install your App from the Appstore to their organization to give your app access to their data in the graphql.

# Api Keys

SalesCloud Apps must use a public key and a secret key to authorize requests with the SalesCloud Graph.

These keys are found in the security section of your app in the SalesCloud Developer portal.

The secret key cannot be retrieved again after it is generated, so make sure to save it in a secure place. A new secret key can be generated at any given time and is effective immediately.

# Headers

Authenticated requests on behalf of your app have the following headers.

# SalesCloud-Application

This header is the uuid of your app so that the SalesCloud Graph knows which app is making the authenticated request.

# SalesCloud-Application-Public-Key

This header is the public key of your app as seen on the security section in the developer portal.

# SalesCloud-Organization

This header is the uuid of the organization on behalf which you want to make a request.

The uuid of the organization must exist and must have your application installed for your request to make an authenticated request on behalf of that organization.

We recomment that you make a "appOrganizations" query on the SalesCloud Graph to get a list of organizations that have installed your app.

curl --verbose  --header "SalesCloud-Application: xxx" --header "SalesCloud-Application-Public-Key: xxx" --header "Authorization: App xxx"--data '{    "query": "{ query appOrganizations { uuid, label } }"}' --request "POST" "https://graph.salescloud.is?"

# Authorization

This header contains a cryptographically signed string using the app uuid, public key and the request body with the secret.

This header will be computed in the graph with the same values and compared to this header. Only if both signatures are the same is your request considered valid.

The Authorization header is followed by an App prefix where you would normally see Bearer, like so: "Authorization: App .....".

Below is an example of how to generate the authorization header.

const crypto = require('crypto')

const applicationUUID = 'edadd893-9472-4324-a4db-b1707c563184'
const organizationUUID = '7b371391-1561-4cac-8f86-9b7bcba83db2'

const applicationPublicKey = '849015eb35e25eee9b36b36481b55ec3a4efc4c6351873f98d33601448b80139e4ca2ca2adc314df182edc1848dcef713b448f982bcf8d8382813a5547e0a87b21e7119ef83349e176ac49a0a35be0197a1bb41e8660a33eaeeae3ffc6e61174b4462b833e18a1586a7a847deb1f2605a38cce7e1e29cce4295fbd2bfa37108abdc00399c2b4b8a7e4cbe5073530a6737550f5c497c1d09d0c4ed86b3fefbe2eb97381dcc645611ae47b2bdc8c481f1d99dd36b2cb0e56d24cf292f5ddaead29000fb806b7577272f6f1440b69cd4808094c1e042fa1753e8e563d1f8d1da46b6eb7346c179322f57a06134adf3bc508b815c3e6fc42b2bb82bf27836aa23432'

const applicationSecretKey = 'dd14918184be8aacfcb44b939804f0d3efb09e35d7945f8bf91c71984f41db0646c69412d1795ae7da766d04153344b04d4dcb8eb28171c7d21b43ff5afd4aa6b8ee1d22d9c5bef82d82c540aebdc67f10f46275c2fc924a764f1849b4b2fd0640a9afc00174efca544d56c6ca02c048af802ba2f1992943f83f04cd0f177b8b867291700b236cab7e17defb92b51554d0d04368e637f02d3ccd2ebafb6ccc65b4809a3f6d38c8332f94a4008d01238e2818da89d5c978be85473f6f874bd3499b3fc1e2d4e992f81822ccb2ae4b50aa20f196ce4b5780df38badb749c6c6b85c2baeb2d7afeaaa13dfbe72d4bd86cc437bc8043beaf8d60bcdad8d26fafe7c0'

// Simple Example Request
const bodyOfRequestAsJsonString = '{ "query": { systemTimeInMillis } }'

// The string that must be cryptographically signed
const sign = applicationUUID + ':' + applicationPublicKey + ':' + organizationUUID + ':' + bodyOfRequestAsJsonString

// The computed signature for Authorization header
const computedSignature = crypto.createHmac('sha256', applicationSecretKey).update(sign).digest('base64')

# Read Access Tokens

Read access tokens allow you to easily query data from the graph. As the name suggests, you can only read information with those tokens.

All that is required is an header like this: "Authorization: ReadAccessToken {TokenHere}"

# Axios Example

const crypto = require('crypto')
const axios = require('axios')

function CreateHeaders(appUUID, organizationUUID, publicKey, privateKey, query, variables) {
    let formattedQuery = ''

    if (variables) {
        formattedQuery = JSON.stringify({ query: query, variables: variables })
    } else {
        formattedQuery = JSON.stringify({ query: query })

    let stringMeantForSigning = appUUID + ':' + publicKey + ':' + organizationUUID + ':' + formattedQuery

    const SIGNED = crypto.createHmac('sha256', privateKey).update(stringMeantForSigning).digest('base64')

    let headers = {
        "SalesCloud-Application": appUUID,
        "SalesCloud-Application-Public-Key": publicKey,
        "Authorization": "App " + SIGNED,
        "SalesCloud-Organization": organizationUUID
    return headers

function SendData() {

    let query = 'mutation createLog($log: NewLog!) {createLog(log: $log)}'
    let variables = { log: { msg: "hello!" } }
    const headers = CreateHeaders(query, variables)

    let response = axios.post(
        { query: query, variables: variables },
            timeout: 10000,
            headers: { ...headers, 'content-type': 'application/json' },
    ).then((response) => {
        return response
    }).catch((error) => {
        return error