Allow API authentication without write access

Platform(s): API

Description of need: I’m building an app, iNaturalist Bingo, that connects to a user’s iNaturalist account in order to check off species from a bingo card that they have observed. The app does not need write access, it only needs the user’s ID.

I tried to modify the OAuth flow to request only the login scope, but the resulting access token wasn’t usable for anything—requesting /users/api_token resulted in a 403 (because requesting an API token requires write access).

Feature request details: I would like to be able to request a JWT that has only read scope, and perhaps even only login scope (i.e. only provides access to https://api.inaturalist.org/v1/users/me). Alternatively, I would like to be able to request a user’s details without fetching a JWT, e.g. by a CORS-enabled https://inaturalist.org/users/me.json.

It looks like at present, the JWT doesn’t encode any info about granted scopes, so I’d imagine this could go like:

  1. Add scope info to the JWT, e.g. {"user_id": 1234, "scopes": ["login", "write"]}
  2. Have the API service check scopes per-request.

Since JWTs are only valid for 24 hours, it would be sufficient to deploy the Rails-side changes to include the scope data, wait at least 24 hours, then deploy the API-side change that checks the scope. That would avoid inadvertently invalidating existing tokens.

I’m trying to better understand the description of need. Users’ observed species are public information and can be queried with the existing API. Wouldn’t typing in the username be sufficient rather than requiring someone to authenticate?

Are there other desired use cases?

IMO, typing in your username is a worse experience than clicking a button to sign in. It’s not strictly necessary for my use case, but also, it allows you to verify that the user of your app is actually who they say they are, as opposed to being able to type in anyone’s username.

1 Like

i wouldn’t describe the /users/me response as simply a “login(-only)” kind of action. currently, it’ll return some personal information like the user’s e-mail address. i would describe that kind of scope as more of a “profile” kind of scope. but then that opens a whole can of worms in terms of how to scope everything related to the JWT.

right now, it’s pretty clear that the app either get all privileges or no privileges, which i think is fine. trying to define JWT scopes more granularly is fine, too, but i think it should be done in a more deliberate way than what you’re describing here.

i can’t really think of many use cases for a true login-only kind of scope. that would only tell the app that you have an iNat account, not necessarily what your account is. (i suppose you could parse the JWT to discover what the account is though, or i guess the api_token endpoint could be modified to return the user_id along with the JWT.) assuming that an app could use a hypothetical login to basically do a user authentication only (and reveal user_id), i’m thinking something like that would only be useful for doing something like a registration, where, for example, a Discord account could be verified as belonging to a particular iNat user. however, there are other ways to accomplish that sort of registration.

i don’t really understand why you would want to limit your Bingo page in such a way that a user could only generate results for themselves. to me, it would be a nice feature to be able to also check results for friends / family (so that only one person would need to check the results for all members of a group engaged in friendly competition, for example).

1 Like

The OAuth page is already pretty clear about what access the 3rd party will get if you only ask for the login scope:

It’s pretty common for platforms which support 3rd-party apps to provide this sort of information. Typing a username is technically feasible, but in my opinion is a worse interaction for “connect this thing to my iNaturalist account”.

I’d also rather just type in usernames rather than have to require someone else to authenticate their account, or for myself, to scrutinize the terms of what I’m about to allow access to. Typing the username is a lot faster.