Skip to content

Discuss/Define authentication mechansim for "magiclinks" #2517

Closed

Description

@rhafer

Description

The authentication mechanism described in #2513 needs to be defined in detail. So that client and server developers can implement it.

Acceptance Criteria

  • commmon understanding with web team about how the authentication is supposed to work
  • documentation

Activity

  1. rhafer commented on Mar 24, 2026

    @rhafer
    MemberAuthor
  2. self-assigned this
    on Apr 15, 2026
  3. aduffeck commented on Apr 15, 2026

    @aduffeck
    Member

    Here's the plan for the authentication workflow of magic guest links as discussed with @JammingBen

    Authentication workflow

    Accessing a resource shared using a magic guest link works like this:

    Share creation

    1. The sharer creates a magic guest link for a specific email address. A magic token is stored in the backend for that email.
    2. An email with the according magic link is sent to the user

    Authentication

    1. The user clicks the link in their email

    2. The web page loads, retrieves the token from the URL and trades it for a cookie by sending it to a verify endpoint in the backend (e.g. /magic_guest_link_auth/verify/token)

    3. The backend looks up the token and either

      • marks the token as used and sends a signed jwt with a 24h expiry as a httponly, secure cookie. The jwt includes the share id and the role.
      • returns a structured 401 error if the token has expired, e.g.
        // HTTP Status: 401 Unauthorized
        {
        "error_type": "token_expired",
        "message": "Your token has expired.",
        "share_id": "<the-share-id>",
        }
        

      In this case the frontend uses the renew endpoint to create a new token as described in the Token refresh section. The web app also shows a form to enter the PIN to gain access.

    Access

    1. Requests to the actual resource now transport the jwt cookie

    2. A backend middleware verifies the jwt and

      • grants access if the jwt is fine

      • returns a structured 401 error if the jwt has expired.

        // HTTP Status: 401 Unauthorized
        {
        "error_type": "session_expired",
        "message": "Your session has expired.",
        "share_id": "<the-share-id>",
        }
        

    Token refresh

    1. When the frontend retrieves a token_expired or session_expired 401 error it POSTs the share id from the 401 to a renewal endpoint (e.g. /magic_guest_link_auth/renew)which will generate a new magic token AND a PIN and sends an according email to the user. The web app shows a form to enter the PIN to regain access.
    2. The user can either click the magic guest link in the email or enter the pin in the existing browser tab. The link restarts a new authentication flow as described above while the PIN makes a request to a different verify endpoint (e.g. /magic_guest_link_auth/verify/pin) which expects both the PIN and some contextual information like the share id from the 401 response to create a new jwt.

    Endpoints

    • POST /magic_guest_link_auth/verify/token

      Purpose: Trades a token for a fresh 24h JWT cookie.
      Payload: { "token": "abc123xyz..." }
      Response: 200 OK (+ Set-Cookie header) OR 401 Unauthorized (+ token_expired error).

    • POST /magic_guest_link_auth/verify/pin

      Purpose: Trades a PIN and share ID combo for a fresh 24h JWT cookie.
      Payload: { "pin": "123456", "share_id": "" }
      Response: 200 OK (+ Set-Cookie header) OR 401 Unauthorized (if PIN is wrong).

    • POST /magic_guest_link_auth/renew

      Purpose: Generates a new magic token/PIN set and sends it out by email.
      Payload: { "share_id": "" }
      Response: 200 OK (Indicates the email was successfully dispatched).

  4. aduffeck commented on Apr 15, 2026

    @aduffeck
    Member

    Documented as part of this issue for now. We'll merge this into more sophisticated documentation of the whole feature when we get there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions