@@ -52,12 +52,14 @@ impl AgentIdentityManager {
5252 } ;
5353
5454 let client = create_client ( ) ;
55- let url =
56- agent_task_registration_url ( & self . chatgpt_base_url , & stored_identity. agent_runtime_id ) ;
55+ let url = agent_task_registration_url (
56+ & self . agent_identity_base_url ,
57+ & stored_identity. agent_runtime_id ,
58+ ) ;
59+ let human_biscuit = self . mint_human_biscuit ( & binding) . await ?;
5760 let response = client
5861 . post ( & url)
59- . bearer_auth ( & binding. access_token )
60- . header ( "chatgpt-account-id" , & binding. chatgpt_account_id )
62+ . header ( "X-OpenAI-Authorization" , human_biscuit)
6163 . json ( & request_body)
6264 . timeout ( AGENT_TASK_REGISTRATION_TIMEOUT )
6365 . send ( )
@@ -124,13 +126,9 @@ fn curve25519_secret_key_from_signing_key(signing_key: &SigningKey) -> Curve2551
124126 Curve25519SecretKey :: from ( secret_key)
125127}
126128
127- fn agent_task_registration_url ( chatgpt_base_url : & str , agent_runtime_id : & str ) -> String {
128- let trimmed = chatgpt_base_url. trim_end_matches ( '/' ) ;
129- let path = format ! ( "/v1/agent/{agent_runtime_id}/task/register" ) ;
130- if let Some ( root) = trimmed. strip_suffix ( "/backend-api" ) {
131- return format ! ( "{root}{path}" ) ;
132- }
133- format ! ( "{trimmed}{path}" )
129+ fn agent_task_registration_url ( agent_identity_base_url : & str , agent_runtime_id : & str ) -> String {
130+ let trimmed = agent_identity_base_url. trim_end_matches ( '/' ) ;
131+ format ! ( "{trimmed}/v1/agent/{agent_runtime_id}/task/register" )
134132}
135133
136134#[ cfg( test) ]
@@ -201,6 +199,7 @@ mod tests {
201199 #[ tokio:: test]
202200 async fn register_task_registers_and_decrypts_plaintext_task_id ( ) {
203201 let server = MockServer :: start ( ) . await ;
202+ mount_human_biscuit ( & server) . await ;
204203 let tempdir = tempfile:: tempdir ( ) . expect ( "tempdir" ) ;
205204 let keyring_store = Arc :: new ( MockKeyringStore :: default ( ) ) ;
206205 let secrets_manager = SecretsManager :: new_with_keyring_store (
@@ -213,7 +212,7 @@ mod tests {
213212 let manager = AgentIdentityManager :: new_for_tests (
214213 auth_manager,
215214 /*feature_enabled*/ true ,
216- format ! ( "{}/backend-api/" , server. uri( ) ) ,
215+ server. uri ( ) ,
217216 SessionSource :: Cli ,
218217 secrets_manager. clone ( ) ,
219218 ) ;
@@ -224,8 +223,7 @@ mod tests {
224223
225224 Mock :: given ( method ( "POST" ) )
226225 . and ( path ( "/v1/agent/agent-123/task/register" ) )
227- . and ( header ( "authorization" , "Bearer access-token-account-123" ) )
228- . and ( header ( "chatgpt-account-id" , "account-123" ) )
226+ . and ( header ( "x-openai-authorization" , "human-biscuit" ) )
229227 . respond_with ( ResponseTemplate :: new ( 200 ) . set_body_json ( serde_json:: json!( {
230228 "encrypted_task_id" : encrypted_task_id,
231229 } ) ) )
@@ -250,8 +248,9 @@ mod tests {
250248 }
251249
252250 #[ tokio:: test]
253- async fn register_task_uses_canonical_registration_url ( ) {
251+ async fn register_task_uses_agent_identity_base_url ( ) {
254252 let server = MockServer :: start ( ) . await ;
253+ mount_human_biscuit ( & server) . await ;
255254 let tempdir = tempfile:: tempdir ( ) . expect ( "tempdir" ) ;
256255 let keyring_store = Arc :: new ( MockKeyringStore :: default ( ) ) ;
257256 let secrets_manager = SecretsManager :: new_with_keyring_store (
@@ -264,7 +263,7 @@ mod tests {
264263 let manager = AgentIdentityManager :: new_for_tests (
265264 auth_manager,
266265 /*feature_enabled*/ true ,
267- format ! ( "{}/backend-api/" , server. uri( ) ) ,
266+ server. uri ( ) ,
268267 SessionSource :: Cli ,
269268 secrets_manager. clone ( ) ,
270269 ) ;
@@ -275,6 +274,7 @@ mod tests {
275274
276275 Mock :: given ( method ( "POST" ) )
277276 . and ( path ( "/v1/agent/agent-fallback/task/register" ) )
277+ . and ( header ( "x-openai-authorization" , "human-biscuit" ) )
278278 . respond_with ( ResponseTemplate :: new ( 200 ) . set_body_json ( serde_json:: json!( {
279279 "encrypted_task_id" : encrypted_task_id,
280280 } ) ) )
@@ -292,6 +292,20 @@ mod tests {
292292 assert_eq ! ( task. task_id, "task_fallback" ) ;
293293 }
294294
295+ async fn mount_human_biscuit ( server : & MockServer ) {
296+ Mock :: given ( method ( "GET" ) )
297+ . and ( path ( "/authenticate_app_v2" ) )
298+ . and ( header ( "authorization" , "Bearer access-token-account-123" ) )
299+ . and ( header ( "x-original-method" , "GET" ) )
300+ . and ( header ( "x-original-url" , AGENT_IDENTITY_BISCUIT_TARGET_URL ) )
301+ . respond_with (
302+ ResponseTemplate :: new ( 200 ) . insert_header ( "x-openai-authorization" , "human-biscuit" ) ,
303+ )
304+ . expect ( 1 )
305+ . mount ( server)
306+ . await ;
307+ }
308+
295309 fn seed_stored_identity (
296310 manager : & AgentIdentityManager ,
297311 secrets_manager : & SecretsManager ,
@@ -350,6 +364,7 @@ mod tests {
350364 chatgpt_plan_type : None ,
351365 chatgpt_user_id : user_id. map ( ToOwned :: to_owned) ,
352366 chatgpt_account_id : Some ( account_id. to_string ( ) ) ,
367+ is_org_owner : None ,
353368 raw_jwt : fake_id_token ( account_id, user_id) ,
354369 } ,
355370 access_token : format ! ( "access-token-{account_id}" ) ,
0 commit comments