# Connect Microsoft and Google

> Canonical HTML: https://screenrig.ai/docs/connections

A connection is your project's saved access to Microsoft or Google, for work that runs with nobody signed in. Meeting-room sources, Power BI dashboards and SharePoint or OneDrive media sync name a connection instead of each carrying a tenant, a client ID and a secret. Make it once and point any of them at it.

## How a connection works

- **Provider and mode.** `provider` is `microsoft` or `google`. `mode` is `own_app`, your own Microsoft Entra app or Google service account, or `screenrig_app`, screenRIG's app, which a Microsoft 365 administrator or a Google account holder approves.
- **Status.** A connection waits in `pending_consent` until someone approves screenRIG's app. It is `ready` while it holds credentials the last attempt did not refuse, and `error` when Microsoft or Google refused them: `last_error` says why, and a later success returns it to `ready`. A throttle or an outage changes nothing.
- **Secrets stay sealed.** A secret, a key or a refresh token is never shown again. A read shows whether one is held and a hint: the last four characters of a Microsoft client secret, or the address of a Google service account.
- **Test it.** A test signs in and keeps the result. For Microsoft it also lists the Graph application permissions the sign-in carries.
- **Change it.** Changing an own app's credentials returns the connection to `ready` and clears its last error. A connection in screenRIG's app mode can only be renamed: ask for a new consent link to change who approved it.
- **Delete it.** A delete is refused (`resource_conflict`) while a source, a Power BI connection or a media sync account reads through the connection. It does not end the vendor's side: the tenant keeps screenRIG's app until an administrator removes it, and a Google account keeps its grant until its holder revokes it.
- **Limit.** An organization has up to 50 connections across its projects.

## Your own app or screenRIG's app

| | Your own app | screenRIG's app |
| --- | --- | --- |
| You give | For Microsoft, the tenant, the client ID and a client secret. For Google, a service account's JSON key | Nothing: screenRIG answers with a one-time consent link |
| Who approves | You, when you register the app and grant it access | A Microsoft 365 administrator, or the Google account holder, who opens the link |
| What it reads | What you grant the app | For Microsoft, what the administrator approved, which you can narrow. For Google, the calendars the approving account can see, read-only |
| Power BI | Works | Refused: use your own app for Power BI |

## Microsoft

### Your own app

Register an app in the Microsoft Entra admin center, add a client secret (copy its value, not its ID), give the app the application permissions below and grant admin consent. Create the connection with the directory ID or primary domain as `config.tenant_id` (`common`, `organizations` and `consumers` are refused), the app's application ID as `config.client_id` and the client secret value as `secret`.

### screenRIG's app, with admin consent

Create the connection in mode `screenrig_app`, with no settings and no secret. The answer carries `consent_url`, a one-time link that works for 24 hours. Send it to a Microsoft 365 administrator and nobody else: it is the credential of that one consent.

1. The administrator opens the link and approves screenRIG's app for the tenant.
2. Microsoft returns to screenRIG, which asks the administrator to sign in to that tenant. The connection records the tenant that signed in, never one a request only claims.
3. screenRIG signs in to the tenant once with the permission it was given. The connection becomes `ready`.

