# Sign agents in with access you control

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

Every agent, app and script that works on your screens signs in with its own
session. A person approves each one in the dashboard, chooses Read only or
Manage, and can end it from the Access page at any time.

## How sign-in works

screenRIG issues short-lived signed access tokens and long-lived refresh
tokens. The bundled CLI keeps both in its private config file and renews them
on its own, so an agent never handles a token and never pastes one into a
conversation.

| Credential | Lifetime |
| --- | --- |
| Access token | 15 minutes |
| Refresh token | Rotates on every use. It ends 90 days after its last use, and at most one year after sign-in. |
| Sign-in code (`screenrig login`) | 10 minutes |
| Service client token | 15 minutes, with no refresh token: the client asks for a new one |

There are four ways in:

| Who | How it signs in | Approved by |
| --- | --- | --- |
| A new agent with no account | `screenrig agent enroll` creates the organization, the Screens project and the session in one command | Enrollment itself; the person's emailed invitation follows |
| An agent for an existing account | `screenrig login` prints a code that a person approves in the dashboard | A project member, in the dashboard |
| A connected app (Claude, ChatGPT, Grok) | The app opens the screenRIG consent page; see [remote server](https://screenrig.ai/docs/mcp.md#connect-with-oauth) | A project member, on the consent page |
| A server, script or CI job | A [service client](https://screenrig.ai/docs/service-clients.md) signs in with its own key or secret | Created by a project member |

## Sign in with `screenrig login`

Use `screenrig login` when the person already has screenRIG and wants this
agent installation to work in one of their projects. A new installation with
no account starts with `screenrig agent enroll` instead; see
[Start](https://screenrig.ai/docs/start.md).

```sh
screenrig login
```

1. The CLI prints a dashboard address and an eight-letter code such as
   `BCDF-GHJK`, then waits.
2. The person opens `https://screenrig.ai/dashboard/connect`, signs in, and
   enters the code, or follows the full link that already carries it.
3. The dashboard shows the request: the installation name the device reported,
   when and where it asked, and the code. The person checks that the code
   matches the terminal, chooses the project, the access level and the
   capabilities, and approves with their passkey or password.
4. The CLI stores the session, selects the approved project and reports
   `status: signed_in` with the project, organization and access level.

Approve only a sign-in you started yourself, on your own computer, in the last
10 minutes. The dashboard never approves anything on load, and an expired code
needs a new `screenrig login`.

| Flag | Effect |
| --- | --- |
| `--access read` or `--access manage` | Ask for Read only or Manage. The default is `manage`; the person makes the final choice. |
| `--project prj_ID` | Suggest the project the person approves. |
| `--name NAME` | Name this installation, up to 80 characters. |
| `--no-wait` | Return at once with the address, the code and a `login_` handle. |
| `--resume login_ID` | Wait for that pending sign-in to be approved and store its session. |

When the agent has to pass the address to a person in another channel first,
use `--no-wait`. The handle holds no secret, and the pending sign-in stays in
the private config file:

```sh
screenrig login --no-wait
screenrig login --resume login_HANDLE
```

The sign-in address and its code are for the person who approves it. Send them
only to that person, and keep them out of logs and shared channels.

### Add a project or raise access

An installation that is already signed in runs `screenrig login` again to add
another project, or to raise a Read only project to Manage:

```sh
screenrig login --project prj_ID --access manage
```

The person approves that one change, and the installation keeps its other
projects. `screenrig project list` shows every project the installation can
use, and `screenrig project use ID` selects one.

## Read only and Manage

Every session carries one of two access levels, chosen by the person who
approves it.

| | Read only | Manage |
| --- | --- | --- |
| List and read screens, playlists, media, events and playback | Yes | Yes |
| Change, publish, pair, send screenshots or toasts, write application K/V | No | Yes |
| Spend credit on purchases, campaigns or image generation | No | Yes |
| Read webhook receiver URLs | No: the URL reads as redacted | Yes |
| Billed per request like every agent request | Yes | Yes |

Read only means the session cannot change or buy anything. It does not mean
free: each agent request and billed listen-stream event counts against the
project's [included requests](https://screenrig.ai/pricing.md), as it does for
Manage.

A Read only session that tries a change gets `403 insufficient_access`. The CLI
names the next step: a person approves Manage with
`screenrig login --access manage`.

Agent sign-ins default to Manage, and connected apps to Read only. To lower an
installation from Manage to Read only, disconnect it, then sign in again with
`screenrig login --access read`. A level is never lowered silently.

### Capabilities

Within its access level, a session works only in the capability areas the
person approved: `screens`, `content`, `playlists`, `advertising`, `reports`
and `project`. Enrollment grants all six on the project it creates. A command
outside the approved areas returns `403 forbidden` naming the missing
capability. Capabilities stay as approved for an installation's project; for
more, a person approves a new installation that has them.

## The Access page

The dashboard's [Access](https://screenrig.ai/dashboard/access) page lists
everything that can act on the current project:

| Section | What it lists |
| --- | --- |
| Pending | Sign-ins and connection requests waiting for approval |
| People | Members and open invitations |
| Agents | CLI and plugin installations, enrolled or signed in |
| Connected apps | AI assistants a person connected, one entry per app |
| Service clients | Servers, scripts and CI jobs, with their keys and secrets |

Each entry shows how it got access and who approved it, its access level and
capabilities, and when it was created and last used. **Disconnect** ends an
agent or app; **Revoke** ends a service client. Each asks the person to confirm
with their passkey or password.

## Sign out and revoke

| To end | Run or do |
| --- | --- |
| This installation's sign-in | `screenrig logout` |
| This installation's access to the current project | `screenrig agent disconnect --yes` |
| This installation everywhere | `screenrig agent revoke-identity --yes` |
| Any agent or connected app | **Disconnect** on the Access page |
| A service client | **Revoke** on the Access page, or `screenrig service-client revoke ID --yes` |

`screenrig logout` revokes the sign-in on the server, then removes the stored
tokens. If the request might not have reached the server, the tokens stay, so
running it again is safe. A Read only session can always disconnect itself.

A revoked session cannot renew: no new token is issued after the revoke. Its
access tokens stop working within seconds. Deactivating the person responsible
for an agent ends its sessions the same way, and deleting a project ends every
session's access to that project.

## Session length

Each use of the refresh token moves its end 90 days forward, up to one year
after sign-in. `screenrig doctor` shows when this installation's session ends,
and every command warns in its last 30 days. To continue, a person approves a new
`screenrig login`.

## Existing credentials

Installations that signed in before these sessions keep working. On its next
command, the bundled CLI exchanges the stored credential for a session with the
same projects and capabilities, without a prompt and without output. Update the
official plugin to get that CLI; nothing else changes for the agent.

## Reference

These endpoints follow OAuth 2.0. The bundled CLI, connected apps and service
clients use them; an agent working through the plugin never calls them
directly.

| Item | Value |
| --- | --- |
| Issuer | `https://api.screenrig.ai` |
| Authorization server metadata | `https://api.screenrig.ai/.well-known/oauth-authorization-server` |
| Protected resource metadata | `https://api.screenrig.ai/.well-known/oauth-protected-resource/api` |
| Token endpoint | `https://api.screenrig.ai/oauth/token` |
| Device authorization | `https://api.screenrig.ai/oauth/device_authorization` |
| Authorization endpoint | `https://api.screenrig.ai/oauth/authorize` |
| Revocation | `https://api.screenrig.ai/oauth/revoke` |
| Grant types | `authorization_code` (PKCE `S256` only), `refresh_token`, `urn:ietf:params:oauth:grant-type:device_code`, `client_credentials`, `urn:ietf:params:oauth:grant-type:token-exchange` |
| Client authentication | `none`, `private_key_jwt` (`EdDSA`, `ES256`, `RS256`), `client_secret_basic` |
| Scopes | `access:read`, `access:manage`, `identity`, and the capabilities `screens`, `content`, `playlists`, `advertising`, `reports`, `project` |
| Resources | `https://api.screenrig.ai/api` (the default) and `https://api.screenrig.ai/mcp` |

Access tokens are JWTs signed with Ed25519 (`EdDSA`): an EdDSA-only profile
using the claim conventions of RFC 9068 (`typ: at+jwt`, `iss`, `aud`, `sub`,
`client_id`, `scope`, `jti`, `iat`, `exp`). Treat them as opaque: send each one
as `Authorization: Bearer` and request a new one when it expires.

Token endpoint errors are RFC 6749 JSON (`error`, `error_description`) with
`Cache-Control: no-store`:

| `error` | Meaning | CLI problem |
| --- | --- | --- |
| `invalid_grant` | The session was revoked, expired or reused, or a code is wrong | `session_ended`: run `screenrig login` |
| `invalid_client` | Unknown client, or a wrong key, secret or assertion | `client_auth_failed` |
| `invalid_scope` | More access or capabilities than were approved | `insufficient_access` |
| `invalid_target` | A `resource` other than the two above | `invalid_request` |
| `authorization_pending`, `slow_down` | A sign-in still waiting for approval | The CLI keeps waiting |
| `access_denied` | The person denied the sign-in | `login_denied` |
| `expired_token` | The sign-in code expired | `login_expired`: run `screenrig login` |
| `temporarily_unavailable` | Try again shortly | `service_unavailable` |
| `rate_limited` | Wait for `Retry-After` | `rate_limited` |

Requests to `/api` with an expired or revoked access token answer `401` with
`WWW-Authenticate: Bearer error="invalid_token"`; the CLI renews once and
retries once. A Read only token calling a change answers `403`
`insufficient_access` with
`WWW-Authenticate: Bearer error="insufficient_scope", scope="access:manage"`.

The token and revocation endpoints accept 1,200 requests per client address per
hour, 60 renewals per session per hour and 600 service-client tokens per client
per hour. Sign-in starts are limited to 10 per address per hour.

## Related

- [Start](https://screenrig.ai/docs/start.md): install the official plugin and create a project.
- [Service clients](https://screenrig.ai/docs/service-clients.md): sign servers, scripts and CI jobs in with client credentials.
- [CLI reference](https://screenrig.ai/docs/cli.md#sign-in): `login`, `logout` and the agent commands.
- [Remote server](https://screenrig.ai/docs/mcp.md): connect Claude, ChatGPT or Grok.
