This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Reference

Low level reference docs for Authproject.

Reference information about how Authproject, OAuth, and other services and technologies operate.

1 - Authentication Domains

What is an authentication domain? How does it work internally?

This document seeks to explain what an authentication domain is, how it is used, and how we implement it internally.

The Basics

When a user wants to sign in to your applicaiton using Authproject, they have to visit a given URL to enter their information. This URL is the beginning of an “authentication domain.” It is a logical grouping of user identities in our database that can be authenticated against.

How does the URL work?

When a user requests auth.yourwebsite.com, for example, it will be “pointed” via a CNAME record to our servers. This means that when the user visits auth.yourwebsite.com, their browser talks to Authproject’s “domain service.” The domain service is the core service that supports user interaction within our platform.

The URL, as mentioned above, sends a user to the domain service.

How does the domain service work?

The domain service looks for the Host header sent by the user’s browser. It then uses that as a partition key to finding all users that are registered with that domain. It means that when you look up email@example.com for the domain auth.yourwebsite.com, it doesn’t find any results for email@example.com under auth.authproject-demo.com as well. This allows a user to have multiple “accounts” in the domain service, while ensuring that each “account” they have is separate from any others stored in the database.

Networking

This simplicity from a user’s perspective comes at a cost to us, in terms of operational overhead. Any new website or application we onboard has to go through a process to register within our platform. The first step is for us to register the domain with our CDN provider, Cloudflare. All new domains have an entry added into Cloudflare, allowing TLS certificates (the S in HTTPS) to be provisioned, and enabling our web firewall for use by the customer.

Then, once the website has been set up on our side, the customer needs to point their domain to our services. They do this by creating the CNAME mentioned above. This directs web traffic aimed at the authentication domain (auth.yourwebsite.com) to go to our servers.

Emails

Once the authentication domain has been provisioned on both ends, we need to be able to send emails from your authentication domain. This is done by creating three more CNAME records, each of them pointing to a DKIM entry hosted by our email provider, AWS SES.

Once these are configured, we can successfully send emails from the authentication domain. But don’t worry - just because we can send emails from noreply@auth.yourwebsite.com doesn’t mean we can impersonate alan@yourwebsite.com. We can only send emails from auth.yourwebsite.com.

Hope this helps!

We hope this helps explain what an authentication domain is in our platform, how it’s used, and how we implemented it.

2 - Authentication Methods

Reference information on what auth methods are provided by Authproject

What authentication methods does Authproject provide?

Authentication Methods

Once a user enters their email, they are presented with options to select how they want to authenticate.

Password

A password is among the oldest authentication methods, but is still widely used today. After entering their email, a user will enter a password to prove that they are who they say they are. This system, while common, is vulnerable to password reuse attacks - where a user uses the same password as on another site, if that password is discovered, can allow an attacker access to the user’s account on Authproject.

A Magic Link is a link emailed to the user which will allow them to sign in. The link, once clicked, will authenticate the user without the need for a password. If an attacker requests a magic link, the only way to authenticate is to receive the email that the user sent. As long as a user’s email account is secure, magic links are a good way to sign in without the need for a password.

Passkey

Passkeys are becoming more common. They are a cryptographic attestation that the user has access to a device, where that device then validates the user’s identity in some other way - usually using biometrics, or a PIN code. It is a method of passwordless authentication, where a user simply clicks a button or scans a QR code, and are quite robust against all but the most sophisticated adversaries. However, if the user loses the device, they will not be able to sign in using a passkey.

One-Time Code

One-time codes are common for two-factor authentication. A user will either receive a code via email, text, or by checking their authenticator app, and will enter the code presented to log in. One-time codes are resistant to replay attacks, as the code changes with time. Therefore, an attacker can only use a one-time code for up to a certain amount of time after it has been generated - then it becomes no-longer valid.

3 - Login Flow

Reference information on how a user would authenticate with Authproject
How does a user login to Authproject?

Diagram: Login Flow

When a user logs in to Authproject, their authentication journey follows this flow chart.

NOTE: This only shows the “success” path. If they are unsuccessful in a given step, they are brought back to the previous successful step to try again.

flowchart TD
    A[User goes to Login page] --> B[User enters email]
    B --> C{Select first factor}
    C -->|Enter password| D[Password entry page]
    D --> E[Enter password]
    E --> F[Click Submit]
    F --> C2{Password correct?}
    C2 -->|Yes| I[Prompt to select second factor]

    C -->|Magic link| G[System emails magic link]
    G --> H[User clicks link in email]
    H --> I

    I --> J{Select second factor}
    J -->|OTP| K[OTP entry page]
    K --> L[Enter OTP]
    L --> M[Click Submit]
    M --> C3{OTP correct?}
    C3 -->|Yes| N[Login success]

    J -->|Passkey| P[Passkey entry page]
    P --> Q[Interact with passkey]
    Q --> C4{Passkey correct?}
    C4 -->|Yes| N

