[ZBX-22952] API authentication using Authorization bearer header does not work Created: 2023 Jun 12  Updated: 2025 Mar 24  Resolved: 2025 Mar 24

Status: Closed
Project: ZABBIX BUGS AND ISSUES
Component/s: API (A), Frontend (F)
Affects Version/s: 6.4.3
Fix Version/s: 7.0.12rc1, 7.2.6rc1, 7.4.0beta1

Type: Problem report Priority: Trivial
Reporter: Robin Roevens Assignee: Andrejs Griščenko
Resolution: Fixed Votes: 12
Labels: API, api_error, apitoken, authentication, tokens
Remaining Estimate: Not Specified
Time Spent: 8h
Original Estimate: Not Specified
Environment:

Suse Linux Enterprise 15 SP4 - kernel 5.14.21-150400.24.63-default
Zabbix 6.4.3 (Migrated from 6.2.9) - Installed from official Zabbix repos
Postgresql 15.1 + TimescaleDB 2.9.3


Issue Links:
Duplicate
Team: Team C
Sprint: S25-W6/7, DOC S25-W2/3, S25-W8/9, S25-W12/13
Story Points: 0.2

 Description   

According to https://www.zabbix.com/documentation/6.4/en/manual/api we should now use the `Authorization: Bearer xxx`-header to authenticate an API call. The `auth`-parameter is still supported but deprecated.

However, when using the Authorization Bearer, I'm unable to authenticate with the API, while when using the `auth`-parameter method, the API authentication is successful.

