Identitas AI Agent: Delegated Authorization Setelah OAuth 2.1

AI agent identity berarti memberi agent akun tetap miliknya sendiri, terpisah dari manusia yang diwakilinya maupun dari workload tempat ia berjalan. Service account adalah credential berumur panjang yang dipakai bersama untuk workload deterministik, sehingga tidak membawa catatan consent dan tidak punya kaitan dengan orang yang otoritasnya sedang dipakai agent. Dokumentasi agent identity Microsoft sendiri menyebut model identitas untuk human user dan aplikasi terbukti tidak memadai bagi agent, yang sering dibuat secara dinamis dan dihancurkan dalam jumlah besar.
Pecah satu field actor menjadi dua: otoritas, yaitu manusia yang hak delegasinya membuat aksi itu sah, dan actor, yaitu perangkat lunak yang benar-benar melakukan mutasi. Menyimpan nama manusia saja adalah pernyataan palsu di log yang immutable, sementara menyimpan nama agent saja membuat barisnya kehilangan jejak otoritas. Idealnya satu baris audit memuat id actor, subject on-behalf-of, delegation chain, referensi consent, dan jti token.
Model datanya sudah. OAuth 2.0 Token Exchange, RFC 8693, berstatus Standards Track sejak Januari 2020 dan mendefinisikan nested act claim untuk delegasi plus claim may_act untuk menyatakan lebih dulu bahwa satu pihak boleh menjadi actor bagi pihak lain. Yang belum ada adalah layar consent front-channel yang menyebut agent tertentu, serta cara agent membuktikan di token endpoint bahwa dia memang actor yang disetujui user.
Belum. Ada dua individual submission yang beredar di datatracker IETF, keduanya tanpa working group di belakangnya. draft-oauth-ai-agents-on-behalf-of-user berhenti di revisi 02 dan expired pada 27 Februari 2026, sedangkan draft-araut-oauth-transaction-tokens-for-agents masih active di revisi 02 dan berlaku sampai 23 November 2026. Apa pun yang Anda bangun di atas parameter itu hari ini adalah taruhan, jadi modelkan delegasi internal Anda di atas RFC 8693.
Entra Agent ID memberi setiap agent sebuah service principal khusus yang tidak memegang credential sendiri. Agent dibuat dari agent identity blueprint yang bisa dipakai ulang, dan blueprint itulah yang memegang federated identity credentials, sertifikat, atau client secret lalu mengambil token atas nama setiap agent identity. Ketika agent bertindak untuk seseorang, subject token adalah user sementara actor-nya adalah agent identity, yang persis semantik delegasi RFC 8693 di dalam produk vendor.