Text: Login Flow

  1. A user first enters their email.
  2. Then, the user selects the first factor to log in with.
    1. If they choose to authenticate with a password, they are brought to a page where they enter their password.
      1. They enter their password, then click “submit.”
    2. If they choose to authenticate with a Magic Link, they are brought to a page where they can request a Magic Link.
      1. They click “Send Magic Link.”
      2. They then check their email, and find the Magic Link they were sent.
      3. They click “Login” on the Magic Link.
  3. Once the user has completed the first factor, they are (if configured) prompted to enter a second factor.
    1. If they choose to log in with an OTP (One-Time Password, otherwise known as One-Time Code), they are brought to a page where they can enter their OTP.
      1. They enter the OTP from their authenticator app, then click “Submit.”
    2. If they choose to log in with a Passkey (WebAuthn), they are brought to a page where their browser prompts them to log in with a passkey.
      1. They then interact with their Passkey to login.
  4. Once the user has completed the second factor, they are brought to a success page where they can continue on to their application, or they are redirected to the application that initially sent them to the login screen.

Success

If a user was sent to the authentication domain as part of logging in to another platform, they will be sent back to the originating platform.

If a user arrives at the authentication domain without it being part of a request from another platform, they will see a “Login Success” page where they are told to visit their original platform.

4 - PKCE Clients

Reference information on how to set up a PKCE client with Authproject

How do I implement a PKCE client with Authproject?

PKCE

PKCE, or Proof Key for Code Exchange, is an extension to OAuth2’s authorization code flow to enable “public” clients to exchange their credentials for tokens, while maintaining the security of the system. Postman has an excellent set of docs explaining what PKCE is, and how it works.

Setting Up

In order for PKCE to work, there are a couple small requirements. The first is that your client must be set to be a “public” client (NOTE: this is not the default for new OAuth clients created in Authproject). The second is that your client must not have a client secret. This is handled automatically by us - if you request a public client, a client secret will not be generated.

Python Example

In order to demonstrate how to use PKCE with Authproject, we have a sample Python program that will perform a request on behalf of the user, exchange the received authorization code for a token, and display that token.

import base64
import webbrowser
import secrets

import hashlib

from requests_oauthlib import OAuth2Session

# Client ID, provided by Authproject
client_id = "<your-client-id>"

# Base URL for authorization
authorization_base_url = "https://<your-auth-domain>/oauth2/authorize"

# Token URL for exchanging authorization code for access token
token_url = "https://<your-auth-domain>/oauth2/token"

# Redirect URI registered with the OAuth2 provider
redirect_uri = "https://localhost:9000/callback"

# OAuth2 scope (optional, depends on your server)
scope = ["openid", "profile", "email"]


def generate_pkce_pair():
    # Generate a high-entropy code verifier
    code_verifier = (
        base64.urlsafe_b64encode(secrets.token_bytes(64)).rstrip(b"=").decode("utf-8")
    )
    # Create code challenge
    code_challenge = (
        base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode("utf-8")).digest())
        .rstrip(b"=")
        .decode("utf-8")
    )
    return code_verifier, code_challenge


def main():
    code_verifier, code_challenge = generate_pkce_pair()
    # Create an OAuth2 session
    oauth = OAuth2Session(
        client_id,
        redirect_uri=redirect_uri,
        scope=scope,
    )

    # Get authorization URL and state
    authorization_url, state = oauth.authorization_url(
        authorization_base_url,
        code_challenge=code_challenge,
        code_challenge_method="S256",
    )
    print("Open this URL in a browser and authorize:", authorization_url)
    webbrowser.open(authorization_url)

    # Get the authorization response from the user
    redirect_response = input("Paste the full redirect URL here: ").strip()

    # Fetch the access token
    token = oauth.fetch_token(
        token_url,
        authorization_response=redirect_response,
        include_client_id=True,
        code_verifier=code_verifier,
    )
    print("\nAccess token:", token)


if __name__ == "__main__":
    main()

Summary

When setting up PKCE with your client, there are some simple steps to follow:

  1. Create a “public” (not “confidential”) OAuth client in Authproject
  2. Create a PKCE pair in your application
  3. Give the user a URL to open that requests an authorization code, with code_challenge and code_challenge_method in the request
  4. Parse the response
  5. Exchange the authorization code for a token, including code_verifier in the request
  6. Use the access token to perform queries against Authproject

5 - Dashboard API

Reference for the Dashboard API