Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tokens for Invites and Email confirmatin #544

Open
joepio opened this issue Nov 25, 2022 · 0 comments
Open

Tokens for Invites and Email confirmatin #544

joepio opened this issue Nov 25, 2022 · 0 comments

Comments

@joepio
Copy link
Member

joepio commented Nov 25, 2022

There are some systems that I'm working on / have worked on where tokens are needed:

  1. Invites. An invite can be used one to many times, and it represents a right for a specific resource
  2. E-mail confirmations. Sent once during registration. It confirms that one email address is correct
  3. Public key reset link. Used when a user has lost their private key. This link represents a single-use token that allows adding a new public key to an Agent.

All these have some things in common:

  • The token is publicly accessible - we can't use authentication to grant access
  • The token must be unique. We could use URLs for this (as these constraints are already used).
  • The token needs to be hard to guess.
  • The tokens should not be findable through pubic collections. This means the read rights are limited to the creator, or nonexistent.
  • The tokens can only be created under specific conditions. For example, users can only create an Invite for resource R if they have rights for resource R. E-mail confirmation tokens can only be created by the server - not by any user.

But there are also some differences:

  • Invites can be used multiple times, and the others only once

Other thoughts and considerations:

  • It is likely that we'll have different usecases for tokens in the future. For example vote tokens, credits, vouchers.
  • We want to prevent that users create tokens that give rights that they cannot give. For Invites, this meant creating an Invites plugin that handles all commits done to Invite instances.

Approaches

Add some token helper functions in atomic-lib

If we continue to use Class Extender Plugins, we should make sure that most logic is shared. That means:

  • Checking for existing tokens
  • By default disallowing creation of tokens.

Add a token property with custom property level

  • Makes it really simple to query for tokens, because we know they are generated through the plugin.
  • Requires custom property-level validations, which is powerful, but potentially very costly if we allow it as a plugin abstraction. We currently only check for plugins at the class level.

Add a single /token endpoint

  • Users pass a query param containing the token string (not a URL)
  • Depending on the type of token, the server does what should be done
  • Not sure how we need to deal with passing arguments... What if a token requires additional user input? We couldn't communicate these fields to the user. Nope, bad idea.

Protected properties

We can add an isProtected attribute to Property definitions. When this is set to true, we prevent users from editing this field. That way, we can know that nobody can create malicious invites, for example.

Signed tokens (e.g. JWTs)

Most of the current designs are stateful. They require that the server stores something and later retrieves this. This brings complexity - we need to store tokens, retrieve them, make sure they are unique, etc... Instead, we could let the server create signed tokens which contain all relevant information.

  • I think all signed tokens need an expiration date
  • Making them internally JSON-AD would make sense, but I also want serde compatbility. If we go for JSON-AD, then:
    • All should require a Class
    • Their @id fields are probably empty, as they are not hosted anywhere
  • Tokens that are used should probably be stored, so they aren't used again. We could even store just the hash. I'm not sure when we could remove these, though. Perhaps store them indefinitely in a sled::Tree.
  • JWT is the most wide used, but also criticized for its security.

In the case of an email reset, the JWT would contain the e-mail address and the Agent URL.
For pubkey reset, only the Agent URL.

Invites are another story... I'm not sure if the JWT approach works there.
Invites can be used multiple times.
A counter has to be decremented when they are used.

Crates:

  • jwt. Seems to provide everything
  • jwt-simple, seems a bit more maintained and easy to use. Plays well with derive macros and serde.
  • biscuit, improves on some JWT / JOSE design issues. But no JS crate (not sure if I need that though).
  • branca is simple, but more constrained. No third party validation possible. I think that's fine in our use-case, though. The repo seems a bit empty (not many examaples), and it hasn't been maintained in 9 months.
  • paseto, seems to fix jwt issues and has support for ed25519 (which we already use) see examples
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant