Apps authorize calls to the zero-touch enrollment [customer API](https://developers.google.com/zero-touch/reference/customer/rest)
using [OAuth](https://oauth.net/2/). This document explains the API's authorization for
enterprise mobility management (EMM) providers and enterprise IT developers.
After reading this document, you'll know how to authorize API requests in your
app and explain the account requirements to your app's users.

## Authorization quickstart

- To set up a Google Cloud Platform project with the zero-touch enrollment API and OAuth client secrets, run [this wizard](https://console.developers.google.com/start/api?id=androiddeviceprovisioning.googleapis.com).
- Build the quickstart sample code for [Java](https://developers.google.com/zero-touch/guides/customer/quickstart/java), [.NET](https://developers.google.com/zero-touch/guides/customer/quickstart/dotnet), or [Python](https://developers.google.com/zero-touch/guides/customer/quickstart/python). Use Google's API client libraries to support other languages.

## Overview

![Device and customer resource relationship](https://developers.google.com/static/zero-touch/images/guides/customer/auth/access-token.svg)

1. One or more IT admins are users in a zero-touch enrollment customer account.
2. IT admins use a Google Account to authenticate themselves.
3. API requests pass an OAuth2 token to authorize API requests on behalf of an IT admin.

## Customer accounts

An organization's configurations, devices, and (IT admin) users belong to a
customer account. A customer account is similar to a group and isn't an
individual user. A reseller sets up a customer when the organization first
purchases devices for zero-touch enrollment. IT admins manage other users in
their organization using the zero-touch enrollment portal.

The API uses numeric customer IDs to identify accounts. You pass the customer ID
as part of the URL path when calling API methods. Your app needs to get a user's
customer ID before calling any API methods.

The example below shows how to get the customer accounts for the user that
authorizes the API call:

### Java

```java
AndroidProvisioningPartner.Customers.List accountRequest = service.customers().list();
accountRequest.setPageSize(100);
CustomerListCustomersResponse accountResponse = accountRequest.execute();

List<Company> customers = accountResponse.getCustomers();
if (customers == null || customers.isEmpty()) {
    // No accounts found for the user. Confirm the Google Account
    // that authorizes the request can access the zero-touch portal.
    System.out.println("No zero-touch enrollment account found.");
} else {
    // Print the customers in this page.
    for (Company customer : customers) {
        System.out.format("%s\tcustomers/%d\n",
              customer.getCompanyName(), customer.getCompanyId());
    }
}
```

### .NET

```c#
CustomersResource.ListRequest accountRequest = service.Customers.List();
accountRequest.PageSize = 100;
CustomerListCustomersResponse accountResponse = accountRequest.Execute();
IList<Company> customers = accountResponse.Customers ?? new List<Company>();
if (customers.Count == 0)
{
    // No accounts found for the user. Confirm the Google Account
    // that authorizes the request can access the zero-touch portal.
    Console.WriteLine("No zero-touch enrollment account found.");
}
foreach (Company customer in customers)
{
    Console.WriteLine("{0}\tcustomers/{1}",
                      customer.CompanyName,
                      customer.CompanyId);
}
```

### Python

```python
response = service.customers().list(pageSize=100).execute()
if 'customers' not in response:
  # No accounts found for the user. Confirm the Google Account
  # that authorizes the request can access the zero-touch portal.
  print('No zero-touch enrollment account found.')
  response['customers'] = []

for customer in response['customers']:
  print('{0}\tcustomers/{1}'.format(
      customer['companyName'], customer['companyId']))
```

In your app, you'll need to navigate the account result pages because the
example above only prints the first 100 accounts. To learn how to do this, read
[Paged results](https://developers.google.com/zero-touch/guides/customer/how-it-works#paged).

An organization typically has one customer account but larger organizations
might use separate customer accounts for each division. Because an IT admin can
be a member of different customer accounts, your app should help users find and
use new customer accounts. In your app, label each customer account using the
[`companyName`](https://developers.google.com/zero-touch/reference/customer/rest/v1/customers#Companys) value.

## Users

IT admins authorize the API requests your app sends on their behalf. To
authorize API requests, your app's user need to do the following:

1. Associate a Google Account with their email address.
2. Join a customer account using the same email address.
3. Accept the zero-touch enrollment customer Terms of Service (ToS).

To help your app's users get set up, reuse our guidance for IT admins in [Get
started](https://support.google.com/work/android/answer/7514005#get-started) and [Associate a Google Account](https://support.google.com/work/android/answer/7514005#associate-account)
in your own documentation.

### User management

IT admins manage the users for their customer accounts in the zero-touch
enrollment portal. Users in a customer account have a role that's either an
*Owner* or an *Admin* . Both roles have the same access to the customer API but
an *Owner* can manage other users.

### ToS acceptance

Before your app's users can authorize API calls, they need to accept the latest
ToS. This happens when IT admins first use zero-touch enrollment or when we
update the ToS. When a user hasn't accepted the latest ToS, the API returns an
HTTP `403 Forbidden` status code and the response body contains a
[`TosError`](https://developers.google.com/zero-touch/reference/customer/rest/v1/TosError).

The portal automatically prompts users to accept the latest ToS when they sign
in. To see suggested approaches your app could include, read [Handle Terms of
Service](https://developers.google.com/zero-touch/guides/customer/emm#tos) in the EMM integration guide.

## Add authorization to your app

Every request your app sends to the customer API must include an authorization
token. The token also identifies your application to Google. Because the
customer API accesses user data, authorization must come from the owner of the
data. Your app delegates API authorization to IT admins using the [OAuth 2.0
protocol](https://oauth.net/2/).

> [!IMPORTANT]
> **Key Point:** To make it simpler to set up authorization and authentication, Google provides [client libraries](https://developers.google.com/api-client-library) that can reduce the amount of code you need to write and make your code more robust. We recommend using a client library to call the customer API---see the quickstarts for [Java](https://developers.google.com/zero-touch/guides/customer/quickstart/java), [.NET](https://developers.google.com/zero-touch/guides/customer/quickstart/dotnet), and [Python](https://developers.google.com/zero-touch/guides/customer/quickstart/python).

### Instructions

We provide quickstart guides for [Java](https://developers.google.com/zero-touch/guides/customer/quickstart/java), [.NET](https://developers.google.com/zero-touch/guides/customer/quickstart/dotnet), and
[Python](https://developers.google.com/zero-touch/guides/customer/quickstart/python) apps. If you're using a different language, follow the two
steps below to set up authorization for your
app.

#### Step 1: turn on the zero-touch enrollment API

1. Use [this
   wizard](https://console.developers.google.com/start/api?id=androiddeviceprovisioning.googleapis.com) to create or select a project in the Google Developers Console and automatically turn on the API. Click **Continue** , then **Go to credentials**.
2. Click **Cancel** on the Create credentials.
3. At the top of the page, select the **OAuth consent screen** tab. Select an **Email address** , enter a **Product name** if not already set, and click the **Save** button.
4. Select the **Credentials** tab, click the **Create credentials** button and select **OAuth client ID**.
5. Select an **Application type** based on what type of app you're building.
6. Set **Name** to your app's name.
7. Click **Create**.
8. Click **Download JSON**.
9. Move the file to your working directory and rename it `client_secret.json`.

#### Step 2: install the client library

To install the client library for your language:

1. Go to [Google API Client Libraries](https://developers.google.com/api-client-library) and select your language from the list of supported languages.
2. Follow the guidance to install the client library.

To learn more about authorization, read [Using OAuth 2.0 to Access Google
APIs](https://developers.google.com/identity/protocols/OAuth2).

### Authorization scopes

Use the API authorization scope
`https://www.googleapis.com/auth/androidworkzerotouchemm` in your app to request
an OAuth 2.0 access token.

A scope parameter controls the set of resources and operations that an access
token permits calls to. Access tokens are valid only for the set of operations
and resources described in the scope of the token request. The API covers all
the methods and resources with the single zero-touch enrollment scope shown
above.

For an example of the zero-touch enrollment scope used with the Google API
client library, see the quickstarts for [Java](https://developers.google.com/zero-touch/guides/customer/quickstart/java), [.NET](https://developers.google.com/zero-touch/guides/customer/quickstart/dotnet), and
[Python](https://developers.google.com/zero-touch/guides/customer/quickstart/python). To learn more about using Google API scopes, read [Using
OAuth 2.0 to Access Google APIs](https://developers.google.com/identity/protocols/OAuth2).

### Best practices for API keys

When you use API keys in your applications, take care to keep them secure.
Publicly exposing your credentials can result in your account being
compromised, which could lead to unexpected charges on your account. To keep
your API keys secure, follow these best practices:

Do not embed API keys directly in code
:   API keys that are embedded in code can be accidentally exposed to the
    public---for example, if you forget to remove the keys from code that you
    share. Instead of embedding your API keys in your applications, store them in
    environment variables or in files outside of your application's source
    tree.

Do not store API keys in files inside your application's source tree
:   If you store API keys in files, keep the files outside your application's
    source tree to help ensure your keys do not end up in your source code control
    system. This is particularly important if you use a public source code
    management system such as GitHub.

Restrict your API keys to be used by only the IP addresses, referrer URLs,
and mobile apps that need them
:   By restricting the IP addresses, referrer URLs, and mobile apps that can
    use each key, you can reduce the impact of a compromised API key. You can
    specify the hosts and apps that can use each key from the [Google API Console](https://console.cloud.google.com/)
    by opening the [Credentials page](https://console.cloud.google.com/apis/credentials) and then either [creating a new API
    key](https://cloud.google.com/docs/authentication/api-keys) with the settings you want, or editing the settings of an API
    key.

Delete unneeded API keys
:   To minimize your exposure to attack, delete any API keys that you no
    longer need.

Regenerate your API keys periodically
:   You can regenerate API keys from the [Google API Console](https://console.cloud.google.com/) by opening the
    [Credentials page](https://console.cloud.google.com/apis/credentials), selecting an API key, and clicking **Regenerate
    key** for each key. Then update your applications to use the newly-generated
    keys. Your old keys will continue to work for 24 hours after you generate
    replacement keys.

Review your code before publicly releasing it
:   Ensure that your code does not contain API keys or any other private
    information before you make your code publicly available.