Ringkasan Utama
AI agent memerlukan identitas tetap miliknya sendiri plus delegation token per permintaan yang menyebut manusia yang otoritasnya dipinjam. OAuth 2.0 Token Exchange, RFC 8693, sudah memodelkan ini lewat nested act claim, tetapi belum ada ekstensi khusus agent yang menjadi standar, sehingga setiap desain audit trail pada 2026 adalah taruhan pada satu vendor.
Ambil satu pertanyaan yang cepat atau lambat akan diajukan tenant ERP mana pun: bolehkah sebuah agent menyelesaikan purchase order di bawah signing limit seorang finance manager selama dia cuti dua minggu. Bagian permission-nya selesai dalam semenit, karena membatasi nilai dan tipe dokumen memang tugas authorization policy. Yang membuat Anda berhenti adalah field approverId, yang isinya persis satu string, dan yang oleh audit log diperlakukan sebagai jawaban atas siapa yang menyetujui dokumen itu.
Saya merawat hierarchical-approval, npm library yang menjalankan approval chain berjenjang dan menambahkan audit entry yang immutable berisi diff state lama dan baru pada setiap mutasi. Tulisan ini tentang harus menjadi apa satu field itu ketika approver-nya adalah agent, apa yang sudah distandarkan OAuth untuk kasus tersebut sejak 2020, dan mengapa ekstensi yang selalu dirujuk orang justru sudah expired. Saya membaca spesifikasinya dengan teliti; saya belum pernah menaruh agent approver di production, dan keadaan jujurnya pada 2026 adalah belum ada jawaban yang mapan.
Pertanyaan siapa yang menyetujui purchase order ini langsung pecah menjadi dua begitu ada agent di dalamnya, dan satu kolom actor hanya bisa menjawab separuhnya. Compliance menanyakan otoritas: kekuasaan tanda tangan milik manusia mana yang membuat approval ini sah. Security menanyakan actor: perangkat lunak mana yang melakukan mutasinya, supaya bisa dicabut, dibatasi, atau diselidiki. Approver manusia menggabungkan keduanya ke dalam satu id, dan itulah sebabnya skema ini bertahan bertahun-tahun dengan satu field.
// hierarchical-approval: the call that closes an approval level.
await engine.approve(instance.id, { approverId: 'mgr-1' });
// The audit entry it appends names ONE actor. Now an agent runs
// that approval while mgr-1 is on leave. Both fills are wrong.
// Wrong: name the human. The log asserts that a person reviewed
// a document she never opened, and revocation cannot target the
// agent without disabling the manager.
{ approverId: 'mgr-1' }
// Wrong: name the agent. The signing limit that makes this
// approval valid is attached to mgr-1, and no agent id inherits
// it. The row no longer proves anyone had the authority.
{ approverId: 'svc-approval-bot' }Kedua isian di atas tidak akan bertahan dalam percakapan audit. Menulis nama manusia adalah pernyataan yang salah secara faktual di dalam log yang immutable, padahal sifat immutable itulah inti dari log tersebut. Menulis nama agent membuat baris itu kehilangan jejak otoritas, karena signing limit di setiap ERP yang pernah saya kerjakan menempel pada struktur organisasi manusia. Perbaikannya bukan mencari nilai yang lebih baik untuk field itu, melainkan menambah field kedua.
Kedua konstruksi identitas yang sudah ada dirancang untuk sesuatu yang bukan agent, dan keduanya gagal ke arah yang berbeda. Service account adalah credential berumur panjang yang dipakai bersama untuk workload deterministik; agent dibuat untuk satu tugas dan bisa saja sudah tidak ada besok. Dokumentasi agent identity Microsoft menyatakan terang-terangan bahwa model identitas yang dirancang untuk human user dan aplikasi terbukti tidak memadai di sini, dan menyebut agent dibuat secara dinamis serta kadang dihancurkan ribuan kali per hari. Kegagalan yang paling terasa di sebuah approval log:
Bagian inilah yang terus dilewati literatur soal permission. Cerbos, OpenFGA, dan setiap policy engine yang pernah saya tulis menjawab apa yang boleh dilakukan pemanggil, dan semuanya menerima identitas pemanggil sebagai sesuatu yang sudah pasti. Ketika pemanggilnya adalah agent yang berjalan atas nama orang lain, justru identitas itulah bagian yang belum selesai, dan seekspresif apa pun policy-nya tidak akan memperbaiki field actor yang sudah ambigu sejak sampai ke policy engine.
OAuth 2.0 Token Exchange, RFC 8693, berstatus Standards Track sejak Januari 2020, dan sudah memodelkan persoalan ini dengan tepat. Ia membuat pembedaan yang persis dibutuhkan audit ERP: dengan semantik delegasi, principal A tetap punya identitas sendiri yang terpisah dari B, dan dipahami secara eksplisit bahwa meskipun B mendelegasikan sebagian haknya kepada A, setiap tindakan dilakukan oleh A yang mewakili B. Sebaliknya, impersonation membuat A tidak bisa dibedakan dari B di dalam konteks hak tersebut. Rantai delegasinya berbentuk nested act claim.
// RFC 8693 section 4.1: delegation is a NESTED "act" claim.
// Read it outside-in. "sub" is whose authority is being used;
// each "act" is a party that acted, most recent first.
{
"iss": "https://sso.example.co.id",
"aud": "https://erp.example.co.id",
"sub": "mgr-1",
"act": {
"sub": "agent://approvals/finance-v1",
"act": {
"sub": "https://orchestrator.example.co.id"
}
}
}
// Section 4.4 covers the permission side. "may_act" states, in
// advance, that one party is allowed to BECOME the actor for
// another. Put it on the user's own token and you have a
// delegation grant you can revoke without deleting the agent.
{
"sub": "mgr-1",
"may_act": { "sub": "agent://approvals/finance-v1" }
}Jadi format token bukan bagian yang hilang selama enam tahun terakhir. Yang tidak disediakan RFC 8693 adalah momen front-channel tempat user melihat agent mana yang meminta dan memberi consent untuk agent itu secara spesifik, plus cara bagi agent untuk membuktikan di token endpoint bahwa dia memang actor yang disebut dalam consent tersebut. Token exchange terjadi back-channel, antar service. Menutup celah itulah tujuan draft-draft 2026.
Ada dua individual submission yang beredar, dan keduanya memakai ulang sub dan act alih-alih menciptakan bentuk baru. draft-oauth-ai-agents-on-behalf-of-user, dari penulis di WSO2, menambahkan requested_actor pada authorization request, yang harus mengidentifikasi actor secara unik dan harus dipahami oleh authorization server, serta actor_token pada token request, yang sub claim-nya wajib mengidentifikasi agent. draft-araut-oauth-transaction-tokens-for-agents, dari penulis di Amazon, mengambil separuh persoalan yang lain: merambatkan identitas agent melalui call graph, menjaga sub dan act tetap immutable sepanjang transaksi, dan menambahkan claim agentic_ctx yang membawa current_actor, originator, dan hitungan hop.
# draft-oauth-ai-agents-on-behalf-of-user-02
# requested_actor rides on the AUTHORIZATION request, so the
# consent screen can name the agent instead of only the app.
GET /authorize?response_type=code
&client_id=s6BhdRkqt3
&scope=purchase_order.approve
&requested_actor=actor-finance-v1
&redirect_uri=https%3A%2F%2Fapp.example.co.id%2Fcb
# actor_token rides on the TOKEN request, so the agent proves it
# is the actor the user consented to. The draft requires its sub
# claim to identify the agent.
POST /token
grant_type=authorization_code
&code=SplxlOBeZQQYbYS6WxSbIA
&actor_token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
# The access token the draft shows coming back:
{ "sub": "user-456", "azp": "s6BhdRkqt3", "act": { "sub": "actor-finance-v1" } }
# draft-araut-oauth-transaction-tokens-for-agents-02 keeps sub and
# act immutable for the whole transaction and adds agentic_ctx for
# the parts that change as the call graph deepens:
{
"sub": "user:[email protected]",
"act": { "sub": "agent-identity-1" },
"agentic_ctx": {
"current_actor": "agent-identity-1",
"originator": "agent-identity-1",
"chain_metadata": { "hop_count": 1 }
}
}Baca dulu baris statusnya sebelum membangun di atas salah satunya. Keduanya individual submission, tanpa stream IETF dan tanpa working group di belakangnya. Draft on-behalf-of berada di revisi 02 dan sudah expired pada 27 Februari 2026. Draft transaction tokens berada di revisi 02, berstatus active, dan berlaku sampai 23 November 2026 — dan draft itu sendiri adalah hasil penggantian nama dari draft lama yang sempat mencapai revisi 06 dengan nama berkas berbeda. Begitulah wujud area yang belum mapan di datatracker, dan itu lebih baik dikatakan apa adanya daripada menulis parameter-parameter ini seolah sudah final.
Jangan memasang requested_actor atau agentic_ctx di authorization server production hanya karena ada draft-nya. Keduanya bisa berganti nama parameter atau hilang pada revisi berikutnya, dan satu di antaranya sudah pernah lapse. Modelkan delegasi internal Anda di atas act dan may_act milik RFC 8693, yang Standards Track dan tidak akan bergeser, lalu perlakukan parameter draft sebagai wire format yang mungkin harus Anda sesuaikan nanti.
Ada empat pola delegasi yang berjalan di production di suatu tempat pada 2026, dan keempatnya bukan variasi dari tema yang sama. Keempatnya menaruh nilai berbeda di subject token, sehingga menopang klaim audit yang berbeda dan gagal di titik yang berbeda pula. Memilih salah satu berarti bertaruh ke arah mana industri akan mendarat.

