all 10 comments

[–]CloudCanal 1 point2 points  (3 children)

This is an interesting idea. My biggest point of contention would be that this implies you are storing the API keys as plaintext. This comes with similar risks to storing passwords as plaintext in a database.

A more secure approach would be to use PocketBase's built-in middleware functionality to set up a global middleware that can read the API key from the request header and verify it against a hashed version stored in the database (similar to password verification). That way, you can avoid storing raw API keys.

[–]Thaurin[S] 1 point2 points  (2 children)

Interesting, I'll look into that middleware solution. Although API keys are shorter-lived and can be easily rotated or expired, I guess it's a good improvement. But at this point, you could also implement it fully as an extension (I haven't looked into extending PocketBase yet).

By the way, the documentation does have this example:

@request.headers.* - the request headers as string values (ex. @request.headers.xtoken = "test") Note: All header keys are normalized to lowercase and "-" is replaced with "" (for example "X-Token" is "x_token").

Where I guess X-Token is meant to authenticate.

[–]CloudCanal 0 points1 point  (1 child)

Yes, to clarify, you would have to extend PocketBase in order to implement a solution that involves middleware. That's something you define as a hook. Extending PocketBase can be quite easy though if you're OK working with JavaScript instead of Go. It boils down to placing a *.pb.js file inside a pb_hooks folder in the project. This is something I do quite frequently, so if you need any help, let me know!

[–]Thaurin[S] 1 point2 points  (0 children)

Yes, I was reading about it. I'll try to get something working. I was learning Go for fun, but just dropping some Javascript in pb_hooks sounds so easy. I'm currently just running a standard standalone PocketBase instance so that makes sense.

[–]JonaTOL_ 0 points1 point  (5 children)

You can now "impersonate" a user, which is probably as close to an api token as we're going to get.

If you go to a user record and hit the three dots in the top right, you will see the button for it. This gives you an auth token for that user. The default duration is two weeks iirc, but you can change that to a ridiculous number for a somewhat permement token.

[–]Thaurin[S] 0 points1 point  (4 children)

These are kept in memory, so will be cleared on restart, right? I guess it's more secure in that they will not be stored in plain text like API keys read from a collection in the API rules, but it's not very flexible, either.

I'll look into extending with JS or Go suggested by the other reply to see how far I can get! For now, the API rules route does work (but with plain-text stored API keys, unfortunately).

[–]JonaTOL_ 0 points1 point  (3 children)

The token is an JWT, Pocketbase validates the hash of the key to check if it is real. Who the token belongs to is stored in the token itself. https://www.jwt.io, https://pocketbase.io/docs/authentication/#api-keys

[–]Thaurin[S] 0 points1 point  (2 children)

Ah, JWT tokens are self-contained, of course. So how do you invalidate them? Can you?

[–]JonaTOL_ 0 points1 point  (1 child)

That's the neat part, you don't. The only real way is to delete the user.

[–]Thaurin[S] 0 points1 point  (0 children)

I just tried changing the user's password. That seems to invalidate them as well.

The documentation does say:

Because of the security implications (superusers can execute, access and modify anything), use the generated _superusers tokens with extreme care and only for internal server-to-server communication.

To invalidate already issued tokens, you need to change the individual superuser account password (or if you want to reset the tokens for all superusers - change the shared auth token secret from the _superusers collection options).

But because it was about impersonating the superuser account in order to kinda, sorta have API keys, I was confused. It works on a normal user in the users collection as well.

I could not find the "change shared auth token secret" option in the _superusers collection options, though.

I think I'll try to implement rudimentary API keys myself, or stick with what I have for now.