workos/auth.md

An open protocol that lets agents register for services on behalf of users — discoverable through a Markdown file at your domain.

528
GitHub 스타
44
포크
TypeScript
언어
MIT
라이선스
2026.06.10
최근 푸시
2026.05.25
별표한 날

AI 분석

설치 난이도: 보통
큐레이터 노트
에이전트 기반 인증 프로토콜을 연구하거나 구현하려는 개발자에게 유용한 참조 자료입니다. 특히 AI 에이전트가 사용자 대신 서비스에 접근해야 하는 시나리오에서 활용 가능성이 높습니다.

강점

  • 에이전트가 사용자를 대신해 서비스에 인증할 수 있는 새로운 프로토콜을 제안하며, ID-JAG와 RFC 8628 기반 클레임 절차를 모두 지원합니다.
  • AUTH.md 파일을 통해 에이전트가 서비스 인증 방법을 발견할 수 있는 표준화된 방식을 제공합니다.
  • 참조 구현이 포함되어 있어 프로토콜을 쉽게 이해하고 테스트할 수 있습니다.

약점

  • 아직 초기 단계의 프로토콜로, 실제 서비스에 적용하기에는 추가 검증과 표준화가 필요합니다.
  • ID-JAG는 아직 IETF 초안 단계로, 널리 채택되지 않았습니다.

주의사항

  • 프로토콜이 아직 표준화되지 않았으므로, 프로덕션 환경에서 사용하기 전에 충분한 테스트가 필요합니다.
  • ID-JAG 발행을 위한 에이전트 제공자 인프라가 필요하며, 이는 추가적인 의존성을 만듭니다.

시작 가이드

  • 저장소를 클론하고 pnpm install 및 pnpm dev로 로컬에서 실행해 보세요.
  • AUTH.md 파일을 읽고 에이전트 등록 절차를 이해하세요.
  • agent-services/README.md와 agent-providers/README.md를 참고하여 서비스 또는 IdP 구현을 시작하세요.

README 한국어 번역

이 번역은 AI가 원문 README를 옮긴 것입니다. 원문이 항상 우선합니다.

auth.md

에이전트 등록(agentic registration)의 참조 구현 — 에이전트가 사용자를 대신하여 서비스에 인증할 수 있도록 하는 프로토콜입니다. 세 가지 역할이 있습니다: 사용자를 대신하는 에이전트, ID-JAG(ID-JAG)를 발행하는 에이전트 제공자, 그리고 가능할 때 해당 어설션을 수락하고 자격 증명을 발급하는 서비스입니다. 에이전트가 사용자 신원과 연결되지 않았거나 에이전트 제공자가 ID-JAG를 지원하지 않는 경우, 서비스는 RFC 8628 스타일의 클레임 절차를 대신 사용하여 에이전트를 인증합니다.

이 저장소는 에이전트 제공자 측과 에이전트 서비스 측 모두에 대한 샘플 구현을 포함하며, 에이전트 서비스가 호스팅할 샘플 AUTH.md 파일을 포함하여 에이전트가 서비스에 인증하는 방법을 안내합니다.

구조

├── AUTH.md            ← 에이전트가 읽는 스킬 매니페스트
├── agent-services/    ← 샘플 리소스 서버 + 인증 서버
├── agent-providers/   ← ID-JAG를 발행하는 샘플 에이전트 IdP
└── shared/            ← 공유 워크스페이스 패키지 (포트, 타입)

다음 단계

  • 에이전트이거나 auth.md 템플릿이 필요한 경우 → AUTH.md — 절차적 레시피 (발견 → 등록 → 클레임 → 교환 → 사용 → 해지 처리).
  • 서비스를 구현하는 경우 → agent-services/README.md — 전체 구현 가이드, 시퀀스 다이어그램, 오류 테이블.
  • IdP를 구현하는 경우 → agent-providers/README.md — ID-JAG 발행, JWKS 게시, 해지 이벤트 전송.

빠른 시작

pnpm install
pnpm dev

서비스는 <http://localhost:8000>, 제공자는 <http://localhost:4000>에서 실행됩니다. 서비스 홈 페이지는 세 가지 등록 흐름을 대화형으로 안내합니다. pnpm dev:service 또는 pnpm dev:provider를 사용하여 한쪽만 실행할 수 있습니다.

시스템 흐름

등록 및 자격 증명 발급은 두 개의 엔드포인트로 나뉩니다. POST /agent/identity는 에이전트가 선택한 신원 어설션(ID-JAG, 확인된 이메일 또는 익명)을 수락하고 서비스가 서명한 identityassertion을 반환합니다. 그런 다음 에이전트는 POST /oauth2/token (RFC 7523 JWT-bearer grant)에서 해당 어설션을 accesstoken으로 교환합니다.

발견

/.well-known/oauth-authorization-server에서 호스팅:

{
  "resource": "https://api.service.example.com/",
  "authorization_servers": ["https://auth.service.example.com/"],
  "scopes_supported": ["api.read", "api.write"],
  "bearer_methods_supported": ["header"],

  "issuer": "https://auth.service.example.com",
  "token_endpoint": "https://auth.service.example.com/oauth2/token",
  "revocation_endpoint": "https://auth.service.example.com/oauth2/revoke",
  "grant_types_supported": [
    "urn:ietf:params:oauth:grant-type:jwt-bearer",
    "urn:workos:agent-auth:grant-type:claim"
  ],

  "agent_auth": {
    "skill": "https://service.example.com/auth.md",
    "identity_endpoint": "https://auth.service.example.com/agent/identity",
    "claim_endpoint": "https://auth.service.example.com/agent/identity/claim",
    "events_endpoint": "https://auth.service.example.com/agent/event/notify",
    "identity_types_supported": ["anonymous", "identity_assertion", "service_auth"],
    "identity_assertion": {
      "assertion_types_supported": [
        "urn:ietf:params:oauth:token-type:id-jag"
      ]
    },
    "events_supported": [
      "https://schemas.workos.com/events/agent/auth/identity/assertion/revoked"
    ]
  }
}

최상위 issuer / tokenendpoint / revocationendpoint / granttypessupported는 표준 RFC 8414 / RFC 7009 / RFC 7523 필드입니다. agent_auth 블록은 등록 및 클레임 표면을 전달하는 프로필 확장입니다.

신원 어설션 (ID-JAG)

sequenceDiagram
    actor User
    participant Agent
    participant Provider as Agent Provider
    participant Service

    Agent->>Service: GET /api/resource
    Service-->>Agent: 401 Unauthorized<br/>WWW-Authenticate: Bearer resource_metadata="..."

    Agent->>Service: GET /.well-known/oauth-protected-resource
    Service-->>Agent: 200 OK (PRM with authorization_servers)
    Agent->>Service: GET /.well-known/oauth-authorization-server
    Service-->>Agent: 200 OK (AS metadata with agent_auth block)

    Agent->>User: 대상에 대한 신원 어설션 동의?
    User-->>Agent: 동의함

    Agent->>Provider: 대상별 ID-JAG 요청
    Provider-->>Agent: 200 OK (ID-JAG)

    Agent->>Service: POST /agent/identity<br/>{ type: identity_assertion, assertion: ID-JAG }
    Service->>Provider: GET /.well-known/jwks.json
    Provider-->>Service: 200 OK (JSON Web Key Set)
    Service-->>Agent: 200 OK (identity_assertion)

    Agent->>Service: POST /oauth2/token<br/>grant_type=jwt-bearer&assertion=...
    Service-->>Agent: 200 OK (access_token)

확인된 이메일 신원 어설션

sequenceDiagram
    actor User
    participant Agent
    participant Service

    Agent->>Service: POST /agent/identity<br/>{ type: service_auth, login_hint: email }
    Service-->>Agent: 200 OK (claim_token, claim: user_code + verification_uri)
    Agent-->>User: user_code + verification_uri 표시
    User->>Service: GET verification_uri (로그인, /claim으로 이동)
    User->>Service: POST /agent/identity/claim/complete<br/>{ claim_attempt_token, user_code }

    loop until claimed
      Agent->>Service: POST /oauth2/token<br/>grant_type=claim&claim_token=...
      alt user_code window open
        Service-->>Agent: 200 OK (access_token + identity_assertion) | authorization_pending
      else user_code expired (outer claim window still open)
        Service-->>Agent: 400 expired_token
        Agent->>Service: POST /agent/identity/claim<br/>{ claim_token, email }
        Service-->>Agent: 200 OK (fresh claim_attempt: new user_code + verification_uri)
        Agent-->>User: 새 user_code + verification_uri 표시
      end
    end

클레임 절차를 통한 익명 등록

sequenceDiagram
    actor User
    participant Agent
    participant Service

    Agent->>Service: POST /agent/identity<br/>{ type: anonymous }
    Service-->>Agent: 200 OK (identity_assertion, claim_token)
    Agent->>Service: POST /oauth2/token<br/>grant_type=jwt-bearer&assertion=...
    Service-->>Agent: 200 OK (pre-claim scope의 access_token)

    Note over Agent: 에이전트는 pre-claim 범위로 작동

    User-->>Agent: 소유권을 가져오고 싶음
    Agent->>Service: POST /agent/identity/claim<br/>{ claim_token, email }
    Service-->>Agent: 200 OK (claim_attempt: user_code + verification_uri)
    Agent-->>User: user_code + verification_uri 표시
    User->>Service: GET verification_uri (로그인, /claim으로 이동)
    User->>Service: POST /agent/identity/claim/complete<br/>{ claim_attempt_token, user_code }

    loop until claimed
      Agent->>Service: POST /oauth2/token<br/>grant_type=claim&claim_token=...
      alt user_code window open
        Service-->>Agent: 200 OK (post-claim access_token + v2 identity_assertion) | authorization_pending
      else user_code expired (outer claim window still open)
        Service-->>Agent: 400 expired_token
        Agent->>Service: POST /agent/identity/claim<br/>{ claim_token, email }
        Service-->>Agent: 200 OK (fresh claim_attempt: new user_code + verification_uri)
        Agent-->>User: 새 user_code + verification_uri 표시
      end
    end

원본 저장소: workos/auth.md

라이선스: MIT

게재 제외를 원하시면 삭제 요청을 보내주세요.