A link works once. A newer link, a finished consent or a delete ends an older one, and you can ask for a new link at any time: to renew a connection that moved to `error`, or to attach another tenant. If the administrator declines or the sign-in does not complete, the connection records `consent_denied` or `consent_failed` (with Microsoft's `AADSTS` code) and keeps its pending consent, so the same link can be opened again. A connection that already works is never degraded by a declined second consent. If the tenant removes screenRIG's app, the connection reads `consent_revoked`: ask an administrator to approve again.

Approval is per tenant. Once an administrator has approved screenRIG's app, anyone who can sign in to the tenant can connect it to a project of their own, so narrow what the app can read, as below. Deleting the enterprise application in Microsoft Entra ends the access of every project.

### What the app can read

| Use | Permission | Notes |
| --- | --- | --- |
| Room calendars | `Calendars.Read` | Limit it to a mail-enabled security group of the room mailboxes with `New-ApplicationAccessPolicy -AccessRight RestrictAccess` |
| Room count, optional | `Place.Read.All` | A source test counts the rooms your organization lists |
| SharePoint and OneDrive media sync | `Sites.Selected` | Then one `read` grant for each site (`POST /v1.0/sites/{site-id}/permissions`). `Files.Read.All` and `Sites.Read.All` read every site and are not requested |
| Power BI | None for Microsoft Graph | Power BI's own tenant settings and workspace membership apply |

A connection test lists which of these the sign-in carries. It warns when only `Sites.Selected` is held, because each site still needs its grant, and it fails when none is.

## Google

### Your own app

Create a service account in Google Cloud, enable the Google Calendar API and download its JSON key (at most 16 KiB). Give the connection the whole file as `secret`: screenRIG checks it when you save. Then share each room calendar with the service account's address, or turn on domain-wide delegation for the account in the Admin console with the scope `https://www.googleapis.com/auth/calendar.events.readonly` and name a `subject` on the source.

### screenRIG's app

The consent link opens Google's consent page. The account holder grants read-only access to calendar events (the scope `calendar.events.readonly`, with `openid` and `email` so screenRIG learns which account approved). If the person unticks the calendar permission, the consent fails. A source reads the calendars that account can see, so the account has to see every room calendar the source lists, and a source of such a connection cannot name a `subject`. When Google stops honoring the grant, the connection reads `reconnect_required`: ask for a new link.

## Use a connection

- **Meeting-room sources.** Set `connection_id` on a `microsoft365` or `google_calendar` [source](https://screenrig.ai/docs/sources.md#meeting-rooms) in place of `tenant`, `client_id` and `client_secret`, or `service_account_key`. Either mode works. Inline credentials keep working, and cannot be mixed with `connection_id`.
- **SharePoint and OneDrive media sync.** A Microsoft 365 sync account takes `connection_id` in place of `tenant_id`, `client_id` and `secret`.
- **Power BI.** A Power BI connection takes the `connection_id` of a Microsoft connection in mode `own_app`, in place of its own tenant, client ID and secret. Microsoft does not describe an app of another tenant generating embed tokens in a customer's tenant, so screenRIG's app is refused for Power BI. A Power BI administrator still enables the service principal settings and adds the app to each workspace.

A source whose connection is missing, waiting for approval or of the other provider reports `config_invalid`. When Microsoft or Google refuses the sign-in the source reports `auth_failed` and the connection moves to `error`.

## Create one

Create a connection in the dashboard, or with `POST /api/connections`. For your own Microsoft app:

```json
{
  "provider": "microsoft",
  "mode": "own_app",
  "name": "Contoso rooms",
  "config": {"tenant_id": "contoso.com", "client_id": "CLIENT_ID"},
  "secret": "CLIENT_SECRET_VALUE"
}
```

For screenRIG's app, with no settings and no secret:

```json
{"provider": "google", "mode": "screenrig_app", "name": "Campus rooms"}
```

The answer to the second carries `consent_url` and `consent_expires_at`: send the link to the person who approves. `POST /api/connections/ID/connect` makes a new link, and `POST /api/connections/ID/test` signs in and keeps the result. Keep secrets in the request file, not on the command line.

[`connection_app_not_configured`](https://screenrig.ai/problems/connection-app-not-configured) means the server has no screenRIG app for that provider: create the connection with your own app. [`connection_limit_reached`](https://screenrig.ai/problems/connection-limit-reached) means the organization has 50: delete one nothing reads through, or reuse an existing connection.

## Related

- [Data sources](https://screenrig.ai/docs/sources.md): the room sources that use a connection.
- [API reference](https://screenrig.ai/docs/api#group-connections): every connection route.
- [Single sign-on](https://screenrig.ai/docs/single-sign-on.md): how people sign in. A connection is for work that runs with nobody signed in.
