jethro-pmm icon indicating copy to clipboard operation
jethro-pmm copied to clipboard

Implement Personal Access Tokens for secure automated access

Open jefft opened this issue 2 years ago • 4 comments

Jethro users occasionally need API-like access to Jethro data. For instance, Google Sheets might ingest CSV data from a Persons report for further processing.

To this end, it would be nice for Jethro to support personal access tokens for authentication. For instance, I'd go to

image

then fill in a form very similar to the 'create user' form:

image

Submitting this, I then get told my access token (e.g. "MTg1MTc3NzE1MzA0OhiU"), and now I can use it in HTTP requests:

curl 'https://jethro.mychurch.com/?call=report_csv&queryid=1' 
     -H 'Authorization: Bearer MTg1MTc3NzE1MzA0OhiU'

In the database, Jethro stores:

  • associated user id
  • access token name
  • creation date
  • expiry date
  • permissions bit-field
  • hash of the generated token, using the existing password hash algorithm

See for instance Atlassian's access tokens or Github access tokens for ideas.

jefft avatar Dec 09 '22 07:12 jefft

Question: Is it best for an access token to be a child of a staff_member (so if the staff_member is archived, the access token is defunct)? Or better for access tokens to be their own thing, so that any sysadmin can create/maintain them?

tbar0970 avatar Jan 11 '23 07:01 tbar0970

Access tokens should be tied to a real account (thus the associated user id field). Deactivating the owner account deactivates their tokens. The token's permission bitset is ANDed with the owner's, so removing owner permissions removes permission from the access token.

Otherwise, if access tokens were "their own thing", might as well just create a jethrobot role account and use HTTP Basic auth (if Jethro supported it):

curl -u 'jethrobot:hunter2' 'https://jethro.mychurch.com/?call=report_csv&queryid=1'

In fact, just adding HTTP Basic support would solve my CSV-scraping-bot use-case just fine. It's a simpler solution, with no extra database table or UI work.

Having access tokens is still nicer than role accounts + HTTP Basic auth:

  • If we ever implement 2FA or SAML, access tokens will be exempt and continue to work.
  • Access tokens are guaranteed to be cryptographically secure, and not reused across websites, unlike the self-chosen passwords of most church people I know :)
  • Access can be restricted to API-like calls (?call=report_csv) and rate-limited differently.

In general, it's a good idea to know whether your user is a real person or a bot, because the authentication flows are diverging. Real persons may one day authenticate with OAuth/SAML/WebAuthn, or regular passwords plus 2FA / CAPTCHAs. Bots are spared all that malarkey, and just need a token (static or generated via OAuth). HTTP Basic auth doesn't distinguish bots from people, which is why bigger SaaS vendors like Google, Atlassian and Microsoft are removing HTTP Basic auth.

jefft avatar Jan 12 '23 01:01 jefft

I agree that http basic auth is old skool and better avoided.

But as you say, just using regular accounts would be simpler. I wonder about the option of being able to mark user accounts as "API user" which means they get an access key generated instead of a password, and get access only to certain endpoints.

tbar0970 avatar Jan 12 '23 02:01 tbar0970

Thinking of API endpoints, there are some that need to know who you are:

  • get iCal for my roster allocations
  • show person records visible to me (in my shared groups)
  • show my assigned notes
  • show my user details

and then there are API calls like "show CSV from report" which don't care who you are.

An "API user" flag would be fine for "show CSV of report" type queries, but not the first kind that need to know your identity.

If you take the idea of an "API user", but then associate it with an existing person/account, technically that's exactly what a "personal access token" would be.

jefft avatar Jan 12 '23 04:01 jefft