# GlobAI OS auth.md — agent authentication

This document tells AI agents (and their operators) how to obtain and use credentials
for the GlobAI OS platform. Every environment has its own base domain `<base>`: the
web console lives at `os.<base>`, the API at `api.os.<base>` (REST routes under `/v1`),
and the identity provider at `auth.os.<base>`. The host serving this file is the
console, `os.<base>`; derive the sibling hosts from it.

## Discovery metadata

- Authorization-server metadata (RFC 8414):
  `https://api.os.<base>/.well-known/oauth-authorization-server`
  (OpenID Connect discovery: `https://api.os.<base>/.well-known/openid-configuration`)
- Protected-resource metadata (RFC 9728):
  `/.well-known/oauth-protected-resource` on this host; the MCP servers publish their
  own at `https://api.os.<base>/.well-known/oauth-protected-resource`
- API catalog (RFC 9727): `/.well-known/api-catalog` on this host

## Authenticating without registering

The platform has no dynamic client registration and no agent self-registration: an
agent never registers itself. Which credential it uses depends on what it calls:

1. **The REST API** — an operator-issued API key (Option 1 below), or a token from an
   OAuth client an operator registered for the agent (Option 2 below).
2. **The MCP servers** — the same API key, or OAuth with the shared public client: use
   the client id `mcp`, a public PKCE client (`token_endpoint_auth_method: none`, grant
   types `authorization_code` and `refresh_token`, a loopback `redirect_uri`). Request
   the scopes `mcp.tools offline_access`; a user signs in and authorizes the agent, and
   the token acts on that user's behalf on the MCP servers only. See Option 2 below.

## Option 1 — API key (recommended for autonomous agents)

Agent registration is operator-mediated: a human with access to the GlobAI OS console
issues an API key bound to an organization, and optionally to one of its projects. The key
carries exactly one role, chosen at creation (an organization role for an organization key,
a project role for a project key), and is authorized as its own principal, never as the
person who created it.

Use the key on every request:

```
GET https://api.os.<base>/v1/orgs/<orgId>/projects
X-API-Key: <your key>
```

## Option 2 — OAuth 2.0 authorization code + PKCE

For user-delegated access, run the authorization-code flow with PKCE (`S256` only)
against the endpoints advertised in the authorization-server metadata above.

- **MCP servers only:** the shared public client id `mcp`, with no client secret, and
  the scopes `mcp.tools offline_access`. Every token of the `mcp` client, and every
  token granted the `mcp.tools` scope, is bound to an MCP resource, whatever other
  scopes it asks for, and is refused on the REST API with a 401.
- **REST API:** a client an operator registered for the agent; a confidential one posts
  its secret (`client_secret_post`). Ask only for the scopes the operator allowed for the
  client (its `allowedScopes`, set with `POST /v1/orgs/<orgId>/oauth-clients` or
  `PATCH /v1/orgs/<orgId>/oauth-clients/<clientId>`; a new client allows none), and `offline_access` must be among them for a refresh token.
  Any other scope is refused with `invalid_scope`. Do not ask for `mcp.tools`, and send
  no MCP `resource`.

## MCP access

MCP servers live at `https://api.os.<base>/v1/mcp/<hub>/<plane>`
(hubs: `agentic`, `intelligence`, `corporate`; planes: `run`, `build`) over the
Streamable HTTP transport. Send a Bearer token (JWT or API key) carrying the
`mcp.tools` scope. Tokens that carry an `aud` claim must be bound to the MCP resource
`https://api.os.<base>/v1/mcp` (RFC 8707 resource indicators). A token for the shared
client `mcp` or the `mcp.tools` scope gets that resource as its `aud` even when the request
names none (see Option 2).

## Session security

Interactive users authenticate through the identity provider at
`auth.os.<base>` (OpenID Connect). Agents should prefer API keys or the
PKCE flow above; never scrape or replay browser sessions.