| Pola | Subject dan actor pada token | Yang bisa dibuktikan baris audit | Titik gagalnya |
|---|---|---|---|
| User-delegated | sub adalah user, act adalah agent | Otoritas sekaligus actor, dari satu token | Butuh momen consent interaktif, sehingga job terjadwal tengah malam tidak punya apa pun untuk disandarkan |
| Autonomous | sub adalah agent, tanpa act claim | Apa yang bertindak, tanpa keterangan otoritas siapa | Limit approval menempel pada manusia, jadi agent butuh limit yang dibuatkan sendiri dan diatur terpisah |
| Hybrid orchestrated | sub adalah user, act bersarang sekali per hop | Seluruh rantainya, kalau log Anda bisa menyimpan array | Sebagian besar skema audit hanya punya satu kolom actor, dan kedalaman hop tak terbatas kecuali dibatasi policy |
| Scoped impersonation | sub adalah user, tanpa act, scope dipersempit | Tidak ada apa pun tentang agent-nya | Barisnya tidak bisa dibedakan dari baris manusia, sehingga agent tidak bisa dicabut atau diselidiki sendirian |
Baris yang harus saya pertahankan di depan auditor adalah yang ketiga, dan justru itu yang paling minim tooling. Satu kolom actor tidak bisa menyimpan rantai dengan kedalaman tak diketahui, jadi pilihannya adalah menambah kolom JSON di log atau membatasi kedalaman lewat policy. Saya akan membatasinya di dua hop, karena dua adalah kedalaman terjauh yang masih bisa saya jelaskan dalam satu rapat. Itu bukan argumen teknis, tapi itulah argumen yang menentukan.
Microsoft Entra Agent ID adalah implementasi terlengkap yang pernah saya baca, dan ia tidak mengikuti draft mana pun. Agent identity di sana adalah service principal khusus, dan detail pentingnya adalah ia tidak memegang credential sendiri. Ia dibuat dari template yang bisa dipakai ulang bernama agent identity blueprint, dan blueprint itulah yang memegang federated identity credentials, sertifikat, atau client secret, lalu mengambil token atas nama setiap agent identity yang dibuatnya.
Bentuk claim-nya mendarat persis di tempat yang ditetapkan RFC 8693. Dokumentasinya menjelaskan tiga kasus token: agent meminta token yang subject-nya adalah agent identity, menerima token yang audience-nya adalah agent identity, dan meminta user token di mana subject token adalah user sementara actor-nya adalah agent identity. Setiap agent identity juga punya sponsor, yang mencatat user atau grup manusia yang bertanggung jawab atasnya — jawaban ala struktur organisasi yang berdiri berdampingan dengan delegasi per permintaan. Agent identity bersifat single-tenant, meski blueprint-nya bisa multitenant dan membuat identitas lokal di tenant lain.
Dua konsekuensi mengikuti dari model credential itu, dan keduanya adalah pembacaan saya, bukan kalimat dokumentasinya. Pertama, blueprint adalah objek yang diincar penyerang, karena ia memegang credential untuk semua agent identity di bawahnya, sehingga jumlah blueprint menjadi keputusan batas keamanan, bukan sekadar soal kerapian. Kedua, ini model vendor, bukan model yang interoperable: agent identity yang diterbitkan di satu tenant Entra tidak berarti apa-apa bagi resource server yang tidak berfederasi dengannya. Microsoft menyebut Agent ID tersedia untuk semua pelanggan Microsoft Entra, sementara memperluas fitur keamanan Entra yang lebih luas ke agent memerlukan lisensi Agent 365 terpisah, jadi taruhannya komersial sekaligus arsitektural.
Agent identity di sebuah directory menjawab agent yang mana. Ia tidak menjawab proses mana yang sedang memegang credential itu, dan di armada container keduanya pertanyaan yang berbeda. SPIFFE adalah jawaban matang untuk pertanyaan kedua. Sebuah workload mendapat SPIFFE ID berbentuk URI, spiffe://acme.com/billing/payments, di mana komponen pertama adalah trust domain yang berperan sebagai akar kepercayaan kriptografis dan sisanya mengidentifikasi workload-nya. Ia membuktikan ID itu dengan SVID: X.509-SVID yang membawa ID plus private key berumur pendek, atau JWT-SVID, yang oleh dokumentasi SPIFFE sendiri ditandai membawa risiko replay.
Sifat yang layak ditiru adalah cara workload memperolehnya. Workload API tidak mengharuskan workload pemanggil mengetahui identitasnya sendiri, atau memegang authentication token saat memanggil API tersebut — identitas datang dari attestation atas apa yang bisa diamati platform tentang proses itu, bukan dari secret yang dikirim menyertainya. Itu postur yang tepat untuk agent, yang justru merupakan jenis proses berumur pendek yang tidak ingin Anda beri kunci berumur panjang. Jadi ada tiga sistem yang menjawab tiga pertanyaan: SPIFFE menyebut proses mana, agent identity menyebut agent mana, dan delegation token menyebut atas otoritas siapa. Satu baris audit ERP membutuhkan ketiganya, dan hari ini ketiganya datang dari tiga tempat berbeda.
Catat jti token dan id consent grant di baris audit, bukan hanya id actor-nya. Id bisa dipakai ulang ketika agent dibuat kembali dari blueprint yang sama, dan consent bisa dicabut, sehingga setahun kemudian catatan grant mungkin satu-satunya artefak yang bisa membuktikan delegasi itu memang ada pada saat approval terjadi.
Berikut yang akan saya masukkan ke approval log ERP hari ini, mengingat belum ada yang distandarkan. Sengaja dibuat membosankan: enam field datar, semuanya bisa diturunkan dari token yang mengikuti RFC 8693, dan tidak satu pun bergantung pada parameter draft yang belum tentu bertahan.

