# Sign-in apps: Google, Microsoft and other providers

A connection that reads Google Sheets or Microsoft 365 signs in as the person who made it
([Signing a connection in](https://codna.me/docs/automations.md#signing-a-connection-in)). It does that through a
**sign-in app** that whoever runs CoDNA registers once, inside the company's own Google Cloud
project or Microsoft tenant. This page walks through registering one with each, and with any
other OAuth 2.0 provider.

Each app is **internal**: only the company's own people can sign in to it, and Google and
Microsoft review nothing. It takes a few minutes, by someone who administers the company's
Google Workspace or Microsoft tenant.

Every app needs the same **redirect address**, which the console's Connections tab shows with a
copy button, and `codna oauth list` prints:

```
https://acme.codna.me/connections/oauth/callback
```

Use your own CoDNA's address in place of `acme.codna.me`.

## Google

In the [Google Cloud console](https://console.cloud.google.com/), signed in as an administrator
of the company's Google Workspace:

1. **Pick or create a project** for CoDNA, such as `codna`.
2. **Turn on the APIs** people will read, under **APIs & Services → Library**: Google Sheets API,
   Google Drive API, Google Calendar API, Gmail API, as needed.
3. **Set up Google Auth Platform**, under **APIs & Services → OAuth consent screen**: give it a
   name people will recognise when they sign in, such as "CoDNA", and under **Audience** choose
   **Internal**. An external app in testing gives out sign-ins that stop after seven days.
4. **Create a client**, under **Clients → Create client**: application type **Web application**,
   and under **Authorized redirect URIs** add the redirect address above. Copy the **client ID**
   and the **client secret** as it is shown: Google shows a new secret only once.

Then register it in CoDNA, from the console's Connections tab (**New app**, provider Google), or:

```
codna oauth add google --provider google \
  --client-id 123456789-abc.apps.googleusercontent.com \
  --scopes https://www.googleapis.com/auth/spreadsheets.readonly,https://www.googleapis.com/auth/drive.readonly
```

The secret is asked for. The scopes are the most people may ask for; each connection asks for
some of them. The common ones:

- Sheets, read: `https://www.googleapis.com/auth/spreadsheets.readonly`
- Sheets, read and write: `https://www.googleapis.com/auth/spreadsheets`
- Drive, read: `https://www.googleapis.com/auth/drive.readonly`
- Calendar, read: `https://www.googleapis.com/auth/calendar.readonly`
- Gmail, read: `https://www.googleapis.com/auth/gmail.readonly`

CoDNA adds `openid` and `email` itself, to show whose account a connection signed in as.

A person's connection then reads from the API's own address. For a sheet,
`https://sheets.googleapis.com/v4`, and a script reads a range with:

```js
source('sheet', { path: '/spreadsheets/1AbC…/values/Applications!A1:F500' })
```

## Microsoft 365

In the [Microsoft Entra admin center](https://entra.microsoft.com/), as an administrator of the
company's tenant:

1. **Register an app**, under **App registrations → New registration**: a name such as "CoDNA";
   supported account types **Accounts in this organizational directory only** (single tenant);
   redirect URI platform **Web**, with the redirect address above.
2. From its **Overview**, copy the **Application (client) ID** and the **Directory (tenant) ID**.
3. **Make a secret**, under **Certificates & secrets → New client secret**. Copy its **Value**, not
   its Secret ID. A secret expires, after two years at most: make a new one before then, and give
   it to CoDNA with `codna oauth change microsoft --secret`.
4. **Choose what it may ask for**, under **API permissions → Add a permission → Microsoft Graph →
   Delegated permissions**, such as `Files.Read`, `Sites.Read.All`, `Calendars.Read` or
   `Mail.Read`. **Grant admin consent** for the tenant, so people aren't each asked, and so
   permissions that need an administrator, such as `Sites.Read.All`, work at all.

Then register it in CoDNA, from the console (**New app**, provider Microsoft), or:

```
codna oauth add microsoft --provider microsoft \
  --client-id 0f1e2d3c-… --tenant acme.ge \
  --scopes Files.Read,Sites.Read.All
```

The tenant is its directory ID, or a domain of the tenant. CoDNA adds `openid`, `email` and
`offline_access` itself. A connection reads from `https://graph.microsoft.com/v1.0`, for example a
file in someone's OneDrive with `source('onedrive', { path: '/me/drive/root:/Reports/q3.xlsx' })`.

## Another OAuth 2.0 provider

HubSpot, Salesforce, Zoom and most others follow the same steps in their developer settings:
register an app with the redirect address above, and copy its client ID and secret. CoDNA needs
the provider's authorize and token addresses too, from its documentation, and a revoke address if
it has one:

```
codna oauth add hubspot --provider oauth2 --client-id … \
  --authorize-url https://app.hubspot.com/oauth/authorize \
  --token-url https://api.hubapi.com/oauth/v1/token \
  --scopes crm.objects.contacts.read
```

CoDNA signs in with PKCE. It sends the client ID and secret in the body of each token request, or
as HTTP Basic to a provider that refuses them in the body, as Zoom does.

## Afterwards

- **People sign in** on the Connections page, choosing the app under **How it gets its token**.
- **Changing an app's scopes** leaves connections signed in with what they were given, until they
  sign in again.
- **Removing an app** stops every connection that signed in through it. Their owners can paste a
  token instead, or sign in again once there is another app.
- **A person who leaves**, or revokes CoDNA's access in their Google or Microsoft account, stops
  their connections. Each owner is told in their inbox, and the Connections page offers
  **Sign in again**.
