API endpoint users/by-external/ failing with authorization headers, works without

Starting on March 24th, there seems to have been a change in the way the Discourse API responds to requests.

No code changes have been made on our end, and the Api-Key is still valid, but one of our backend services that attempts to get user info started failing when hitting the users/by-external/{id}.json

We send the Api-Key and Api-Username headers with these requests, which should be required, per the documentation. These requests have been working fine for years.

Now, all requests made to this endpoint fail with a 403, and the response body:

{
    "errors": [
        "You are not permitted to view the requested resource."
    ],
    "error_type": "invalid_access"
}

This also happens if I try to request /u/{username}.json

Amazingly, when I do NOT send the headers, these requests which according to the docs require these authentication headers actually responds with the requested data, as though it were authenticated.

I’ve also tried sending and incorrect Api-Key, and the responds with a slightly different message:

{
    "errors": [
        "You are not permitted to view the requested resource. The API username or key is invalid."
    ],
    "error_type": "invalid_access"
}

This tells me that the key is being accepted, but erroneously reports that it does not grant access to the resource, while granting unauthenticated requests full access.

I also just tested with a brand new Api-Key with all-users / global options, and I get the same results.

4 Likes

After working through this with @Tim_Scaffidi we realized that the user being passed in for the Api-Username had been automatically deactived by the SiteSetting.invalidate_inactive_admin_email_after_days. There likely is a bug related to this setting where api calls made by a user are not updating that user’s “login” activity.

7 Likes

I looked into this again to see if there was some code that should be changed to improve things, but because the issue only occurred because an “All Users” api key was being used, I don’t think we should change anything code wise. The best option to avoid user deactivation is to use a “Single User” api key so that we can check the last_used_at on the api key record instead of trying to check last_seen_at on the user record.

1 Like