# auth.md

You are an agent. **Glory To Glory CPA Limited** (`https://g2gcpa.com`) supports agentic registration for its **public discovery API**. Follow: discover → register → (claim if needed) → use credential → handle revocation.

Audience: AI agents that need machine-readable firm facts (services, contact, OpenAPI). This is **not** a client portal; credentials grant `public:read` only. No confidential client data is exposed.

## Step 1 — Discover

### 1a. Protected Resource Metadata (RFC 9728)

```http
GET https://g2gcpa.com/.well-known/oauth-protected-resource
```

```json
{
  "resource": "https://g2gcpa.com/api/",
  "resource_name": "Glory To Glory CPA Limited Public Discovery API",
  "authorization_servers": ["https://g2gcpa.com"],
  "scopes_supported": ["public:read"],
  "bearer_methods_supported": ["header"]
}
```

### 1b. Authorization Server metadata (RFC 8414 + agent_auth)

```http
GET https://g2gcpa.com/.well-known/oauth-authorization-server
```

Read `issuer`, `token_endpoint`, `revocation_endpoint`, `grant_types_supported`, and the full `agent_auth` block (`skill`, `register_uri`, `claim_uri`, `revocation_uri`, `identity_types_supported`).

## Step 2 — Pick a method

1. **Anonymous** (recommended for public firm data) → no user identity required.
2. **Verified email** (`identity_assertion` + `verified_email`) → claim ceremony so a human can attach an email.
3. **ID-JAG** (`identity_assertion` + `urn:ietf:params:oauth:token-type:id-jag`) → if your agent provider can mint an audience-bound assertion for `https://g2gcpa.com/api/`.

## Step 3 — Register

`POST` JSON to `agent_auth.register_uri` (`https://g2gcpa.com/agent/auth`).

### anonymous

```http
POST /agent/auth
Content-Type: application/json

{
  "type": "anonymous",
  "requested_credential_type": "access_token",
  "requested_scopes": ["public:read"]
}
```

Success:

```json
{
  "type": "anonymous",
  "credential_type": "access_token",
  "credential": "g2g-public-read",
  "token_type": "Bearer",
  "expires_in": 86400,
  "scope": "public:read",
  "claim_required": false,
  "claim_uri": "https://g2gcpa.com/agent/auth/claim",
  "resource": "https://g2gcpa.com/api/"
}
```

You may also request `"requested_credential_type": "api_key"`; the same public read key is returned as `credential`.

### identity_assertion + verified_email

```http
POST /agent/auth
Content-Type: application/json

{
  "type": "identity_assertion",
  "assertion_type": "verified_email",
  "login_hint": "user@example.com",
  "requested_credential_type": "access_token",
  "requested_scopes": ["public:read"]
}
```

Success starts a claim ceremony (`claim_token`, `user_code`, `verification_uri`). Complete claim at `claim_uri`, then use the issued credential.

### identity_assertion + ID-JAG

```http
POST /agent/auth
Content-Type: application/json

{
  "type": "identity_assertion",
  "assertion_type": "urn:ietf:params:oauth:token-type:id-jag",
  "assertion": "<id-jag-jwt>",
  "requested_credential_type": "access_token",
  "requested_scopes": ["public:read"]
}
```

If the assertion cannot be verified, the server returns `400` with `error: invalid_assertion`. Prefer **anonymous** for this public discovery API.

## Step 4 — Claim (optional)

When registration returns a claim ceremony (verified email / deferred ownership):

```http
POST /agent/auth/claim
Content-Type: application/json

{
  "claim_token": "<claim_token>",
  "email": "user@example.com"
}
```

Humans complete ownership at the returned `verification_uri` using `user_code`. For this public API, claim is informational; anonymous credentials already work for `public:read`.

## Step 5 — Use the credential

```http
GET https://g2gcpa.com/api/firm
Authorization: Bearer g2g-public-read
```

Public endpoints also work without a token. Prefer Bearer when calling as a registered agent.

Useful resources:

- OpenAPI: `https://g2gcpa.com/api/openapi.json`
- Status: `https://g2gcpa.com/api/status`
- Firm facts: `https://g2gcpa.com/api/firm`
- LLM index: `https://g2gcpa.com/llms.txt`

## Step 6 — Revocation

```http
POST /agent/auth/revoke
Content-Type: application/json

{
  "token": "g2g-public-read",
  "token_type_hint": "access_token"
}
```

Or RFC 7009 form POST to `https://g2gcpa.com/oauth/revoke`. On `401` with a previously working credential, drop it and restart at Step 1.

## Notes

- Issuer: `https://g2gcpa.com`
- Scope: `public:read` only
- Contact: info@g2gcpa.com · +852-6323-8642
- Protocol docs: https://workos.com/auth-md · https://github.com/workos/auth.md
