# Robbclan agent enrollment

1. GET /.well-known/agent-enrollment. Check enabled and available plans/cycles/prices.
2. Generate an RSA 2048–4096 bit signing key locally. Keep the private key in your runtime's
   credential store. Submit only the public JWK (kty, n, e, kid, alg=RS256, use=sig).
3. POST /api/agent-enrollments with JSON: agent_name, owner_email, public_jwk, capabilities (discover,
   passage_drafts, learning_drafts), plan, billing_cycle and daily_request_limit (10–1000).
   Send a cryptographically random URL-safe Idempotency-Key of at least 32 characters.
   Optional discovery_source: unknown, direct, recipes, registry, search or other. This is
   self-reported attribution only; it changes neither permissions nor retry identity.
   Keep that key secret: it permits recovery of the same registration response on retry.
   Reuse it only for identical requests. Store returned bootstrap_token securely.
4. Give owner_url to your human owner. The owner signs in or registers, returns to the
   review page, approves permissions for their tenant, and completes Checkout if needed.
   Never automate the owner's login, consent or payment authorization.
5. Poll status_url with Authorization: Bearer <bootstrap_token>, at most every 10 seconds.
   POST activation_url with the same header after owner approval. Activation verifies
   current Stripe subscription state and provisions the service identity. Retry on 503
   with backoff; retries reconcile the same identity. Pending requests expire in 24 hours.
6. Once ready, connection contains client_id, token_endpoint, scopes and mcp_url.
   POST to token_endpoint: grant_type=client_credentials, client_id,
   client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer,
   client_assertion=<RS256 JWT signed locally>, scope=<space-separated scopes>.
   Assertion claims: iss=sub=client_id, aud=token_endpoint, iat=now, exp=now+60,
   jti=new random value on EVERY attempt; header kid matches your submitted public JWK.
7. Connect to mcp_url with Authorization: Bearer <access_token>. Obtain a new access token
   before expiry. Start with tools/list and robbclan_list_workflows. Your MCP runtime must
   support client credentials/private_key_jwt or securely inject the current bearer token.

The agent is a separate Editor service identity, never its owner or a tenant administrator.
Only the exact approved tools are granted. Draft generation may incur model usage. Human
approval between learning stages remains required. No publishing, sending, administration
or external integration consent is granted by enrollment. Company SSO is optional and separate.
The daily limit counts all authenticated MCP HTTP requests, including discovery/polling;
it is not a dollar budget. Existing tenant product quotas still apply. Initial activation
requires an active paid Stripe subscription; no free, trialing or comped activation.
Existing paid subscriptions determine available product access; enrollment never changes
an existing subscription automatically. Owners can revoke access on their review page.
Key rotation requires revoking and enrolling a new key. Bootstrap tokens are not MCP tokens.
