Review PaperCut on G2

Choose your language

Choose your login

Contact us

API security

TLS 1.2

PaperCut expects all API traffic to use the TLS 1.2 and above cryptographic protocol.

API security overview

The PaperCut cloud-native Add-on Platform (AOP) verifies every API call you make using a bearer token. For more information about bearer tokens, see Bearer Authentication.

The AOP uses OAuth2 to manage authentication and authorization between the AOP and your solution (machine to machine).

To use our APIs you’ll need to provide an access token (via a bearer token header) in each API call to the AOP.

So you can generate access tokens in your solution, PaperCut Software will give you a client ID and a client secret. It’s essential to keep these two pieces of information secure.

Access tokens have a limited lifecycle. You must create and manage them according to the steps on this page.

Access tokens grant you access to a specific API scope. The scope defines the list of APIs that can be used with the specific solution.

Generating the access token

When your solution (application component) starts it will need to generate a new token via the token service at https://myaccount.papercut.com/, as described below.

These examples use curl and Python to show how to generate a new API key is generated using your client id and client secret.

curl --request POST \
  --url 'https://myaccount.papercut.com/oauth/token' \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data grant_type=client_credentials \
  --data client_id=$YOUR_CLIENT_ID \
  --data client_secret=$YOUR_CLIENT_SECRET \
  --data audience=https://api.cloud.papercut.com

or

#!/usr/bin/env python

from requests import post, codes

def getNewAPItoken():
    
    payload = {
        "client_id": client_id,
        "client_secret": client_secret,
        "audience": "https://api.cloud.papercut.com",
        "grant_type": "client_credentials"
    }

    headers = { 'content-type': "application/json" }

    resp = post("https://myaccount.papercut.com/oauth/token",
                json=payload,
                headers=headers)

    if resp.status_code == codes.ok:
        return resp.json()
    else:
        print(resp)
        resp.raise_for_status()

if __name__ == "__main__":
    print(getNewAPItoken())

This should return something similiar to:

{
'access_token': 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik16Z3hNRGRDUkVWRU16RkRSa1l3UTBKRE56RkNNVEJCTWpGQk9VTXpNVEkwUWpjNFF6QkRSZyJ9.eyJpc3MiOiJodHRwczovL3BtaXRjLmF1dGgwLmNvbS8iLCJzdWIiOiJQSWYyMXc0cVdkekEzenk5cWZPNnpOcmJUNXdssRnI5RUBjbGllbnRzIiwiYXVkIjoiaHR0cHM6Ly9hcGkuY2xvdWQucGFwZXJjdXQuY29tIiwiaWF0IjoxNjIyNDMzMTg4LCJleHAiOjE2MjI1MTk1ODgsImF6cCI6IlBJZjIxdzRxV2R6QTN6eTlxZkdsdek5yYlQ1dzVGcjlFIiwic2NvcGUiOiJqb2ItbG9nLnJlYWQiLCJndHkiOiJjbGllbnQtY3JlZGVudGlhbHMifQ.kKGquiY2t7FXiyeotSEsTABTN5ALbpDtMmGpv8VlClFxNwEETvesf79DGs00WIj5e3ubiTA9KEvc3bsUlC1S5tOZcDugFO2NvrwR83_Fpn_T5HeR97lx1T4l1Jppe5Wnp-NQjejRK9z7BUT5LVENqwe6jQQ9PZjw32mwUUPq0wiUXiu28rvWRzKlkk0ETnOcR7L8yizWrrOIkUfehCP-cSYFg1b2mXr8oH0vSRCMG1jXOyRhZTU9MEL2_CO9WAOnbIo-YRXUieNKfd87L8w_8ckiA3ubvEdoaAF7dmnmF2zb1EfrDHhntwOsnezj2p_nnKGKxKfqOo19y2r1JSzZVg',
'scope': 'job-log.read',
'expires_in': 86400,
'token_type': 'Bearer'
}    

Tokens have an expiry time. For example, in the above example, the expiry time is 86400 seconds (24 hours). The solution must cache the token and re-use it until it expires, at which point it must generate a new access token.

Note: If a solution service is transient (for example, only runs every 160 minutes), ensure the tokens persist between invocations so they can be re-used until expiry.

The API scope will reflect the set of API features your solution has access to.

Using the access token

  • The solution must use the access token with every API call it makes to the AOP.

  • Send the token in the https authorization header as a “bearer token”. For example:

{"Authorization": "Bearer " + accessTokenGeneratedViaOAuth}

Note: the exact way you specify HTTP headers will vary depending on the technology you are using. Please consult your library documentation. For example, in Python 3 (using the Requests package) you can do something like this:

resp = post(f"{apiRoot}/{org}/addons.verify-options-token/{apiVersion}",
     headers={
             "Authorization": "Bearer {accessTokenGeneratedViaOAuth}",
             "Content-type":"application/json",
             "Accept": "application/json"},
     json={"token": token })

In the above example accessTokenGeneratedViaOAuth and token refer to two different pieces of information. For more information refer to the details in the API reference.

Example

Notes:

  • The client ID, client secret, and access token must be kept secure. For example, you cannot distribute the API key in a plugin, desktop application, or single page web application.

  • PaperCut Software will issue you with a different client ID and client secret for every add-on solution you develop. You must use the correct key for each solution you publish.

  • For the addons.verify-options-token you may use any valid token for the solutions you are deploying.

  • Each client ID is scoped to a specific set of API calls (for example, job log export), plus the addons.verify-options-token end point.

  • If your client ID or client secret is compromised, you must ask PaperCut to issue you with a new one; email integration-dev-support@papercut.com.

  • If your access token is invalid, the response status is 401.