This is also seen when using the [pyZabbix python library|https://github.com/lukecyca/pyzabbix.] When that library detects a Zabbix API version > 6.4, it will use the Authorization Bearer-method.. but also fails to authenticate with it, at least on Zabbix 6.4.3.

 

Steps to reproduce:

  1. Ensure you have a user with API access
  2. Generate an API token for that user (optional - alternatively obtain a token using the user.login API call)
  3. Call the API method host.get with a `Authorization: Bearer xxx`-header:
curl --request POST --url 'http://zabbix643server/api_jsonrpc.php' --header 'Authorization: Bearer 5488f5b22f4ec4d028596deecc90d41a7bd26076f818f2d3f5be9596ce1a5da9' --header 'Content-Type: application/json' --data '{"jsonrpc": "2.0","method": "host.get","params": {"output": ["hostid","host"]},"id": 2}' 

Result:

Authorization failure:

{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params.","data":"Not authorized."},"id":2}

**
Expected:

a list of hosts, as requested by the `host.get` call

{"jsonrpc":"2.0","result":[{"hostid":"14195","host":"icos"},{"hostid":"14207","host":"webdbprd"},{"hostid": .... 

When I call the API using the same token, but using the `auth`-parameter, it works like it should be:

curl --request POST --url 'http://zabbixserver/api_jsonrpc.php' --header 'Content-Type: application/json' --data '{"jsonrpc": "2.0","method": "host.get","params": {"output": ["hostid","host"]},"id": 2,"auth": "5488f5b22f4ec4d028596deecc90d41a7bd26076f818f2d3f5be9596ce1a5da9"}' 

I get:

{"jsonrpc":"2.0","result":[{"hostid":"14195","host":"icos"},{"hostid":"14207","host":"webdbprd"},{"hostid": ....  

So it seems the new authentication method using an authentication bearer, just does not work.

Note that this is tested on an installation, migrated from Zabbix 6.2.9. If it works on a vanilla installation, this may be a migration bug? I did not test on a vanilla installation.



 Comments   
Comment by Robin Roevens [ 2023 Jun 13 ]

I think I found the culprit: After adding

SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

to my apache config, authorization using the bearer header now works.

However this requirement is not mentioned in the documentation.

It was this unrelated page that hinted me in the right direction: https://www.zabbix.com/documentation/6.4/en/manual/appendix/install/okta#scim-provisioning

I think the warning on that page about adding the SetEnvIf line should also be added in the zabbix frontend installation instructions, and/or in the API usage documentation.

And/or it should be set in the zabbix provided apache config in the zabbix-apache-conf package ?

 

Comment by Michael Weber [ 2023 Jun 13 ]

Great Job @Robin

I added tthis to my apache config and it is working now!

Comment by Cloud Ops [ 2023 Aug 05 ]

Thanks for identifying this! We're just now upgrading from 4.x and need to use pyzabbix for automation and ran into this problem.
Unfortunately, putting that directive in the apache config is not solving this for us. This is apache 2.4.37 with Alma Linux 8.8.

Works fine when we send Bearer token with curl. Hoping for some help or a fix, we'd prefer not to downgrade zabbix.

Comment by Oleksii Zagorskyi [ 2023 Aug 05 ]

The new auth method with HTTP header 'Authorization: Bearer XXXXX' works just fine on default installation, where default Internal authentication is used.

So, question is what is specific for your installation guys that it does not work for you.
Do you use HTTP auth in global frontend Authentication settings?
Or something else?

Comment by Cloud Ops [ 2023 Aug 07 ]

Maybe the default auth calls between API (or at least pyzabbix for Python) and apache2 no longer match default for Zabbix API? I have been using this way for years but it fails after upgrading from 4.0 to 6.4:

 $ python3
Python 3.7.16 (default, Mar 10 2023, 03:25:26)
[GCC 7.3.1 20180712 (Red Hat 7.3.1-15)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyzabbix import ZabbixAPI
>>> server_url = 'http://myzabbixserver/zabbix'
>>> z = ZabbixAPI(server_url)
>>> z.user.login(username='Admin', password='<xxx>')
'a364f29d36fae2c5a7148d5a2163fd28'
>>> z.host.get()
Traceback (most recent call last):

pyzabbix.ZabbixAPIException: ('Error -32602: Invalid params., Not authorized.', -32602)
>>>
$ curl --request POST \
--url 'http://myzabbixserver/api_jsonrpc.php' \
--header 'Content-Type: application/json-rpc' \
--header 'Authorization: Bearer a364f29d36fae2c5a7148d5a2163fd28' \
--data '{"jsonrpc":"2.0","method":"host.get","params":

{"output":["hostid","host"]}

,"id":1}'}
{same token but returns all my data!}
Comment by Oleksii Zagorskyi [ 2023 Aug 08 ]

It looks like "pyzabbix" is doing something wrong, not zabbix itself. Even for old auth method.

Show please result of "pip list | grep zabbix"

Comment by Cloud Ops [ 2023 Aug 08 ]

I don't think pyzabbix has changed in a while, this has all worked fine with Zabbix 4.0.

$ pip3 list|grep zabbix
pyzabbix 1.3.0

Comment by Cloud Ops [ 2023 Sep 06 ]

Hi Oleksii, were you able to reproduce this, or do you know how we can work around it?

Comment by Mladen Georgiev [ 2023 Oct 03 ]

I have the same issue on 6.0 LTS. Hope somebody finds a workaround or the issue is fixed.

Comment by Michael Weber [ 2023 Oct 03 ]

There is a workaround/fix for apache webservers:

SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 

Posted by @Robin Roevens

Comment by Mladen Georgiev [ 2023 Oct 03 ]

Thanks but this doesn`t work for me. I am using Apache but there is no difference when I added the config.

Comment by Kilian Kreibich [ 2023 Nov 02 ]

Hi, I have the same Problem, but i am using nginx. I already tried adding

fastcgi_param  HTTP_AUTHORIZATION $http_authorization;

to my nginx-config, but this didn't work.

I am trying to access the API with the example Curl-Commands. With Bearer Header it doesn't work, with the auth paramenter it works just fine.

Does somebody know how to fix this with nginx Webserver?

Comment by simon delmotte [ 2023 Dec 02 ]

i have the same problem with nginx

Comment by Andrei Gushchin (Inactive) [ 2024 Jan 03 ]

Probably for nginx could be used

proxy_set_header  Authorization $http_authorization;
proxy_pass_header Authorization;
Comment by Kevin Humphreys [ 2024 Apr 04 ]

I am running into this as well starting from at least 6.4.2 (currently on 6.4.1)

We are using the images

  • zabbix/zabbix-web-apache-mysql:ubuntu-6.4.11
  • zabbix/zabbix-server-mysql:centos-6.4.11
    Tested using curl:
    curl --request POST   --url 'https://zabbix.xxxx.com/api_jsonrpc.php'   --header 'Content-Type: application/json-rpc'   --data '{"jsonrpc":"2.0","method":"host.get","params":{"search":{"host":["HOSTNAME"]}},"id":1,"auth":"AUTH_TOKEN"}' returns a list of hosts
     
    curl --request POST   --url 'https://zabbix.xxxx.com/api_jsonrpc.php'   --header 'Content-Type: application/json-rpc'   --data '{"jsonrpc":"2.0","method":"host.get","params":{"search":{"host":["HOSTNAME"]}},"id":1}' --header "Authorization:  Bearer AUTH_TOKEN" returns `{"jsonrpc":"2.0","error": {"code":-32602,"message":"Invalid params.","data":"Not authorized."}

    ,"id":1}`

Edit: manually testing adding `SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 ` in one of our docker containers fixes the issue. is there a non-invasive way to inject this setting into a container without having to rebuild it ourselves or pass the entire apache.conf in?

Comment by Peter [ 2024 Apr 30 ]

Has anyone found a solution for Nginx? This does not look like a documentation task. I've checked and both Authorization header with token and HTTP_AUTHORIZATION parameter get through nginx to php-fpm. To check I've created headers.php and put it in header.php file the same directory zabbix frontend:

<?php

$headers =  getallheaders();

foreach($headers as $key=>$val){
  echo $key . ': ' . $val . '<br>' . "\n";
}

echo "\n";
echo $_SERVER['HTTP_AUTHORIZATION'] ;
echo "\n";
echo "\n"; 

Now with curl I've called:

curl -v --request POST 'https://zabbix.*com/headers.php' --header 'Authorization: Bearer token' --header 'Content-Type: application/json-rpc'

and I see both header and HTTP_AUTHORIZATION parameter value in the output:

Authorization: Bearer token<br>

Bearer token

But authorization is not working. It mentioned above it works only if I put a token into auth parameter. Any hints here, what could be wrong? I can dig further, but I'm not sure, where this token is parsed? After reading sources I've got the impression that PHP only parses the Authorization header for Basic and Digest types of authorization. I don't see where this header is parsed in php code as well. Is it possible that this header is not supposed to work with nginx -> php-fpm setup?

 

 

Comment by Stefan König [ 2024 Jun 19 ]

I can see this problem in the new 7.0 LTS as well. The deprecated method is still working, but flooding the nginx server logs:

2024/06/19 13:00:22 [error] 1086087#1086087: *16219 FastCGI sent in stderr: "PHP message: PHP Deprecated:  Parameter "/auth" is deprecated. in /usr/share/zabbix/include/classes/validators/CApiInputValidator.php on line 1513" while reading response header from upstream, client: <redacted>, server: <redacted>, request: "POST /api_jsonrpc.php HTTP/2.0", upstream: "fastcgi://unix:/var/run/php/zabbix.sock:", host: "<redacted>"

Comment by jchegedus [ 2024 Nov 27 ]

Hi,

Now that in 7.2.0 RC1 the auth field is completely removed, I was trying to use the API Token on the header Authorization Bearer.

If I send this directly to the Apache I use, not proxied anyhow, just a vhost, it works.

But in general I will use HAProxy everywhere, then I found something funny.

To cite HAProxy documentation: https://docs.haproxy.org/3.1/configuration.html#4.2-no%20option%20h1-case-adjust-bogus-server

 

There is no standard case for header names because, as stated in RFC7230,
they are case-insensitive. So applications must handle them in a case-
insensitive manner. But some bogus applications violate the standards and
erroneously rely on the cases most commonly used by browsers. This problem
becomes critical with HTTP/2 because all header names must be exchanged in
lower case, and HAProxy follows the same convention. All header names are
sent in lower case to clients and servers, regardless of the HTTP version. 

I noticed that when the header is sent via HAProxy he will send "authorization" instead of "Authorization" and looking at `include/classes/core/CHttpRequest.php` , the code specifically want "Authorization" (violating the RFC saying header should be case insensitive)

Nonetheless, if anyone else in the same situation reach this comment, one possible solution for HAProxy is to add the following:

global
  h1-case-adjust          authorization Authorization

defaults
  option                  h1-case-adjust-bogus-server

That will force the correct case expected by Zabbix API.

Hope that it helps.

PS: This then will become a bug when related to HTTP/2, because the protocol will not accept the Authorization case anyway.

 

Comment by Michael Weber [ 2025 Feb 07 ]

I am using HAproxy in front ob Zabbix webinterface, and confirm the hint provided by spectroman 

Python script local on zabbix server it working without any modification.

Python script from remote via HAproxy requires the two options in haproxy or the apache2 config modification.

Comment by Andrejs Griščenko [ 2025 Feb 27 ]

Available in versions:

Comment by Arturs Dancis [ 2025 Mar 20 ]

Thank you for reporting! Documentation updated:

  • Appendix 3. Changes (7.0.11, 7.2.5)
  • API (7.0, 7.2, 7.4), SAML setup with Okta (7.0, 7.2, 7.4) — updated note on authentication issues
  • Known issues (7.0, 7.2, 7.4) — added "Authorization header forwarding" entry
Generated at Mon Jun 23 07:49:17 EEST 2025 using Jira 9.12.4#9120004-sha1:625303b708afdb767e17cb2838290c41888e9ff0.