From bd780b4cc62fd3dd45fc988188ce550d9b24f626 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 27 May 2026 17:21:53 +0530 Subject: [PATCH] feat: hide agent bot access_token when using read only token --- app/views/api/v1/models/_agent_bot.json.jbuilder | 4 ++-- .../api/v1/accounts/agent_bots_controller_spec.rb | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/app/views/api/v1/models/_agent_bot.json.jbuilder b/app/views/api/v1/models/_agent_bot.json.jbuilder index d5dbc91b4..6fe96ba72 100644 --- a/app/views/api/v1/models/_agent_bot.json.jbuilder +++ b/app/views/api/v1/models/_agent_bot.json.jbuilder @@ -6,6 +6,6 @@ json.outgoing_url resource.outgoing_url unless resource.system_bot? json.bot_type resource.bot_type json.bot_config resource.bot_config json.account_id resource.account_id -json.access_token resource.access_token if resource.access_token.present? -json.secret resource.secret if !resource.system_bot? && Current.account_user&.administrator? +json.access_token resource.access_token if resource.access_token.present? && @access_token&.scope != 'read_only' +json.secret resource.secret if !resource.system_bot? && Current.account_user&.administrator? && @access_token&.scope != 'read_only' json.system_bot resource.system_bot? diff --git a/spec/controllers/api/v1/accounts/agent_bots_controller_spec.rb b/spec/controllers/api/v1/accounts/agent_bots_controller_spec.rb index 61fcf30ac..f713ac09d 100644 --- a/spec/controllers/api/v1/accounts/agent_bots_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/agent_bots_controller_spec.rb @@ -54,6 +54,19 @@ RSpec.describe 'Agent Bot API', type: :request do expect(account_bot_response).to include('thumbnail') end end + + context 'when authenticated via a read-only api_access_token' do + it 'lists the bots but redacts their access tokens to prevent write escalation' do + get "/api/v1/accounts/#{account.id}/agent_bots", + headers: { api_access_token: admin.read_only_access_token.token }, + as: :json + + expect(response).to have_http_status(:success) + expect(response.body).to include(agent_bot.name) + expect(response.body).not_to include(agent_bot.access_token.token) + expect(response.parsed_body.first).not_to have_key('access_token') + end + end end describe 'GET /api/v1/accounts/{account.id}/agent_bots/:id' do