# IOI delegated registration status

Public industry research, catalogs, MCP and A2A remain open. OAuth is optional and protects only GET /oauth/registration-status, not the public catalog.

Issuer: https://www.industriesofindia.com
Discovery: /.well-known/oauth-authorization-server
Resource server identifier: https://www.industriesofindia.com
Protected endpoint: https://www.industriesofindia.com/oauth/registration-status
Compatibility path-specific resource identifier: https://www.industriesofindia.com/oauth/registration-status
Scope: registration.status.read

## Register a public client
POST /oauth/register with application/json, client_name, one redirect_uris HTTPS URL, token_endpoint_auth_method none. Redirect must have no query/fragment/credentials/port; exact match required. Client registration expires after30days. No client secret. Maximum20newclients/hour globally.

## Authorization
Send the claimant to /oauth/authorize with response_type=code, client_id, exact redirect_uri, scope=registration.status.read, resource=https://www.industriesofindia.com, state(random at least16characters), code_challenge(base64url SHA256of verifier), code_challenge_method=S256.

The claimant signs in with the private confirmation link from their already-confirmed registration email and explicitly approves the named app, return address and scope. Anonymous agent token or claim start token cannot sign in. The private email link is a bearer login credential; keep it private. It is never sent to the third-party app. No extra login emails are sent. The existing registration lasts24hours. Its private email link is valid for this sign-in only while the verified registration remains active. Cancel grants nothing.

The app receives code,state,iss through the exact registered return URI. Verify state and issuer. Exchange code at POST /oauth/token using form-urlencoded or JSON: grant_type=authorization_code,code,client_id,redirect_uri,code_verifier,resource. Authorization codes expire after120seconds, are single-use and bound to client,redirect and S256challenge. Access token is Ed25519-signed JWT with issuer,audience,client,scope,jti,exp. Verify via /.well-known/oauth-jwks.json. The server additionally requires the hashed token record to be active, so revocation is immediate. Tokens expire after15minutes or the registration expiry, whichever comes first. No refresh,implicit,password,client_credentials or IDtokens.

GET /oauth/registration-status with Authorization: Bearer token returns registration ID, claimed flag, creation time and delegated access expiry. It exposes no email, name, claim secret, private link or editing/revocation powers. Invalid tokens return401 with resource_metadata challenge. POST /oauth/revoke with token and client_id revokes only the delegated token. Revoking the underlying registration also invalidates all delegated access. No site editing or delegation of registration revoke.

Cross-origin browser token exchange is not enabled; use an app backend. API POSTs60/IP/hour,2000global/hour; caps fail closed. Free Worker/D1 platform limits can make endpoints temporarily unavailable, never automatically upgrade. Expired rows are cleaned in bounded batches. No usage billing is enabled by these features.

The origin resource identifier names the IOI resource server, not a restriction on every URL. Only registration.status.read at /oauth/registration-status is protected. Public pages, catalogs and research stay open. Origin and path-specific audience identifiers are supported; each authorization code is bound to the exact requested resource and cannot be exchanged for the other audience. The endpoint401 challenge points to its exact path-specific metadata as RFC9728section3.3requires.
