# Auth.md

## Agent registration at Data Jockey

Most of this site is open. Read anything through the MCP server at https://datajockey.us/mcp
or the JSON API at https://datajockey.us/agent/v1 without registering, without a token, and
without telling us who you are.

You need a token for one thing: sending an enquiry to Data Jockey. That reaches a
real inbox that a person reads, which is why it is gated.

## What you get

An OAuth 2.1 access token, valid for one hour, carrying the scopes you were
granted. Supported scopes are openid, email, inquiry:write.

- `inquiry:write` lets you call `submit_inquiry` on the MCP server, or
  POST https://datajockey.us/agent/v1/inquiries.
- `openid` adds an ID token.
- `email` puts the address your principal typed into that ID token.

## What the identity claim is worth

Very little, and deliberately so. The person approving the grant types their own
email address at the consent screen. Data Jockey sends no confirmation to it and
checks nothing. Every ID token therefore carries `email_verified: false`.

Treat the email as a reply-to address rather than as proof of identity. If you
need a verified identity, this is not the server to get it from.

## Registering

Dynamic client registration is open, per RFC 7591.

```
POST https://datajockey.us/oauth/register
Content-Type: application/json

{
  "client_name": "Your agent",
  "redirect_uris": ["https://your-agent.example/callback"],
  "scope": "inquiry:write openid email"
}
```

Redirect URIs must use https, or point at loopback for a local client. The
`client_id` you get back is a signed token rather than a database row, so there
is nothing to look up and nothing stored about you. It is valid for a year.

## The flow

1. Send your user to https://datajockey.us/oauth/authorize with `response_type=code`,
   your `client_id`, a registered `redirect_uri`, a `state`, and a PKCE
   `code_challenge` with `code_challenge_method=S256`. The plain PKCE method
   is rejected.
2. They see what you are asking for and type their email.
3. You receive a `code` at your redirect URI. It lives for sixty seconds.
4. Exchange it at https://datajockey.us/oauth/token with `grant_type=authorization_code`,
   the `code`, your `code_verifier`, `client_id` and `redirect_uri`.
   There is no client secret, because every client here is public.
5. Send the access token as `Authorization: Bearer <token>`.

## Discovery

- Authorization server metadata: https://datajockey.us/.well-known/oauth-authorization-server
- OpenID configuration: https://datajockey.us/.well-known/openid-configuration
- Protected resource metadata: https://datajockey.us/.well-known/oauth-protected-resource
- Verification keys: https://datajockey.us/.well-known/jwks.json

A 401 from any protected endpoint carries a `WWW-Authenticate` header naming
the protected resource metadata, so you can start from a failed request rather
than from this page.

## What we do with an enquiry

It is emailed to Data Jockey and read by a person. It is not added to a marketing
list, and the address is not sold or shared. If you would rather book directly,
the calendar is at https://datajockey.us/book and needs no token at all.
