# auth.md

You are an AI agent. This document tells you how to register for and
authenticate against Economico's agent-native API — MCP at `https://economi.co/mcp`
and REST at `https://economi.co/v1`. Economico is a general ledger and CRM: one
account is one business.

Authentication is **OAuth 2.1**. There are two paths — pick one.

**New account signups are temporarily paused.** Existing Economico users can
continue to authenticate. A new email cannot create a business until signups
reopen.

## Interactive (a human owns the account)

Use this when a person is present to sign in. It is the standard MCP OAuth
discovery flow, and most MCP clients run it automatically.

1. Call `https://economi.co/mcp` with no bearer token. You get `401` with a
   `WWW-Authenticate: Bearer resource_metadata="https://economi.co/.well-known/oauth-protected-resource"`
   header.
2. Fetch that Protected Resource Metadata, then the Authorization Server
   metadata at `https://economi.co/.well-known/oauth-authorization-server`.
3. Register a client with RFC 7591 Dynamic Client Registration:
   `POST https://economi.co/oauth/register`.
4. Send the user to the authorization endpoint `https://economi.co/oauth/authorize` with PKCE
   (`code_challenge_method=S256`). An existing user signs in with a
   one-time code emailed to them and approves your client. New emails cannot
   create a business while signups are paused.
5. Exchange the returned `code` at `https://economi.co/oauth/token`
   (`grant_type=authorization_code`) for an access token and refresh token.

## Headless (an agent runs unattended)

Use this for a service that already owns a business account. The owner first
registers your client's public JWKS at `POST https://economi.co/v1/oauth/clients`
(authenticated as the owner), then:

1. `POST https://economi.co/oauth/token` with `grant_type=client_credentials`,
   `client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer`,
   and a `client_assertion` JWT signed by your registered key (RFC 7523
   private_key_jwt).

## Using the credential

- The access token is a short-lived (1 hour) RS256 `at+jwt` **bearer**
  token. Send it as `Authorization: Bearer <token>` on every
  `https://economi.co/mcp` and `https://economi.co/v1/*` request. Scope: `mcp`.
- Refresh with `grant_type=refresh_token` at `https://economi.co/oauth/token`. Refresh
  tokens are single-use and rotate; replaying a consumed one revokes the whole
  family.

## Revocation

An account owner revokes a headless client with
`DELETE https://economi.co/v1/oauth/clients/{client_id}`. Existing access tokens stay
valid until they expire (at most 1 hour); new token requests with that client
fail with `invalid_client`.

Machine-readable discovery for all of the above lives in the `agent_auth`
block of `https://economi.co/.well-known/oauth-authorization-server`.