// One approval row, six fields instead of one.
type AgentApprovalAudit = {
actorType: 'human' | 'agent';
actorId: string; // agent://approvals/finance-v1
onBehalfOf: string | null; // mgr-1; null is legal only for 'human'
delegationChain: string[]; // flattened from the token's nested act
consentRef: string; // the grant this delegation was made under
tokenJti: string; // the exact credential, checkable a year later
};
// hierarchical-approval already exposes the refusal point, so the
// rule lives in front of the log rather than in a reviewer's head.
const engine = new ApprovalEngine({
adapter: pgAdapter,
tenantId: 'acme',
authorizationPolicy: {
authorize: async (ctx) => {
const d = delegationFor(ctx.actorId); // parsed from the bearer token
if (d.actorType === 'agent' && !d.onBehalfOf)
return 'Agent actor with no delegation subject';
if (d.actorType === 'agent' && d.delegationChain.length > 2)
return 'Delegation chain too deep to approve';
if (d.actorType === 'agent' && !d.consentRef)
return 'No consent grant recorded for this agent';
},
},
});Penolakannya lebih penting daripada skemanya. Aksi agent tanpa subject delegasi bukan approval, melainkan mutasi tanpa atribusi, dan membiarkannya masuk ke log yang immutable berarti kesalahannya permanen. hierarchical-approval sudah menyediakan hook authorizationPolicy yang berjalan sebelum mutasi, sehingga pemeriksaannya berdiri di depan penulisan, bukan menunggu review kuartalan.
hierarchical-approval adalah npm library open-source saya untuk approval chain ERP berjenjang, lengkap dengan audit log yang immutable, hook authorization policy, dan audit adapter yang bisa dipasang sendiri.
npmjs.com/package/hierarchical-approvalAturan yang layak dibawa pulang: jangan pernah biarkan aksi sebuah agent menghasilkan baris log dengan satu actor saja. Simpan actor dan otoritas sebagai dua field terpisah sejak migrasi pertama, bahkan ketika Anda masih memakai service account biasa, karena menambahkan kolom actor kedua ke tabel audit yang immutable adalah versi mahal dari masalah ini. Standarnya belum mapan dan akan terus bergerak. Bentuk barisnya sudah bisa diketahui sekarang.
Sumber dan bacaan lanjutan