Ana içeriğe atla
← Tüm makaleler
protocolİleri12 dk okumaSon güncelleme: 30 Nis 2026

OpenAPI Catalog + OAuth Discovery: Otonom API Erişimi

AI ajanlarının insan eli olmadan API'nizi keşfedip OAuth dance'ini tamamlamasını sağlayın. AIDE'nin proto-openapi-catalog ve proto-oauth-discovery kontrolleri.

  • #openapi
  • #oauth
  • #discovery
  • #well-known
  • #advanced

Bir ajan API'nizi otonom kullanmak istediğinde iki şey bilmeli: (1) hangi endpoint'ler var, ne istiyorlar ve (2) kimlik doğrulamayı nasıl yapacak. Bu rehber RFC 8414 OAuth Authorization Server Metadata + OpenAPI 3.1 well-known catalog kombinasyonuyla, ajanın insanın elini hiç tutmadan API'nizi tüketebilmesini sağlamayı anlatıyor. AIDE'nin proto-openapi-catalog ve proto-oauth-discovery kontrolleri bu altyapının doğru kurulduğunu doğruluyor.

Bağlam: AIDE bu kontrollerde neye bakıyor?

proto-openapi-catalog üç adım:

  1. https://<domain>/.well-known/openapi HTTP 200 dönüyor mu?
  2. Yanıt geçerli OpenAPI 3.1 dökümanı mı (parser hatası yok)?
  3. Endpoint'lerden en az birinde x-ai-tags veya benzeri AI metadata var mı?

proto-oauth-discovery iki adım:

  1. https://<domain>/.well-known/oauth-authorization-server HTTP 200 dönüyor mu?
  2. Yanıt RFC 8414 zorunlu alanlarını (issuer, authorization_endpoint, token_endpoint, response_types_supported) içeriyor mu?

İkisi de PASS olduğunda agent dispatcher API'nizi keşfedip otomatik OAuth tamamlayabilir.

Adım 1 — OpenAPI 3.1 dökümanı

Eğer FastAPI/Flask-OpenAPI kullanıyorsanız spec zaten otomatik üretiliyor. Onu well-known path'e map etmeniz yeterli:

# FastAPI örneği — apps/api/src/aide_api/main.py
from fastapi import FastAPI
from fastapi.responses import JSONResponse

app = FastAPI(
    title="AIDE Scan API",
    version="1.0.0",
    description="AI hazırlık taraması yapan REST API",
)

@app.get("/.well-known/openapi", include_in_schema=False)
async def well_known_openapi():
    """Discovery için OpenAPI dökümanı."""
    schema = app.openapi()

    # AI ajanları için spec'i zenginleştir
    schema["info"]["x-ai-friendly"] = True
    schema["info"]["x-mcp-server"] = "https://mcp.aide.tr/v1/rpc"

    # Her endpoint'e AI tag ekle (örnek)
    for path, methods in schema["paths"].items():
        for method, operation in methods.items():
            if isinstance(operation, dict):
                operation.setdefault("x-ai-tags", _infer_ai_tags(path, operation))

    return JSONResponse(
        schema,
        headers={
            "Content-Type": "application/json",
            "Cache-Control": "public, max-age=3600",
            "Access-Control-Allow-Origin": "*",
        },
    )


def _infer_ai_tags(path: str, op: dict) -> list[str]:
    """Path'den AI tag öner — ajan dispatcher'lar bunu filtre olarak kullanır."""
    tags: list[str] = []
    if "/scans" in path:
        tags.append("audit")
    if "/leaderboard" in path:
        tags.append("benchmark")
    if op.get("method", "").upper() == "GET":
        tags.append("read-only")
    return tags

x-ai-tags non-standard ama yaygınlaşan bir uzantı. AIDE bu alanı ararken x-ai-friendly, x-llm-tags, x-agent-skills gibi varyantları da kabul eder.

Adım 2 — OAuth Authorization Server Metadata

RFC 8414 standart bir well-known endpoint tanımlar:

// /.well-known/oauth-authorization-server
{
  "issuer": "https://aide.tr",
  "authorization_endpoint": "https://aide.tr/oauth/authorize",
  "token_endpoint": "https://aide.tr/oauth/token",
  "registration_endpoint": "https://aide.tr/oauth/register",
  "scopes_supported": ["scan:create", "scan:read", "leaderboard:read"],
  "response_types_supported": ["code"],
  "grant_types_supported": ["authorization_code", "refresh_token"],
  "code_challenge_methods_supported": ["S256"],
  "token_endpoint_auth_methods_supported": ["client_secret_basic", "none"],
  "pkce_required": true,
  "device_authorization_endpoint": "https://aide.tr/oauth/device",
  "x-ai-dynamic-registration": true
}

Kritik alanlar:

| Alan | Niçin | |---|---| | registration_endpoint | Dynamic Client Registration (RFC 7591) — ajan kendi clientId'sini insanın eli olmadan kayıt eder | | code_challenge_methods_supported: ["S256"] | PKCE zorunlu — public client'lar için güvenli | | device_authorization_endpoint | Cihaz akışı (RFC 8628) — headless ajanlar için | | pkce_required: true | Tüm flow'larda PKCE — none auth method ile birlikte ajanlar için ideal | | x-ai-dynamic-registration | AIDE bunu PASS sayar; ajan otomatik kayıt destekleniyor demek |

Adım 3 — Dynamic Client Registration

Ajan client_id'yi statik configurate edemez (her ajan farklı). RFC 7591 dynamic registration bunu çözer:

# Dynamic client registration endpoint
from fastapi import APIRouter, Request
from pydantic import BaseModel
import secrets

router = APIRouter()


class ClientRegRequest(BaseModel):
    client_name: str
    redirect_uris: list[str]
    grant_types: list[str] = ["authorization_code", "refresh_token"]
    token_endpoint_auth_method: str = "none"  # PKCE için public client
    scope: str = "scan:read"


@router.post("/oauth/register")
async def register_client(req: ClientRegRequest):
    client_id = f"agent_{secrets.token_urlsafe(16)}"

    # DB'ye yaz
    await db.clients.insert({
        "client_id": client_id,
        "client_name": req.client_name,
        "redirect_uris": req.redirect_uris,
        "grant_types": req.grant_types,
        "auth_method": req.token_endpoint_auth_method,
        "scope": req.scope,
        "created_at": datetime.utcnow(),
        "is_agent": True,  # filtreleme için işaretle
    })

    return {
        "client_id": client_id,
        "client_id_issued_at": int(datetime.utcnow().timestamp()),
        "redirect_uris": req.redirect_uris,
        "grant_types": req.grant_types,
        "token_endpoint_auth_method": req.token_endpoint_auth_method,
        "scope": req.scope,
    }

PKCE + public client (token_endpoint_auth_method: "none") kombinasyonu ajanlar için en güvenli yol — secret saklamak gerekmiyor.

Adım 4 — PKCE flow

Ajan ilgili scope için authorization code akışını PKCE ile çalıştırır:

# Ajan tarafı pseudocode
import hashlib, base64, secrets

# 1. Code verifier üret
code_verifier = secrets.token_urlsafe(64)
code_challenge = base64.urlsafe_b64encode(
    hashlib.sha256(code_verifier.encode()).digest()
).rstrip(b"=").decode()

# 2. Authorization redirect — kullanıcı browser'da onaylar
auth_url = (
    f"https://aide.tr/oauth/authorize?"
    f"response_type=code&client_id={client_id}&"
    f"redirect_uri={redirect_uri}&"
    f"code_challenge={code_challenge}&"
    f"code_challenge_method=S256&"
    f"scope=scan:create"
)

# 3. Kullanıcı authorize ettikten sonra code dönüyor → token exchange
token_resp = await client.post(
    "https://aide.tr/oauth/token",
    data={
        "grant_type": "authorization_code",
        "code": auth_code,
        "redirect_uri": redirect_uri,
        "client_id": client_id,
        "code_verifier": code_verifier,  # PKCE
    },
)
access_token = token_resp.json()["access_token"]

Yaygın hatalar

| Hata | Belirti | Çözüm | |---|---|---| | OpenAPI dökümanı securitySchemes boş | Ajan auth'u keşfedemiyor | securitySchemes altında oauth2 flow tanımla, scopes ekle | | .well-known/openapi 200 ama info.title boş | AIDE WARNING | OpenAPI dökümanını her build'de validate et — Spectral linter ile CI'a koy | | Dynamic registration 401 — gizli sayılıyor | Ajan kayıt olamıyor | Endpoint anonymous'a açık olmalı, rate limit ile koru | | redirect_uris whitelist'te http://localhost yok | Local test ajanları başarısız | Dev/test için http://localhost:* pattern'ini izin verin | | scopes_supported boş | Ajan ne isteyeceğini bilmiyor | En az 2-3 anlamlı scope yayınla (read, write, admin) |

Test: AIDE'nin yaptığı şey

# OpenAPI catalog
curl -s https://siteniz.com/.well-known/openapi | jq '.openapi, .info.title, (.paths | keys | length)'
# Beklenen: "3.1.0", "Site API", >0

# OAuth discovery
curl -s https://siteniz.com/.well-known/oauth-authorization-server | jq '.issuer, .token_endpoint, .scopes_supported'
# Beklenen: hepsi dolu

# Dynamic registration test
curl -X POST https://siteniz.com/oauth/register \
  -H 'Content-Type: application/json' \
  -d '{"client_name":"test","redirect_uris":["http://localhost:8080/cb"]}'
# Beklenen: 200, body içinde client_id

Üçü de doğruysa ajan dispatcher'ları otomatik kayıt → PKCE → API call zincirini insan eli olmadan tamamlayabilir.

Production için

  • Token TTL: Access token 1 saat, refresh token 30 gün. Daha kısa = ajan trafik artırır; daha uzun = compromise riski büyür.
  • Audit log: oauth_grants tablosuna her grant + her exchange'i yazın. Ajan client'larını işaretleyin (is_agent: true) — gerektiğinde toplu revoke edebilirsiniz.
  • Rate limit: /oauth/register endpoint'i abuse vector — dakikada 10 kayıt yeterli.
  • Scope inflation: Ajanlar genellikle gereksiz yere admin scope ister. Default olarak en sınırlı scope'u zorla, escalation ayrı bir flow olsun.

İlgili kaynaklar

1284 abone

Haftalık AI-Readiness bülteni

Yeni makaleler, sektör trendi, kontrol değişiklikleri — haftada bir mail.

Sitenizde deneyin

Tek bir tıklamayla bu kontrolü çalıştırın.

Hangi kontrolü istersin?