<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     category="std"
     docName="draft-hemanth-oauth-ai-scopes-00"
     ipr="trust200902"
     obsoletes=""
     updates=""
     submissionType="IETF"
     xml:lang="en"
     version="3">

  <front>
    <title abbrev="OAuth AI Scopes">OAuth 2.0 Extension for AI Model Access</title>
    
    <seriesInfo name="Internet-Draft" value="draft-hemanth-oauth-ai-scopes-00"/>
    
    <author fullname="Hemanth HM" initials="H." surname="HM">
      <organization/>
      <address>
        <email>hemanth.hm@gmail.com</email>
        <uri>https://h3manth.com</uri>
      </address>
    </author>
    
    <date year="2024" month="December" day="24"/>
    
    <area>Security</area>
    <workgroup>OAuth Working Group</workgroup>
    
    <keyword>OAuth</keyword>
    <keyword>AI</keyword>
    <keyword>API</keyword>
    <keyword>scopes</keyword>
    <keyword>delegation</keyword>
    
    <abstract>
      <t>This document defines an extension to OAuth 2.0 for delegating scoped 
      access to AI model APIs. It introduces a standardized scope syntax, 
      resource indicators for AI providers, and token constraints suitable 
      for AI workloads including spend limits and model restrictions.</t>
    </abstract>
  </front>

  <middle>
    <section numbered="true" toc="default">
      <name>Introduction</name>
      
      <t>The proliferation of AI model APIs (OpenAI, Anthropic, Google, Mistral, etc.) 
      has created a need for secure delegation of API access. Current approaches 
      involve sharing API keys directly with applications, which:</t>
      
      <ul>
        <li>Exposes master credentials to third parties</li>
        <li>Provides no usage limits or audit trail</li>
        <li>Cannot be scoped to specific models or capabilities</li>
        <li>Cannot be revoked without rotating the master key</li>
      </ul>
      
      <t>This specification extends OAuth 2.0 to address these concerns by defining:</t>
      
      <ol>
        <li>A standard scope syntax for AI model access</li>
        <li>Resource indicators for AI providers</li>
        <li>Token metadata for usage limits and spending caps</li>
        <li>Security considerations specific to AI workloads</li>
      </ol>
      
      <section numbered="true" toc="default">
        <name>Terminology</name>
        <dl>
          <dt>AI Provider</dt>
          <dd>A service offering AI model APIs (e.g., OpenAI, Anthropic)</dd>
          <dt>Model</dt>
          <dd>A specific AI model (e.g., gpt-4, claude-3, gemini-pro)</dd>
          <dt>Capability</dt>
          <dd>A function offered by a model (chat, embeddings, images, audio)</dd>
          <dt>Master Key</dt>
          <dd>The user's API key for a provider</dd>
          <dt>Delegated Token</dt>
          <dd>An OAuth access token with AI-specific scopes</dd>
        </dl>
      </section>
      
      <section numbered="true" toc="default">
        <name>Notational Conventions</name>
        <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 
        "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 
        document are to be interpreted as described in <xref target="RFC2119"/>.</t>
      </section>
    </section>

    <section numbered="true" toc="default">
      <name>Scope Syntax</name>
      
      <section numbered="true" toc="default">
        <name>AI Scope Format</name>
        <t>AI-specific scopes follow this syntax:</t>
        <artwork><![CDATA[
ai:<provider>:<model>:<capability>
        ]]></artwork>
        
        <t>Examples:</t>
        <ul>
          <li><tt>ai:openai:gpt-4:chat</tt> - Chat completions with GPT-4</li>
          <li><tt>ai:anthropic:claude-3-opus:*</tt> - All capabilities for Claude 3 Opus</li>
          <li><tt>ai:openai:*:embeddings</tt> - Embeddings with any OpenAI model</li>
          <li><tt>ai:*:*:chat</tt> - Chat with any provider/model</li>
        </ul>
      </section>
      
      <section numbered="true" toc="default">
        <name>Provider Identifiers</name>
        <table>
          <thead>
            <tr><th>Provider</th><th>Identifier</th></tr>
          </thead>
          <tbody>
            <tr><td>OpenAI</td><td>openai</td></tr>
            <tr><td>Anthropic</td><td>anthropic</td></tr>
            <tr><td>Google AI</td><td>google</td></tr>
            <tr><td>Mistral</td><td>mistral</td></tr>
            <tr><td>Groq</td><td>groq</td></tr>
            <tr><td>Together AI</td><td>together</td></tr>
            <tr><td>Cohere</td><td>cohere</td></tr>
          </tbody>
        </table>
      </section>
      
      <section numbered="true" toc="default">
        <name>Capability Identifiers</name>
        <table>
          <thead>
            <tr><th>Capability</th><th>Description</th></tr>
          </thead>
          <tbody>
            <tr><td>chat</td><td>Chat/text completions</td></tr>
            <tr><td>embeddings</td><td>Vector embeddings</td></tr>
            <tr><td>images</td><td>Image generation</td></tr>
            <tr><td>audio</td><td>Audio transcription/synthesis</td></tr>
            <tr><td>vision</td><td>Multimodal/vision</td></tr>
            <tr><td>code</td><td>Code generation</td></tr>
          </tbody>
        </table>
      </section>
    </section>

    <section numbered="true" toc="default">
      <name>Token Metadata</name>
      
      <section numbered="true" toc="default">
        <name>Token Introspection Response Extensions</name>
        <t>The token introspection response (<xref target="RFC7662"/>) is extended with:</t>
        <sourcecode type="json"><![CDATA[
{
  "active": true,
  "scope": "ai:openai:gpt-4:chat",
  "ai_limits": {
    "monthly_spend_usd": 100.00,
    "daily_spend_usd": 10.00,
    "requests_per_minute": 60,
    "requests_per_day": 1000,
    "max_tokens_per_request": 4096
  },
  "ai_usage": {
    "spend_this_month_usd": 23.45,
    "spend_today_usd": 2.10,
    "requests_this_minute": 3,
    "requests_today": 156
  }
}
        ]]></sourcecode>
      </section>
      
      <section numbered="true" toc="default">
        <name>Limit Fields</name>
        <table>
          <thead>
            <tr><th>Field</th><th>Type</th><th>Description</th></tr>
          </thead>
          <tbody>
            <tr><td>monthly_spend_usd</td><td>number</td><td>Maximum spend per calendar month</td></tr>
            <tr><td>daily_spend_usd</td><td>number</td><td>Maximum spend per day</td></tr>
            <tr><td>requests_per_minute</td><td>integer</td><td>Rate limit (RPM)</td></tr>
            <tr><td>requests_per_day</td><td>integer</td><td>Daily request limit</td></tr>
            <tr><td>max_tokens_per_request</td><td>integer</td><td>Per-request token limit</td></tr>
          </tbody>
        </table>
      </section>
    </section>

    <section numbered="true" toc="default">
      <name>Authorization Request</name>
      
      <section numbered="true" toc="default">
        <name>Additional Parameters</name>
        <table>
          <thead>
            <tr><th>Parameter</th><th>Type</th><th>Description</th></tr>
          </thead>
          <tbody>
            <tr><td>ai_limits</td><td>JSON</td><td>Requested limits (as defined in Section 3.2)</td></tr>
            <tr><td>ai_reason</td><td>string</td><td>Human-readable reason for access</td></tr>
          </tbody>
        </table>
        
        <t>Example authorization request:</t>
        <artwork><![CDATA[
GET /authorize?
  response_type=code&
  client_id=app123&
  scope=ai:openai:gpt-4:chat&
  ai_limits={"monthly_spend_usd":50}&
  ai_reason=Code+assistant+for+IDE
        ]]></artwork>
      </section>
    </section>

    <section numbered="true" toc="default">
      <name>Resource Server Requirements</name>
      
      <section numbered="true" toc="default">
        <name>Proxy Architecture</name>
        <t>The resource server (authorization server or dedicated proxy) MUST:</t>
        <ol>
          <li>Validate the OAuth access token</li>
          <li>Verify the requested operation matches token scopes</li>
          <li>Check usage against token limits</li>
          <li>Substitute the master API key</li>
          <li>Proxy the request to the AI provider</li>
          <li>Log usage for auditing</li>
          <li>Update usage counters</li>
        </ol>
      </section>
      
      <section numbered="true" toc="default">
        <name>Error Responses</name>
        <t>When limits are exceeded:</t>
        <sourcecode type="json"><![CDATA[
{
  "error": "ai_limit_exceeded",
  "error_description": "Daily spend limit of $10.00 exceeded",
  "ai_usage": {
    "spend_today_usd": 10.23,
    "daily_spend_usd": 10.00
  }
}
        ]]></sourcecode>
      </section>
    </section>

    <section numbered="true" toc="default">
      <name>Security Considerations</name>
      
      <section numbered="true" toc="default">
        <name>Token Binding</name>
        <t>For high-security deployments, tokens SHOULD be sender-constrained using:</t>
        <ul>
          <li>DPoP (<xref target="RFC9449"/>)</li>
          <li>mTLS (<xref target="RFC8705"/>)</li>
        </ul>
      </section>
      
      <section numbered="true" toc="default">
        <name>Prompt and Response Handling</name>
        <t>Resource servers:</t>
        <ul>
          <li>MUST NOT log prompt or response content by default</li>
          <li>MUST encrypt any logged content at rest</li>
          <li>SHOULD provide configurable retention policies</li>
          <li>SHOULD support zero-logging mode</li>
        </ul>
      </section>
      
      <section numbered="true" toc="default">
        <name>Master Key Protection</name>
        <ul>
          <li>Master keys MUST be encrypted at rest</li>
          <li>Master keys MUST NOT be exposed in logs or error messages</li>
          <li>Key rotation SHOULD be supported without token invalidation</li>
        </ul>
      </section>
    </section>

    <section numbered="true" toc="default">
      <name>IANA Considerations</name>
      
      <section numbered="true" toc="default">
        <name>OAuth Scope Registration</name>
        <t>This specification registers the "ai" scope prefix in the 
        OAuth Parameters registry.</t>
      </section>
      
      <section numbered="true" toc="default">
        <name>AI Provider Registry</name>
        <t>This specification requests the establishment of a registry 
        for AI provider identifiers.</t>
      </section>
    </section>
  </middle>

  <back>
    <references>
      <name>References</name>
      
      <references>
        <name>Normative References</name>
        
        <reference anchor="RFC2119" target="https://www.rfc-editor.org/info/rfc2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner"/>
            <date month="March" year="1997"/>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
        </reference>
        
        <reference anchor="RFC6749" target="https://www.rfc-editor.org/info/rfc6749">
          <front>
            <title>The OAuth 2.0 Authorization Framework</title>
            <author fullname="D. Hardt" initials="D." surname="Hardt"/>
            <date month="October" year="2012"/>
          </front>
          <seriesInfo name="RFC" value="6749"/>
        </reference>
        
        <reference anchor="RFC7662" target="https://www.rfc-editor.org/info/rfc7662">
          <front>
            <title>OAuth 2.0 Token Introspection</title>
            <author fullname="J. Richer" initials="J." surname="Richer"/>
            <date month="October" year="2015"/>
          </front>
          <seriesInfo name="RFC" value="7662"/>
        </reference>
        
        <reference anchor="RFC8705" target="https://www.rfc-editor.org/info/rfc8705">
          <front>
            <title>OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens</title>
            <author fullname="B. Campbell" initials="B." surname="Campbell"/>
            <author fullname="J. Bradley" initials="J." surname="Bradley"/>
            <author fullname="N. Sakimura" initials="N." surname="Sakimura"/>
            <author fullname="T. Lodderstedt" initials="T." surname="Lodderstedt"/>
            <date month="February" year="2020"/>
          </front>
          <seriesInfo name="RFC" value="8705"/>
        </reference>
        
        <reference anchor="RFC9449" target="https://www.rfc-editor.org/info/rfc9449">
          <front>
            <title>OAuth 2.0 Demonstrating Proof of Possession (DPoP)</title>
            <author fullname="D. Fett" initials="D." surname="Fett"/>
            <author fullname="B. Campbell" initials="B." surname="Campbell"/>
            <author fullname="J. Bradley" initials="J." surname="Bradley"/>
            <author fullname="T. Lodderstedt" initials="T." surname="Lodderstedt"/>
            <author fullname="M. Jones" initials="M." surname="Jones"/>
            <author fullname="D. Waite" initials="D." surname="Waite"/>
            <date month="September" year="2023"/>
          </front>
          <seriesInfo name="RFC" value="9449"/>
        </reference>
      </references>
    </references>

    <section numbered="true" toc="default">
      <name>Example Flow</name>
      <artwork><![CDATA[
+--------+                               +---------------+
|        |--(1) Authorization Request--->|               |
|        |     scope=ai:openai:gpt-4:chat|               |
|        |     ai_limits={...}           | Authorization |
|        |                               |     Server    |
|        |<-(2) Authorization Code-------|               |
|        |                               +---------------+
|        |
| Client |                               +---------------+
|        |--(3) Token Request----------->|               |
|        |                               |     Token     |
|        |<-(4) Access Token-------------|   Endpoint    |
|        |     + ai_limits metadata      |               |
|        |                               +---------------+
|        |
|        |                               +---------------+
|        |--(5) API Request------------->|               |
|        |     Authorization: Bearer ... |   Resource    |
|        |     POST /v1/chat/completions |    Server     |
|        |                               |   (Proxy)     |
|        |<-(6) API Response-------------|               |
|        |                               +---------------+
+--------+
      ]]></artwork>
    </section>

    <section numbered="false" toc="default">
      <name>Acknowledgements</name>
      <t>The author would like to thank the OAuth Working Group for their 
      foundational work on authorization frameworks.</t>
    </section>
  </back>
</rfc>
