# Authentication & Security

> How authorization and security work in the Mapped API

## Authorization overview {#AuthOverview}

All Mapped API calls will make use of a Personal Access Token, typically generated on the **[Personal Access Token][1]** page of the Mapped Console:

[![PAT_Screenshot](./img/pat_frame_generic.png)][3]

You can generate multiple access tokens that have individual scopes for different tasks (which is recommended from a security point of view - less risk if a token is inadvertently exposed) or you can generate less tokens with more scopes; either way works. Personal Access Tokens don't expire on their own - they live indefinitely until intentionally revoked (see **[Deleting Access Tokens][4])**. This is another reason limiting the scopes on a particular token is generally the best idea. 

The scopes available for selection are also dependent on your role, specifically whether you're an ADMIN or EXPLORER. Roles are discussed in more detail in the **[User][5]** portion of the docs, but the core idea is an EXPLORER will only have read-only access to the majority of API resources. The scopes available to them won't include any with "write" permissions.

## Using a Token {#UsingToken}

Below are the steps to actually use the token you created in the previous section; it may also be beneficial to review the **[How to Make a GraphQL Request][6]** section of the Introduction docs.

When making an API request, you'd make a call to this URL:

**https://api.mapped.com/graphql**

and pass your PAT in as an Authorization header with the type **token** like this: 

```bash
Authorization: token PATABcDZGRpbjpvcGVuc2Vz1138
```

You'll also want to include a Content-type header with the value application/json:

```bash
Content-type: application/json
```

Last, you would then include your request body, such as those shown throughout the docs.

## Viewing access tokens {#ViewAccessTokens}

To view all tokens associated with your user, you'll need a token with the scope **PERSONALACCESSTOKEN_READ**. If you want to view all tokens associated with a particular user, you'll need to be an ADMIN and have a token with the scope **PERSONALACCESSTOKEN_READ_ALL**

The following example includes the **[filter][7]** for a specific userId; if you just want to see your own tokens, remove the filter:

```graphql title="Request"
{
  tokens(filter: {userId: {eq: "1234abcd5678c3p0"}}) {
    id
    name
    permissions
    created
  }
}
```

```json title="Response"
{
  "data": {
    "tokens": [
      {
        "id": "ABCd2Rj1i5G4GN5qU7ThX138",
        "name": "Testing Token",
        "permissions": [
          "PLACE_READ_ALL"
        ],
        "created": "2021-02-10T20:09:33.263"
      },
      {
        "id": "EFGHR8sQhz7ad83x5qpDk2187",
        "name": "Testing Token 2",
        "permissions": [
          "THING_READ_ALL"
        ],
        "created": "2021-02-10T20:09:50.212"
      },
      {
        "id": "IJKLuEeuMwrRMkqnZXtdk1138",
        "name": "Testing Token 3",
        "permissions": [
          "USER_READ_ALL"
        ],
        "created": "2021-02-10T20:12:40.513"
      }
    ]
  }
}
```

## Creating an access token {#CreateAccessToken}

If the token you're using to make API calls has the **PERSONALACCESSTOKEN_READWRITE** (or **PERSONALACCESSTOKEN_READWRITE_ALL** for an ADMIN), you can create a new token programmatically. The following example creates a token with the **ORG_READ** and **USER_READ** permissions, then returns the actual token in the response body:

```graphql title="Request"
mutation {
    	createPersonalAccessToken(input: { 
        pat: {
          name: "New Token"
          permissions: [ORG_READ USER_READ]
        }
      }) {
    		token
    	}
    }
```

```json title="Response"
{
  "data": {
    "createPersonalAccessToken": {
      "token": "PAT2Bg8GsJRw3t4CwrTWS3svusSjsVoBXGfBvNgHBQ2JUAPz451234A"
    }
  }
}
```

If your role is EXPLORER, you will only be able to create tokens with limited permissions, primarily restricted to "read" access rights.

## Deleting access tokens {#DeleteAccessTokens}

You can also programmatically remove a Personal Access Token - if you're an ADMIN and your token has the permission **PERSONALACCESSTOKEN_READWRITE_ALL**, then you can remove a token from anyone in your organization. if you have the EXPLORER role, or your token has the permission **PERSONALACCESSTOKEN_READWRITE**, you can only remove your own tokens. 

Note you're using the value of the **id** field here, not the access token itself. If you review the code samples in "Viewing Access Tokens" above, you'll see an **id** for each returned record; this is what you'll use to delete the token. Since we never display the token after the initial creation step, this allows you to remove tokens from your account (or as an admin, someone else's account) without knowing the value of the token itself.

```graphql title="Request"
mutation {
    	deletePersonalAccessToken(input: { id: "IJKLuEeuMwrRMkqnZXtdk1138" }) {
    		_
    	}
    }
```

```json title="Response"
{
      "data": {
        "deletePersonalAccessToken": {
          "_": null
        }
      }
    }
```

## Updating access token scopes {#UpdateScopes}

It's also possible to update an existing token's scopes using the **id** of the token; just to note again, this is not the same as the token itself, it's an identifier for the token record as a whole. This process will regenerate the token, so the old one will no longer function and you'll have a new token to work with. The ID of the token, however, as well as the name and scope assignment will remain the same. This is the API equivalent to the Regenerate button on the [Personal Access Tokens][8] page of the console. Note that if you're updating an existing token with new permissions/scopes, which is the typical use case for the update function, you'll need to include all the previous permissions and include the new ones - you can't just list the new one, as it will overwrite the previous list instead of adding to it.

Like the "Creating a Token" example, make sure to include the **token** field in the returned fields, or you won't have any way to retrieve the actual access token value. 

```graphql title="Request"
mutation {
  updatePersonalAccessToken(
    input: {
      pat: {
        id: "VPT5NfW3X6U2HGXZ2z6123ABC" 
        permissions: [ORG_READ USER_READ]
      }
    }
  ) {
    token
    pat {
      id
      permissions
    }
  }
}
```

```json title="Response"
{
  "data": {
    "updatePersonalAccessToken": {
      "token": "PAT2Bg8GuFsoCWv123ABC65PTfkx95WVav15zJVmAAHSEM9rv123ABC",
      "pat": {
        "id": "VPT5NfW3X6U2HGXZ2z6123ABC",
        "permissions": [
          "ORG_READ",
          "USER_READ"
        ]
      }
    }
  }
}
```

## Security {#Security}

We put together a **[Security Whitepaper][9]** that outlines the steps we take to protect your data. If you have any questions about Mapped security, please don't hesitate to **[contact support][10]**.

  [1]: https://app.mapped.com
  [2]: ./img/pat_frame_generic.png
  [3]: https://app.mapped.com
  [4]: /guides/platform/authentication-security#DeleteAccessTokens
  [5]: /guides/platform/users#UserRoles
  [6]: /guides/platform/introduction#Make
  [7]: /guides/platform/filtering
  [8]: https://app.mapped.com
  [9]: /guides/support/security-whitepaper
  [10]: https://support.mapped.com
