# Overskill auth.md

This document is for **autonomous agents** (and the developers building
them) that need to authenticate against the Overskill API. It is the
human-readable companion to the machine-readable discovery documents:

- **OAuth Authorization Server Metadata** (RFC 8414):
  `https://www.overskill.com/.well-known/oauth-authorization-server`
  — also carries the structured `agent_auth` block.
- **OAuth Protected Resource Metadata** (RFC 9728):
  `https://www.overskill.com/.well-known/oauth-protected-resource`
- **MCP Server Card** (SEP-1649):
  `https://www.overskill.com/.well-known/mcp/server-card.json`

## Audience

You are an AI agent that wants to read or build apps on Overskill on
behalf of a user. You must authenticate: every build runs inside a team
and spends that team's credits, so there is no unauthenticated build
flow. Unauthenticated agents get discovery and docs only.

## What we support

- **OAuth 2.0 Authorization Code + PKCE** (`S256`) — the recommended
  flow for agents acting on behalf of a user.
- **Refresh tokens** (`grant_type=refresh_token`) — access tokens last
  24 hours; a long-running agent renews its own instead of sending the
  user back through consent. Public PKCE clients included.
- **Opaque bearer tokens** — present the access token as
  `Authorization: Bearer <token>` on every API request.
- **API keys** — alternatively send `X-API-Key: <key>` for
  server-to-server access. Obtain one at `https://www.overskill.com/account/api_keys`.

We implement **Dynamic Client Registration** (RFC 7591) at
`https://www.overskill.com/oauth/register` for hosted MCP clients of any vendor.
Registration always mints a **public PKCE** client
(`token_endpoint_auth_method=none`). Generated Overskill apps stay
first-class OAuth clients and are not created through this endpoint.
We do **not** implement ID-JAG or anonymous / ephemeral identity tokens.

Hosted MCP hosts may either:

1. POST to `https://www.overskill.com/oauth/register` with `redirect_uris` and then
   use the returned `client_id`, or
2. Use the published static client `client_id=overskill-mcp-server` when
   they already know it (CLI / a host config that carries a client id).

## Provisioning / registration

1. If you do not already have a client id, POST JSON to
   `https://www.overskill.com/oauth/register` with `redirect_uris` (https, http on
   loopback, or a native `scheme://host/…` URI) and
   `token_endpoint_auth_method=none`. Extra fields such as
   `grant_types` are ignored.
2. Direct the user's browser to the authorize endpoint:
   `https://www.overskill.com/oauth/authorize`
   with `response_type=code`, your `client_id`, `redirect_uri`,
   `scope`, `code_challenge`, and `code_challenge_method=S256`.
3. Exchange the returned `code` at the token endpoint:
   `https://www.overskill.com/oauth/token`
   with `grant_type=authorization_code` and your PKCE `code_verifier`.
   Public clients send `client_id` and no client secret.
4. Present `Authorization: Bearer <access_token>` on `/mcp`.
5. **Persist the `refresh_token` from step 3.** The access token expires
   in 24 hours; when it does (or on a `401`), POST to
   `https://www.overskill.com/oauth/token` with `grant_type=refresh_token`, your
   `refresh_token` and your `client_id` — no client secret. You get a
   new access token and a **new refresh token**: store it and discard
   the old one, which is revoked the moment it is used. Replaying a
   used refresh token returns `400 invalid_grant`, and so does refreshing
   after the connection is revoked — start a new authorization request.

## Scopes

| Scope        | Grants                                         |
|--------------|------------------------------------------------|
| `read`       | Read access to apps and resources              |
| `write`      | Write access to apps and resources             |
| `apps:read`  | Read access to apps only                       |
| `apps:write` | Write access to apps only                      |

## Using the credential

Send the bearer token on every authenticated request:

```
Authorization: Bearer <access_token>
```

## Identity assertions

Overskill verifies end-user email addresses through Google and GitHub
SSO. When a user authenticates via a provider that asserts the email is
verified, Overskill treats that identity as **`verified_email`**. This
is the identity assertion exposed under
`agent_auth.identity_assertions.verified_email` in the OAuth
Authorization Server Metadata document. We make no claims we cannot
back: only `verified_email` and standard OAuth bearer identity.

## See also

- Developer docs: `https://www.overskill.com/developers`
- Agent overview: `https://www.overskill.com/agents`
- SKILL.md: `https://www.overskill.com/SKILL.md`
