An open protocol that lets agents register for services on behalf of users — discoverable through a Markdown file at your domain.
이 번역은 AI가 원문 README를 옮긴 것입니다. 원문이 항상 우선합니다.
에이전트 등록(agentic registration)의 참조 구현 — 에이전트가 사용자를 대신하여 서비스에 인증할 수 있도록 하는 프로토콜입니다. 세 가지 역할이 있습니다: 사용자를 대신하는 에이전트, ID-JAG(ID-JAG)를 발행하는 에이전트 제공자, 그리고 가능할 때 해당 어설션을 수락하고 자격 증명을 발급하는 서비스입니다. 에이전트가 사용자 신원과 연결되지 않았거나 에이전트 제공자가 ID-JAG를 지원하지 않는 경우, 서비스는 RFC 8628 스타일의 클레임 절차를 대신 사용하여 에이전트를 인증합니다.
이 저장소는 에이전트 제공자 측과 에이전트 서비스 측 모두에 대한 샘플 구현을 포함하며, 에이전트 서비스가 호스팅할 샘플 AUTH.md 파일을 포함하여 에이전트가 서비스에 인증하는 방법을 안내합니다.
├── AUTH.md ← 에이전트가 읽는 스킬 매니페스트
├── agent-services/ ← 샘플 리소스 서버 + 인증 서버
├── agent-providers/ ← ID-JAG를 발행하는 샘플 에이전트 IdP
└── shared/ ← 공유 워크스페이스 패키지 (포트, 타입)
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 블록은 등록 및 클레임 표면을 전달하는 프로필 확장입니다.
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